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

strutils:formatFloat() gives different result in JS mode #8244

Open
genotrance opened this issue Jul 7, 2018 · 4 comments
Open

strutils:formatFloat() gives different result in JS mode #8244

genotrance opened this issue Jul 7, 2018 · 4 comments

Comments

@genotrance
Copy link
Contributor

Test case in strutils.nim

echo formatFloat(123.456, ffScientific, precision = -1)

Prints "1.234560e+02" in C/C++ mode but prints "1.234560e+2" without the "0" in the exponent in JS mode. Wasn't getting caught all this time since testament wasn't running all test cases. See #8232 and #8242.

@skilchen
Copy link
Contributor

skilchen commented Jul 7, 2018

There are many more cases where formatFloat gives different results on the c/c++ and js backends.
Some examples:

import math
import fenv
import strutils

proc echoFloat(f: float) = 
  echo formatFloat(f, ffDefault)
  
proc test() = 
  echoFloat(maximumPositiveValue(float64))
  echoFloat(maximumPositiveValue(float32))
  echoFloat(minimumPositiveValue(float64))
  echoFloat(minimumPositiveValue(float32))
  echoFloat(1.0 + epsilon(float64))
  echoFloat(1.0 + epsilon(float32))
  echoFloat(1.0e23)
  echoFloat(log2(100000.0))
  echoFloat(PI / 2.0)
  echoFloat(PI / 3.0)
  echoFloat(E / 2.0)
  echoFloat(NaN)
  echoFloat(Inf)
  echoFloat(-Inf)
  echoFloat(0.0)
  echoFloat(-0.0)
  
test()  

gives

1.797693134862316e+308
3.402823466385289e+38
2.225073858507201e-308
1.175494350822288e-38
1.000000000000000
1.000000119209290
9.999999999999999e+22
16.60964047443681
1.570796326794897
1.047197551196598
1.359140914229523
nan
inf
-inf
0.000000000000000
-0.000000000000000

on the c/c++ backends and

1.7976931348623157e+308
3.40282347e+38
2.2250738585072014e-308
1.17549435e-38
1.0000000000000002
1.00000011920929
1e+23
16.609640474436812
1.5707963267948966
1.0471975511965976
1.3591409142295225
NaN
Infinity
-Infinity
0
-0

on the js backend.

Except for the last 5 examples where the correct representation is open to debate, the values printed on the js backend are the correct ones according to the current state of the art in terms of textual floating-point representations.

The main problem with the representations on the c/c++ backends (again except for the last 5 examples) is, that you either can't reconstruct the same floating-point value from the textual representation or you are wasting space displaying more digits than are necessary to reconstruct the same floating-point value.

@genotrance
Copy link
Contributor Author

Does this mean we need different test cases for C/C++ vs JS here or is it reasonable to expect consistent results?

@skilchen
Copy link
Contributor

Personally I would prefer consistent results, but @Araq doesn't seem to care much about these issues (see #7717). If you have some spare time, you could try to wrap https://github.com/google/double-conversion. Then we would have automatically the same behaviour on all backends, as this is the code used in the v8 engine.

@Araq
Copy link
Member

Araq commented Jul 11, 2018

Personally I would prefer consistent results, but @Araq doesn't seem to care much about these issues (see #7717).

Not true and you know it, see #7717.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants