Skip Menu |
Report information
Id: 128914
Status: resolved
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: zefram [at] fysh.org
Cc:
AdminCc:

Severity: (no value)
Tag: Bug
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Date: Fri, 12 Aug 2016 18:24:35 +0100
Subject: [BUG] decimal->float conversion differs for literals and Str.Num
To: rakudobug [...] perl.org
From: Zefram <zefram [...] fysh.org>
Download (untitled) / with headers
text/plain 1.4k
Show quoted text
> "9.998999999999999e0".EVAL - "9.998999999999999e0".Num
1.77635683940025e-15 Observe that the same string yields different Num values when interpreted as a Num literal and when coerced. Where the string is meaningful both ways, this is a bug. Obviously there are some situations where the syntax of Perl 6 literals doesn't exactly match what one would expect of a Str.Num conversion, but that's not the case here. Where the syntax matches, as it does in this case, or more generally where the same digits are presented with the same weights, one would expect the core decimal->float conversion to behave the same for both. The conversions yielding different values implies that at least one of them is individually incorrect. In this case, the coercion yields the correctly-rounded value, and the literal is getting it wrong. [perl #128912] is concerned with these conversions being incorrect per se, and my test case there used the conversion for literals. The difference between the two forms of decimal->float conversion is not merely a matter of literals getting it wrong and coercion getting it right: there are also cases where the coercion gets it wrong. In fact, coercion gets it wrong in the [perl #128912] test case: both literal interpretation and coercion get "9.999e-5" wrong in the same way. I have not yet encountered a case where literal interpretation gets it right and coercion gets it wrong, but nor can I say that there isn't such a case. -zefram
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 2.7k
On Fri, 12 Aug 2016 10:24:48 -0700, zefram@fysh.org wrote: Show quoted text
> > "9.998999999999999e0".EVAL - "9.998999999999999e0".Num
> 1.77635683940025e-15 > > Observe that the same string yields different Num values when interpreted > as a Num literal and when coerced. Where the string is meaningful both > ways, this is a bug. Obviously there are some situations where the > syntax of Perl 6 literals doesn't exactly match what one would expect of > a Str.Num conversion, but that's not the case here. Where the syntax > matches, as it does in this case, or more generally where the same > digits are presented with the same weights, one would expect the core > decimal->float conversion to behave the same for both. > > The conversions yielding different values implies that at least one > of them is individually incorrect. In this case, the coercion yields > the correctly-rounded value, and the literal is getting it wrong. > [perl #128912] is concerned with these conversions being incorrect per se, > and my test case there used the conversion for literals. The difference > between the two forms of decimal->float conversion is not merely a matter > of literals getting it wrong and coercion getting it right: there are also > cases where the coercion gets it wrong. In fact, coercion gets it wrong > in the [perl #128912] test case: both literal interpretation and coercion > get "9.999e-5" wrong in the same way. I have not yet encountered a case > where literal interpretation gets it right and coercion gets it wrong, > but nor can I say that there isn't such a case. > > -zefram
While OP's code snippet now shows there's no difference any more, it appears that the reason is because both literal and coercion give wrong values now: <Zoffix__> m: dd [ "9.998999999999999e0".EVAL, "9.998999999999999e0".Num] <camelia> rakudo-moar f48636011: OUTPUT: «[9.999e0, 9.999e0]␤» A quick print out with C shows both values should be: <Zoffix__> m: say 9.9989999999999988 <camelia> rakudo-moar f48636011: OUTPUT: «9.9989999999999988␤» And looks like our new approach of using nqp::div_In for coercion, literal parsing, and Rat->Num degradation might be flawed (or there's a bug in that op), as this: <Zoffix__> m: dd 9.9989999999999991e0 == 9.998999999999999e0 <camelia> rakudo-moar f48636011: OUTPUT: «Bool::False␤» after parsing eventually essentially becomes this: <Zoffix__> r: use nqp; dd nqp::div_In(99989999999999991, 100_000_000_000_000_000) == nqp::div_In(9998999999999999, 10_000_000_000_000_000) <camelia> rakudo-jvm a92950fb4, rakudo-moar f48636011: OUTPUT: «Bool::False␤» And it gives False, but in C, those two numbers are equal: $ ccc 'printf("%d\n", 9.9989999999999991e0 == 9.998999999999999e0)' 1
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 1.7k
On Fri, 12 Aug 2016 10:24:48 -0700, zefram@fysh.org wrote: Show quoted text
> > "9.998999999999999e0".EVAL - "9.998999999999999e0".Num
> 1.77635683940025e-15 > > Observe that the same string yields different Num values when interpreted > as a Num literal and when coerced. Where the string is meaningful both > ways, this is a bug. Obviously there are some situations where the > syntax of Perl 6 literals doesn't exactly match what one would expect of > a Str.Num conversion, but that's not the case here. Where the syntax > matches, as it does in this case, or more generally where the same > digits are presented with the same weights, one would expect the core > decimal->float conversion to behave the same for both. > > The conversions yielding different values implies that at least one > of them is individually incorrect. In this case, the coercion yields > the correctly-rounded value, and the literal is getting it wrong. > [perl #128912] is concerned with these conversions being incorrect per se, > and my test case there used the conversion for literals. The difference > between the two forms of decimal->float conversion is not merely a matter > of literals getting it wrong and coercion getting it right: there are also > cases where the coercion gets it wrong. In fact, coercion gets it wrong > in the [perl #128912] test case: both literal interpretation and coercion > get "9.999e-5" wrong in the same way. I have not yet encountered a case > where literal interpretation gets it right and coercion gets it wrong, > but nor can I say that there isn't such a case. > > -zefram
Thank you for the report. This is now fixed. Fix: https://github.com/rakudo/rakudo/commit/a760ac3cfc6426d9bd2fb00db https://github.com/MoarVM/MoarVM/commit/b735866ddee9bd719440e5c82 Test: https://github.com/perl6/roast/commit/4da5909f926e7eb42


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org