>>> numpy.float64(5.9975).hex()
'0x1.7fd70a3d70a3dp+2'
>>> (5.9975).hex()
'0x1.7fd70a3d70a3dp+2'
They are the same number. What differs is the textual representation obtained via by their __repr__ method; the native Python type outputs the minimal digits needed to uniquely distinguish values, while NumPy code before version 1.14.0, released in 2018 didn't try to minimise the number of digits output.
>>> numpy.float64(5.9975).hex()
'0x1.7fd70a3d70a3dp+2'
>>> (5.9975).hex()
'0x1.7fd70a3d70a3dp+2'
They are the same number. What differs is the textual representation obtained via by their __repr__ method; the native Python type outputs the minimal digits needed to uniquely distinguish values, while NumPy code before version 1.14.0, released in 2018 didn't try to minimise the number of digits output.
Numpy float64 dtype inherits from Python float, which implements C double internally. You can verify that as follows:
isinstance(np.float64(5.9975), float) # True
So even if their string representation is different, the values they store are the same.
On the other hand, np.float32 implements C float (which has no analog in pure Python) and no numpy int dtype (np.int32, np.int64 etc.) inherits from Python int because in Python 3 int is unbounded:
isinstance(np.float32(5.9975), float) # False
isinstance(np.int32(1), int) # False
So why define np.float64 at all?
np.float64 defines most of the attributes and methods in np.ndarray. From the following code, you can see that np.float64 implements all but 4 methods of np.array:
[m for m in set(dir(np.array([]))) - set(dir(np.float64())) if not m.startswith("_")]
# ['argpartition', 'ctypes', 'partition', 'dot']
So if you have a function that expects to use ndarray methods, you can pass np.float64 to it while float doesn't give you the same.
For example:
def my_cool_function(x):
return x.sum()
my_cool_function(np.array([1.5, 2])) # <--- OK
my_cool_function(np.float64(5.9975)) # <--- OK
my_cool_function(5.9975) # <--- AttributeError
python - Difference between numpy.float and numpy.float64 - Stack Overflow
which data type should I use for most accurate calculations? float decimal or python?
`np.float64` is not accepted as `float` under static type checks
[Week 1] np.float vs float
np.float is an alias for python float type.
np.float32 and np.float64 are numpy specific 32 and 64-bit float types.
float?
Init signature: float(self, /, *args, **kwargs)
Docstring:
float(x) -> floating point number
Convert a string or number to a floating point number, if possible.
Type: type
np.float?
Init signature: np.float(self, /, *args, **kwargs)
Docstring:
float(x) -> floating point number
Convert a string or number to a floating point number, if possible.
Type: type
np.float32?
Init signature: np.float32(self, /, *args, **kwargs)
Docstring: 32-bit floating-point number. Character code 'f'. C float compatible.
File: c:\python\lib\site-packages\numpy\__init__.py
Type: type
np.float64?
Init signature: np.float64(self, /, *args, **kwargs)
Docstring: 64-bit floating-point number. Character code 'd'. Python float compatible.
File: c:\python\lib\site-packages\numpy\__init__.py
Type: type
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.float64(2.0), np.float64) would obviously be True.
This would seem to be the difference between a 32-bit floating point number and a 64-bit floating point number (in C, a float vs. a double), and 2.0 ends up being a 32-bit floating point number.
I am trying to write a scientific simulation in python, precision is very important, what should I use?
You should not compare floats with equality, in any programming language, because you can never know that they are exactly equal. Instead, you should test whether their difference is smaller than a tolerance:
if abs(a - b) < 1e-10
So this problem doesn't have to do with the difference between float and float64 (Python converts them automatically), but with the fundamental problem of comparing floats for equality.
See also What's wrong with using == to compare floats in Java?
If you are using numpy, the best way to do what Antonis has suggested is to use the function np.allclose(a, b). You can also specify the tolerance (1e-10 from above).
CPython floats are allocated in chunks
The key problem with comparing numpy scalar allocations to the float type is that CPython always allocates the memory for float and int objects in blocks of size N.
Internally, CPython maintains a linked list of blocks each large enough to hold N float objects. When you call float(1) CPython checks if there is space available in the current block; if not it allocates a new block. Once it has space in the current block it simply initializes that space and returns a pointer to it.
On my machine each block can hold 41 float objects, so there is some overhead for the first float(1) call but the next 40 run much faster as the memory is allocated and ready.
Slow numpy.float32 vs. numpy.float64
It appears that numpy has 2 paths it can take when creating a scalar type: fast and slow. This depends on whether the scalar type has a Python base class to which it can defer for argument conversion.
For some reason numpy.float32 is hard-coded to take the slower path (defined by the _WORK0 macro), while numpy.float64 gets a chance to take the faster path (defined by the _WORK1 macro). Note that scalartypes.c.src is a template which generates scalartypes.c at build time.
You can visualize this in Cachegrind. I've included screen captures showing how many more calls are made to construct a float32 vs. float64:
float64 takes the fast path

float32 takes the slow path

Updated - Which type takes the slow/fast path may depend on whether the OS is 32-bit vs 64-bit. On my test system, Ubuntu Lucid 64-bit, the float64 type is 10 times faster than float32.
Operating with Python objects in a heavy loop like that, whether they are float, np.float32, is always slow. NumPy is fast for operations on vectors and matrices, because all of the operations are performed on big chunks of data by parts of the library written in C, and not by the Python interpreter. Code run in the interpreter and/or using Python objects is always slow, and using non-native types makes it even slower. That's to be expected.
If your app is slow and you need to optimize it, you should try either converting your code to a vector solution that uses NumPy directly, and is fast, or you could use tools such as Cython to create a fast implementation of the loop in C.