Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why numpy converts 20000001 int to float32 as 20000000.?

Tags:

python

numpy

I am trying to put some numbers into numpy array

>>> np.array([20000001]).astype('float32')
array([ 20000000.], dtype=float32)

where did 1 go?

like image 245
Bob Avatar asked Feb 15 '17 15:02

Bob


People also ask

Are Python floats 32 or 64?

Python's floating-point numbers are usually 64-bit floating-point numbers, nearly equivalent to np.

What is difference between numpy float64 and float?

float64 are numpy specific 32 and 64-bit float types. Thus, when you do isinstance(2.0, np. float) , it is equivalent to isinstance(2.0, float) as 2.0 is a plain python built-in float type... and not the numpy type. isinstance(np.

How do I change the Dtype of a numpy array?

We have a method called astype(data_type) to change the data type of a numpy array. If we have a numpy array of type float64, then we can change it to int32 by giving the data type to the astype() method of numpy array. We can check the type of numpy array using the dtype class.


Video Answer


2 Answers

You simply don't have enough precision. The float32 has only approximately 7 digits of accuracy, whereas the float64 has approximately 16 digits of accuracy. Thus, any time you convert to a float32, it's only guaranteed to be "correct" to within about a part in 10^7. So, for example, you can try this:

>>> np.array([20000001]).astype('float64')
array([ 20000001.])

That's the expected answer. (The dtype=float64 is automatically omitted, because that's the default.) In fact, you can go further and find

>>> np.array([2000000000000001]).astype('float64')[0]
2000000000000001.0

but

>>> np.array([20000000000000001]).astype('float64')[0]
20000000000000000.0

At some point, no matter how high your precision, you'll always get to the point where floats drop the least significant digits. See here for more info on floats.

On the other hand, python's int objects have many more digits they can keep track of. In python 3, it's practically unlimited. So ints have basically infinite precision. See here for more info on ints.

like image 125
Mike Avatar answered Oct 06 '22 01:10

Mike


First of all, float64 works in this case:

>>> np.array([20000001]).astype('float32')
array([ 20000000.], dtype=float32)
>>> np.array([20000001]).astype('float64')
array([ 20000001.])


How does a float work under the hood:

enter image description here


What's the difference between float32 and float64?:

  • 32bit (single precision float): 24 bit significand
  • 64bit (double precision float): 53 bit significand


With float32, you get 23 bits to represent the digits plus 1 bit to represent the sign. Lets view 20000001 in binary:

0b 1 0011 0001 0010 1101 0000 0001  ---->
0b 1 0011 0001 0010 1101 0000 00

So the last two bits "01" will get cut off when converting from int to float32.

Interestingly, converting 20000003 will get you 20000004:

>>> np.array([20000003]).astype('float32')
array([ 20000004.], dtype=float32)

And that is:

0b 1 0011 0001 0010 1101 0000 0011  ---->
0b 1 0011 0001 0010 1101 0000 01
like image 42
greedy52 Avatar answered Oct 05 '22 23:10

greedy52