lua-users home
lua-l archive

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


On Sat, Jul 30, 2016 at 3:00 AM, Duane Leslie <parakleta@darkreality.org> wrote:
Essentially by IEEE 0.5 should round to 0, and 1.5 to 2.

Thanks, now I understood why rounding is so weird :-)
> x=2^53
> x+1-x
0.0
> x+3-x
4.0
 

```lua
function rint(x)
    if x < 0 then
        return ((x - 0x1p+52) + 0x1p+52) | 0
    end
    return ((x + 0x1p+52) - 0x1p+52) | 0
end
```

If your argument is not expressible as an integer then this will cause an error so you should wrap it in `pcall` if the argument could be larger than `math.maxinteger` (or smaller than `math.mininteger`).

Using "math.floor(z)" instead of "z|0" will avoid raising an error:

> function rint(x)
    local y = 2^52
    return math.floor(x+y-y-y+y)
  end
> rint(0.5), rint(-0.5), rint(1.5), rint(-1.5)
0    0    2    -2
> rint(2^100)
1.2676506002282e+30


Unfortunately, this method (add 0x1p+52 and subtract 0x1p+52) gives wrong result for some inputs.
For example, the number 0x1p+105 does not have fractional part, so we need it to stay unmodified, but:

> rint(0x1p+105) == 0x1p+105
false
> 0x1p+105 + 0x1p+52 - 0x1p+52 == 0x1p+105
false