lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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