ulfjack / ryu

Converts floating point numbers to decimal strings
Apache License 2.0
1.19k stars 99 forks source link

s2d vs MSVC/Clang #157

Closed ejb77 closed 4 years ago

ejb77 commented 4 years ago

i noticed that s2d disagrees with MSVC & CLang. Is this expected?

int main() { double d; double e = 1.2999999999999999E+154; s2d("1.2999999999999999E+154", &d); assert(d==e); // assert occurs. }

E

ejb77 commented 4 years ago

d2s returns a number that is slightly different to what MSVC and CLang think they should be. d2s returns 1.2999999999999998e+154, the most insignificant bit is different.

(unsigned long long)&d,x 0x5fef06d5a4bf631e vs (unsigned long long)&e,x 0x5fef06d5a4bf631f

abolz commented 4 years ago

This is due to an invalid shift value in multipleOfPowerOf2. I think a fix would be to change https://github.com/ulfjack/ryu/blob/4cd47db40e6b1e9fe74ae9967ab78ba164f02388/ryu/s2d.c#L187 to

trailingZeros = e2 < e10 || (e2 - e10 < 64 && multipleOfPowerOf2(m10, e2 - e10));

and possibly adding an assert to multipleOfPowerOf2 to check the preconditions.

ejb77 commented 4 years ago

thanks. this works great