3
votes

I have a question which seems trivial.

Let's say that at the top of the Lua stack there's a number. I want to find out (in C) if this number is positive, negative, or zero.

A naive solution would be:

lua_Number num = lua_tonumber(L, -1);
if (num > 0)
   print("positive")
else if (num < 0)
   print("negative")
else
   print("zero")

However, this may not work well in Lua 5.3 because if it's a Lua integer (lua_Integer) on the stack it may not fit in our num variable (which is lua_Number).

So how can I write my C code to work in both Lua 5.1/5.2 and Lua 5.3?

(BTW, the reason I'm interested only in the sign, not in the number itself, is because this number is the return value of a comparison function for a sort algorithm. It's the result of comparing two items.)

1
If lua_Number is a floating-point number, then even if it loses some precision in the conversion, it will still retain the sign. - Colonel Thirty Two
@Colonel Thirty Two: Are you sure? Let's assume lua_Integer and lua_Number are both 64 bits (that's typical). Now, since lua_Number has larger range, it follows that some lua_Integer's can't be represented exactly as lua_Number. You assume that they'll merely lose precision on conversion. But perhaps the result of such conversion is "undefined behavior"? - Niccolo M.

1 Answers

3
votes

One possible solution is to let Lua do the comparison for you. This can be done using lua_compare (or lua_lessthan, for LuaJIT and Lua 5.1):

#if LUA_VERSION_NUM == 501
  #define LUA_LESS_THAN(state, index1, index2) lua_lessthan(state, index1, index2)
#elif LUA_VERSION_NUM > 501
  #define LUA_LESS_THAN(state, index1, index2) lua_compare(state, index1, index2, LUA_OPLT)
#endif

lua_pushnumber(L, 0);
if (LUA_LESS_THAN(L, -1, -2)) {
  // 0 < num
} else if (LUA_LESS_THAN(L, -2, -1)) {
  // 0 > num
} else {
  // 0 == num
}
lua_pop(L, 1);