SWI-Prolog / issues

Dummy repository for issue tracking
7 stars 3 forks source link

format to atom/codes of a large float in non-exp notation #71

Closed attoparsec137 closed 6 years ago

attoparsec137 commented 6 years ago

hello !

i am using SWI-Prolog (threaded, 32 bits, version 7.4.2) on windows 7. using format/3 to atom/codes for a float in non-exponential notation produces a weird result if the number is > 1.e19 :

?- format(atom(X), '~f', [1e20]). X = '100000000000000000000.00000\004\'.

the last character of X is the ASCII control code 4 (EOT). the same happens for codes(X) instead of atom(X). it works fine for numbers <= 1.e19. for numbers >= 1e20 the atom length seems to be 28 in all cases.

?- format(atom(X), '~f', [1e19]), atom_length(X, L). X = '10000000000000000000.000000', L = 27.

?- format(atom(X), '~f', [1e20]), atom_length(X, L). X = '100000000000000000000.00000\004\', L = 28.

?- format(atom(X), '~f', [1e30]), atom_length(X, L). X = '100000000000000000000000000\004\', L = 28.

?- format(atom(X), '~f', [1e100]), atom_length(X, L). X = '100000000000000000000000000\004\', L = 28.

?- format(atom(X), '~f', [1e200]), atom_length(X, L). X = '999999999999999970000000000\004\', L = 28.

i understand that floats are printed by a C function called dtoa. may be there is a buffer size issue with that function ?

thanks, -attoparsec-

JanWielemaker commented 6 years ago

Thanks for reporting. The dtoa() function is only used for quoted write that tries to write a float with as few as possible digits. This one is handled by formatFloat() in os/pl-fmt.c, which eventually calls snprintf(). I recall there is a problem with that on Windows. Your examples work fine on Linux, but also for the current version fail on Windows, both 32-bit and 64-bit. The character following the string differs. I'll have a look into this snprintf story ...

JanWielemaker commented 6 years ago

Should be fixed with SWI-Prolog/swipl-devel@dc4745174b87d3bafab8c65e3703fae406a01261 To appear in 7.7.14 (soon) and nightly builds.