Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

decimal->float conversion differs for literals and Str.Num #5565

Closed
p6rt opened this issue Aug 12, 2016 · 5 comments
Closed

decimal->float conversion differs for literals and Str.Num #5565

p6rt opened this issue Aug 12, 2016 · 5 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Aug 12, 2016

Migrated from rt.perl.org#128914 (status was 'resolved')

Searchable as RT128914$

@p6rt
Copy link
Author

p6rt commented Aug 12, 2016

From zefram@fysh.org

"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

@p6rt
Copy link
Author

p6rt commented Mar 26, 2018

From @zoffixznet

On Fri, 12 Aug 2016 10​:24​:48 -0700, zefram@​fysh.org wrote​:

"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

@p6rt
Copy link
Author

p6rt commented Mar 26, 2018

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Apr 13, 2018

From @zoffixznet

On Fri, 12 Aug 2016 10​:24​:48 -0700, zefram@​fysh.org wrote​:

"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​: rakudo/rakudo@a760ac3cfc6426d9bd2fb00db
  MoarVM/MoarVM@b735866ddee9bd719440e5c82
Test​: Raku/roast@4da5909f926e7eb42

@p6rt
Copy link
Author

p6rt commented Apr 13, 2018

@zoffixznet - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Apr 13, 2018
@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant