[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Possible Bug in bitlib under Windows?
- From: Mike Pall <mikelu-0812@...>
- Date: Sat, 13 Dec 2008 04:40:24 +0100
David Given wrote:
> float delta = [positive or negative number];
> unsigned int x = x + (unsigned int) delta;
>
> I was finding that on one platform (Intel) the sprites moved in both
> directions. On another platform (ARM) the sprites would only move to the
> right. Turns out that on ARM, casting a negative float to an unsigned
> int produces 0, which on Intel it's equivalent to casting it to a signed
> int.
>
> And they're *both* right --- you're allowed either interpretation. (The
> game had been written for Intel, and was wrong.)
Ouch. I guess this would then affect Lua 5.1.4, too. See line 785
of lstrlib.c:
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
This is casting a double to an uint32_t or uint64_t. Which got me
thinking why both of these lines work fine:
assert(string.format("%x", -1) == "ffffffff")
assert(string.format("%x", 0xffffffff) == "ffffffff")
Remember that for lua_Number = double, 0xffffffff turns into
4294967295, which is not a legal int32_t. And -1 is not a legal
uint32_t. But both are common arguments for "%x" I guess.
I found out this is actually a side-effect of how GCC and MSVC
cast doubles to uint32_t on x87: by going via an int64_t and then
taking the least-significant 32 bits. I.e. this cannot be relied
upon.
One might get away with always defining LUA_USELONGLONG and
casting first to signed then to unsigned INTFRM_T. But I'm not
sure this is the best fix. And it needs to be adapted for MSVC,
too (non-standard MS stuff: "I64" and __int64).
--Mike