lua-users home
lua-l archive

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


On Nov 22, 2012, at 10:04 AM, Roberto Ierusalimschy wrote:

> Moreover, it does not address the other part of the current proposal:
> to make Lua better for small platforms with no hardware support for
> doubles.

I want to click the "Like" button, but I can't find one in this mail client.

I'm looking over the lnum patch in OpenWrt. 

https://dev.openwrt.org/browser/trunk/package/lua/patches/010-lua-5.1.3-lnum-full-260308.patch

If I'm reading it right, it makes integer representation mostly transparent; MAXINT+1 overflows and is represented as floating point. The only odd behavior is with (integer,integer) arithmetic when there are precise integers outside the range of precise floating point numbers. This happens with 64-bit ints and IEEE doubles, or 32-bit ints and IEEE single precision. (Or with 16-bit int, it happens almost immediately.) AFAICT the semantic damage is limited to calculations sensitive to IEEE 754 behavior: don't do gravitation simulations in Lua with this patch on. But numerical analysis is not my strength.

32-bit ints are normal on most systems without FPUs.

When I asked "can I tell what this code does by local inspection", I was thinking of lexical scope. That might be another way to handle this on mixed systems. Consider the following ops (they are very ugly on purpose, they aren't a suggested surface syntax).

  -- current Lua '+' in default build
  n $fp+$ m

  -- overflow as C arithmetic done in int32, coercing.
  n $int32+$ m

  -- overflow as C arithmetic done in int64, coercing.
  -- expect and work with precise integers outside double range
  n $int64+$ m

  -- overflow/underflow signalled, otherwise C, coercing.
  n $sane32+$ m

  -- FP add, promote on overflow, almost identical to $fp+$
  n $promote32+$ m
  n $promote64+$ m

Given these choices, anybody writing non-trivial correct code will need to intentionally pick one. For example,

   local item_size = 270
   function myvector_size(items)
       return items $int32*$ item_size
   end
   ...
   f:seek(myvector_size(n))

With 32-bit integer arithmetic you can see why I think $sane32*$ is the only sane choice: you'll never get useful answers out of silent wraparound. It will confuse new users too.

In any case, "what a+b means" is more a property of the code than of the values. So, let's consider two chunks:

  $declare numbers: int32$
  x = 270 -- parsed as int
  function mysize(n) return 270 * n end
  y = mysize(1000*1000*1000) -- yields -582939648
  z = 37.5 -- parse error? explicit float literal?
----------
  -- traditional lua semantics
  $declare numbers: fp$
  a = mysize(1000*1000*1000) -- yields -582939648
  b = 0.5 * 0.5 -- yields 0.25, since this is $fp*$
  c = mysize(1.25) -- yields 270, since $int32*$ casts to int
  assert( 2^60 == 2^60+1 )

This leaves us with a single number type, again with the glitch that there are some more precise int64s.

What I would do on an embedded machine is #define LUA_DEFAULT_NUMBERS "int32"; most of the time people just want to count things. I'd prefer sane32 of course, since wraparound doesn't help me count things. If I were to use int32 I'd have to put a whole bunch of overflow checks in myself. 

I would need to put overflow checks in for int64 as well, but that's into the range where Lua code fails today. The nature of the failure is softer, though.

I dunno. "I came to Lua to take a vacation from C." Checking for wrap feels like something my higher-level language should handle for me.

Jay