[EMAIL PROTECTED] > I think there might be something wrong with the implementation of > modulus. > > Negative float values close to 0.0 break the identity "0 <= abs(a % b) < > abs(b)".
While that's a mathematical identity, floating point has finite precision. Many mathematical identities can fail when using floats. For example, (x+y)+z = x+(y+z) doesn't always hold when using floats either. > print 0.0 % 2.0 # => 0.0 > print -1e-010 % 2.0 # =>1.9999999999 > > which is correct, but: > > print -1e-050 % 2.0 # => 2.0 > print -1e-050 % 2.0 < 2.0 # => False See footnote 5.2 in the Language (not Library) reference manual, section 5.6 "Binary arithmetic operations": While abs(x%y) < abs(y) is true mathematically, for floats it may not be true numerically due to roundoff. For example, and assuming a platform on which a Python float is an IEEE 754 double-precision number, in order that -1e-100 % 1e100 have the same sign as 1e100, the computed result is -1e-100 + 1e100, which is numerically exactly equal to 1e100. Function fmod() in the math module returns a result whose sign matches the sign of the first argument instead, and so returns -1e-100 in this case. Which approach is more appropriate depends on the application. > This means I can't use modulus to "wrap around" before it reaches a > certain value. It's simply not possible to deliver a float result in all cases that satisfies all desirable identities. % and math.fmod make different tradeoffs, but neither is suitable for all applications, and it's possble that the neither is suitable for a particular application -- pick your poison, or brew your own. > I'm using Python 2.4.2 on WindowsXP. Because it's inherent to using finite-precision approximations to real numbers, this is a cross-platorm and cross-language phenomenon. If you can't tolerate approximations, rework your logic to use integers instead. -- http://mail.python.org/mailman/listinfo/python-list