Numpy's float32 and float comparisons
The numbers compare equal because 58682.7578125 can be exactly represented in both 32 and 64 bit floating point. Let's take a close look at the binary representation:
32 bit: 01000111011001010011101011000010sign : 0exponent: 10001110fraction: 1100101001110101100001064 bit: 0100000011101100101001110101100001000000000000000000000000000000sign : 0exponent: 10000001110fraction: 1100101001110101100001000000000000000000000000000000
They have the same sign, the same exponent, and the same fraction - the extra bits in the 64 bit representation are filled with zeros.
No matter which way they are cast, they will compare equal. If you try a different number such as 58682.7578124 you will see that the representations differ at the binary level; 32 bit looses more precision and they won't compare equal.
(It's also easy to see in the binary representation that a float32 can be upcast to a float64 without any loss of information. That is what numpy is supposed to do before comparing both.)
import numpy as npa = 58682.7578125f32 = np.float32(a)f64 = np.float64(a)u32 = np.array(a, dtype=np.float32).view(dtype=np.uint32)u64 = np.array(a, dtype=np.float64).view(dtype=np.uint64)b32 = bin(u32)[2:]b32 = '0' * (32-len(b32)) + b32 # add leading 0sprint('32 bit: ', b32)print('sign : ', b32[0])print('exponent: ', b32[1:9])print('fraction: ', b32[9:])print()b64 = bin(u64)[2:]b64 = '0' * (64-len(b64)) + b64 # add leading 0sprint('64 bit: ', b64)print('sign : ', b64[0])print('exponent: ', b64[1:12])print('fraction: ', b64[12:])
The same value is stored internally, only it doesn't show all digits with a print
Try:
print "%0.8f" % float_32
See related Printing numpy.float64 with full precision
The decimal 58682.7578125 is the exact fraction (7511393/128
).
The denominator is a power of 2 (2**7
), and the numerator span 23 bits. So this decimal value can be represented exactly both in float32 (which has 24 bits significand) and float64.
Thus the answer of Victor T is correct: in internal representation, it's the same value.
The fact that equality answer true for same value, even for different types is a good thing IMO, what do you expect of (2 == 2.0)
?