I am trying to put some numbers into numpy array
>>> np.array([20000001]).astype('float32')
array([ 20000000.], dtype=float32)
where did 1 go?
I am trying to put some numbers into numpy array
>>> np.array([20000001]).astype('float32')
array([ 20000000.], dtype=float32)
where did 1 go?
 
    
    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.
with float32 you can't resolve it
>>> np.finfo(np.float32).eps
1.1920929e-07
eps here gives you "the smallest representable positive number such that 1 + eps != 1" which is a measure for float32 accuracy. Multiply that with 20,000,000 and it's just too large.
Less informally, if one wants to avoid computing the binary representation of n then eps * n / base is a convenient lower bound for the resolution around n. While as @hobbs points out eps * n is an upper bound.
Also note that for example 1 + 0.6*eps may actually return something != 1, this is, however, due to rounding. Subtracting 1 from the result returns eps, not 0.6*eps.
 
    
    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:
What's the difference between float32 and float64?:
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
