Hi guys! I was busy working on my fraction class, when I found a problem which gives me quite the headache to think about.
If you type
print(2.5 % 1) it gives you 0.5, as this is the remainder of 2.5 / 1. Simple enough? As I am working with fractions I encounter many numbers smaller than one. So try
print(2 % 0.2). The expected answer should be 0, as 0.2 divides cleanly into 2, but it gives you the answer
-2.98023e-08. (P.S. The formula for Modulo is
a % b == a - math.floor(a/b) * b)
2 - math.floor(2/0.2) * 0.2 == 2 - 10 * 0.2 == 2 - 2 == 0 So I ask, why?
2 % 0.1 == -2.98023e-08
2 % 0.3 == 0.2
-- and then…
2 % 0.4 == -2.98023e-08
2 % 0.5 == 0
Any help? Thanks Jordan
that has to do with the internal representation of floating point numbers. Our everyday math is base-10, that is, 123,45 is 110^2 + 210^1 + 310^0 + 410^-1 + 5*10^-2. Computer’s math is base-2. So, for example, 0.5 base 10 is 1/2 = 2^-1 and thus 0.1 base-2. But now, 0.2 base-10 is 1/5, and that is not exactly representable in base-2. And this is where the differences come from.
I suck at explaining this without typing like 2 pages of text, but I hope you get the idea.
I think I get it, My explanation was leaning towards something like dividing by a fraction makes the number bigger, I was completely wrong. =D. But thanks for the explanation. A quick question… How do I do this without getting
this is not really avoidable. Floating point math on computers can be a tricky subject. Basically you can kinda work around it by not directly comparing floats to numbers. Considering that you probably want to test your modulo operation against 0, the usual way to do that is either only compute the modulo of 2 integral numbers, or compare the absolute value of the result of the modulo against a very small number, so instead of
if a%b == 0 then ...
if math.abs(a%b) < epsilon then ...
with epsilon being something like 0.0001 or less within the range of he mantissa of a codea float number, which is a short (32 bit) float.
Ok. Thanks so much @gunnar_z. You are a life-saver!
I have added a page to the wiki on Codea’s Lua number type.