Modulo returns nan instead of first operand when math.huge is the second operand

In Lua, JavaScript, Python3, and probably every other language that supports taking the remainder/modulo of floating point numbers, taking the modulo of a positive integer with math.huge yields the first operand. In other words, n % inf should yield n for all positive integers of n (and probably all real non-negative numbers).

Reproduction:

-- in Luau
print(1 % math.huge) -- nan

-- in Lua
-- print(1 % math.huge) -- 1

In Luau, I get nan. This is a bug because it’s inconsistent with other languages, it’s a breaking change, and it’s almost certainly not intended.

Version: 0.445.1.410643

11 Likes

I don’t think it’s a bug. I believe this is happening because because math.huge doesn’t really have a numerical value. It’s kind of like infinity. It isn’t an actual number, rather a representation of neverending. If you do some research on math.huge in Lua, you will more or less see the same thing as a result. You could also try doing print(tostring(1%math.huge)) to see, however I am not too sure whether that would alter the output or not.

False, math.huge has 2^63 or something like that as it’s value. Also either way, infinity would be able to be modulated by 1 since anything can be modulated / divided by 1.

1 Like

@7z99 This is absolutely a bug, at the very least because it used to work and now it doesn’t (and also for the reasons I mentioned).

As per the IEEE 754 floating-point standard, it explicitly states it here: remainder(x, ∞) is x for finite x

2 Likes

@jakedies

Oh, didn’t know that. Thanks!

1 Like

% is modulo, not remainder. remainder(-1,5) is -1, while modulo(-1,5) is 4, and -1%5 results in 4.

It looks like math.fmod correctly handles the case where the second argument is infinity (math.fmod is defined as remainder).

print(math.fmod(1,math.huge)) --> 1

Also, according to the Lua 5.1 manual the modulo operator is defined as a % b == a - math.floor(a/b)*b, which gives nan when a = 1 and b = inf. So it doesn’t look like returning nan from 1%math.huge is incorrect.

1 Like

Hmm, yeah after looking at the wiki and the source code, it seems like the behavior of modulo was changed in subsequent Lua versions but in vanilla 5.1 does yield NaN.

Although I’d argue it was probably originally a bug (that inf was an edge case they didn’t think about) since it was changed but that’s not really relevant I guess.

Edit: seems like I was right: Lua 5.3.6 source code - llimits.h
this definition gives NaN when ** 'b' is huge, but the result should be 'a'
So this should still be fixed IMHO.

Thanks for the report! We’ve filed this internally and we’ll follow up here when we have an update for you.

1 Like

Hi there, thanks for filing this bug report. Unfortunately, fixing it isn’t currently on the roadmap so we can’t prioritize a fix at this time.

1 Like