[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: problem with string.format %d and very large integers
- From: nr@... (Norman Ramsey)
- Date: Wed, 27 Jul 2011 16:57:06 -0400 (EDT)
I'm not quite sure if this problem counts as a bug or not, but I
tracked a real bug in a real application to unexpected behavior of
string.format, so I'm reporting it to the list.
I expect that if an integer n has an exact representation as a Lua
number, then the following laws hold:
tonumber(tostring(n)) == n
tonumber(string.format('%d', n)) == n
The first law holds, but if n is sufficiently large, the second does not:
: nr@labrador 12309 ; lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> g = 1000 * 1000 * 1000
> big = 2.5 * g
> =big
2500000000
> =string.format('%d', big)
-2147483648
> bad = tonumber(string.format('%d', big))
> =bad
-2147483648
> =tonumber(tostring(big))
2500000000
>
The documentation for string.format says that "the format string
follows the same rules as the printf family of standard C functions."
I'm sure this is a very large loophole. But I don't think the
current behavior of '%d' serves any useful purpose. Nor do I think it
is good for Lua's users to have to know about certain detailed
situations in which a Lua number is momentarily coerced to a 32-bit
integer. It would be better if numbers behaved like IEEE
floating-point numbers in all situations.
I don't know of a simple, portable way to solve the problem in pure
ANSI C. Using int64_t would solve the problem, but this type is
guaranteed to be present only in C99. There is, however, an ANSI C
solution for the common case in which the "precision" is left
implicit: Lua could implement %d by using '%.0f' internally.
And in any case, I would prefer to see string.format call lua_error()
rather than silently produce wrong answers.
Norman Ramsey