Reputation: 431
For a calculation in program that I wrote that involves finite algebraic fields, I needed to check whether (2**58-1)/61
was an integer. However python seems to indicates that it is, while it is not.
For example -
>>> (2**58-1)/61
4725088133634619.0
Even when using numpy
functions this issue appears -
>>> np.divide(np.float64(2**58)-1,np.float64(61))
4725088133634619.0
This happens although python does calculate 2**58
correctly (I assume this issue is general, but I encountered it using these numbers).
Upvotes: 0
Views: 148
Reputation: 32273
As for float limited precision mentioned by @Thierry Lathuille, Python's float
uses 64
bits and is double-precision that provides 53
bits for mantissa (the same is true for np.float64
). That means that not all numbers > 2**53
are representable using the float
, we have a loss of precision. For example, 2**53
== 2**53 + 1
is true in double precision. More detailed here:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
Is floating point math broken?
Upvotes: 1
Reputation: 2128
Correct answers have already been given. I am just adding another approach (which is not much different from what has already been said).
What you may want to do, due to inherent limitations of representation errors, is use divmod( ) for python and numpy.divmod( ) for numpy. That way you can check the quotient and the remainder.
print(divmod((2**58-1),61))
Gives quotient and remainder as
(4725088133634618, 45)
In numpy you may want to use similar, divmod, function but the numbers should be np.int type and not np.float type (due to representation errors mentioned above).
np.divmod(np.int64(2**58)-1,np.int8(61))
The above gives quotient and remainder as.
(4725088133634618, 45)
Upvotes: 0
Reputation: 24290
If you use normal /
division, your result is a float, with the associated limited precision. The result gets rounded, and in your case, it gets rounded to 4725088133634619.0 - but that doesn't prove that it is an integer.
If you want to check if the result of the division by 61 is an integer, test if the remainder of the division by 61 is 0, using the modulo operator:
>>> (2**58-1) % 61
45
As you can see, it isn't.
Upvotes: 3