nmq
nmq

Reputation: 3154

Numpy losing precision when converting long int to float

It seems numpy is losing precision on numpy.int64 values when converted to float types.

My numpy version is 1.15.4 which seemed to fix this error.

Here is an example:

>>> value = 734625324872288246
>>> value_plus_1 = 734625324872288246 + 1
>>> items = [value, value_plus_1]
>>> value.bit_length()
60
>>> value_plus_1.bit_length()
60
>>> import numpy as np
>>> a = np.array(items, dtype = np.float128) # larger than needed for value
>>> a
array([7.34625325e+17, 7.34625325e+17], dtype=float128)
>>> a.astype(np.int64) # larger than needed for value
array([734625324872288256, 734625324872288256])
>>> np.__version__
'1.15.4'

As you can see, now both values in the array are equivalent, which shows a loss in precision that I am assuming happens on casting to float.

My question is; Is there something I am doing wrong when creating numpy arrays that can be rectified to not lose precision?

Upvotes: 1

Views: 1640

Answers (2)

Warren Weckesser
Warren Weckesser

Reputation: 114811

(The question is almost certainly a duplicate, but my search-fu is weak today.)

There are only finitely many numbers that can be represented with 64 bit floating point numbers. The spacing between the numbers that are exactly representable depends on the magnitude of the numbers; you can find the spacing with the function numpy.spacing(x) for a floating point number x. In your case, the spacing of the floating point numbers around 734625324872288246 is 128:

In [33]: x = float(734625324872288246)

In [34]: x
Out[34]: 7.346253248722883e+17

In [35]: np.spacing(x)
Out[35]: 128.0

The integer value 734625324872288246 is not representable exactly as floating point. You can see that by casting the float back to integer; you don't get the same value:

In [36]: int(x)
Out[36]: 734625324872288256

You can represent 734625324872288256 exactly as a floating point number, but the next lower representable integer is 734625324872288256 - 128 = 734625324872288128.

And here are the obligatory links for questions about floating point:

Upvotes: 1

DatHydroGuy
DatHydroGuy

Reputation: 1116

The numpy documentation (https://docs.scipy.org/doc/numpy-1.15.0/user/basics.types.html) states that the implementation of float64 only uses 52 bits for the mantissa, and 11 bits for the exponent. This is most likely not enough accuracy to store your 60-bit numbers with full precision.

Upvotes: 3

Related Questions