Closed primo-ppcg closed 1 year ago
0.8 evenly divides both 4 and 8, but the remainder produced is 0.8 (or rather, a value minisculely smaller than 0.8), and not zero. I also suspect that this may differ across platforms, depending on the implementation of fmod, although I'm not absolutely sure of that.
Remainder and Mod are usually defined differently - remainder specifically is not defined in terms of modular arithmetic. Use mod
instead of %
for that.
Also, 0.8 is not representable exactly in ieee-754, so yes there is going to be some inexactness there.
remainder specifically is not defined in terms of modular arithmetic
Yes, I think you're right. I've just been mentioning issues as I encounter them. Sometimes it's user error 😉
One thing I've noticed is that
%
with a non-integer divisor is not consistent in terms of modular arithmetic:This will fail for any number of divisors, in particular when the binary representation is not exact.
It also has some interesting artifacts:
0.8 evenly divides both 4 and 8, but the remainder produced is 0.8 (or rather, a value minisculely smaller than 0.8), and not zero. I also suspect that this may differ across platforms, depending on the implementation of
fmod
, although I'm not absolutely sure of that.It's true that floating point arithmetic is not meant to be exact, but that doesn't prevent us from defining the remainder in a way that is consistent, both in terms of modular arithmetic, and also across platforms:
Which parallels the current implementation of
mod
. I've implemented this on my local fork for the purpose of testing. Aside from resolving both issues above, this also appears to be slightly faster, at least on my system: