Modulo operator in Python
PythonOperatorsModuloPython Problem Overview
What does modulo in the following piece of code do?
from math import *
3.14 % 2 * pi
How do we calculate modulo on a floating point number?
Python Solutions
Solution 1 - Python
When you have the expression:
a % b = c
It really means there exists an integer n
that makes c
as small as possible, but non-negative.
a - n*b = c
By hand, you can just subtract 2
(or add 2
if your number is negative) over and over until the end result is the smallest positive number possible:
3.14 % 2
= 3.14 - 1 * 2
= 1.14
Also, 3.14 % 2 * pi
is interpreted as (3.14 % 2) * pi
. I'm not sure if you meant to write 3.14 % (2 * pi)
(in either case, the algorithm is the same. Just subtract/add until the number is as small as possible).
Solution 2 - Python
In addition to the other answers, the fmod
documentation has some interesting things to say on the subject:
> math.fmod(x, y)
> Return fmod(x, y)
, as defined by the platform C
> library. Note that the Python expression x % y
may not return the same
> result. The intent of the C standard is that fmod(x, y)
be exactly
> (mathematically; to infinite precision) equal to x - n*y
for some
> integer n such that the result has the same sign as x
and magnitude
> less than abs(y)
. Python’s x % y
returns a result with the sign of y
> instead, and may not be exactly computable for float arguments. For
> example, fmod(-1e-100, 1e100)
is -1e-100
, but the result of Python’s
> -1e-100 % 1e100
is 1e100-1e-100
, which cannot be represented exactly as a float, and rounds to the surprising 1e100
. For this reason,
> function fmod()
is generally preferred when working with floats, while
> Python’s x % y
is preferred when working with integers.
Solution 3 - Python
Same thing you'd expect from normal modulo .. e.g. 7 % 4 = 3
, 7.3 % 4.0 = 3.3
Beware of floating point accuracy issues.
Solution 4 - Python
same as a normal modulo 3.14 % 6.28 = 3.14
, just like 3.14%4 =3.14
3.14%2 = 1.14
(the remainder...)
Solution 5 - Python
you should use fmod(a,b)
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.
where x = a%b
is used for integer modulo