Python's standard float type is a C double: http://docs.python.org/2/library/stdtypes.html#typesnumeric

NumPy's standard numpy.float is the same, and is also the same as numpy.float64.

Answer from John Zwinck on Stack Overflow
Top answer
1 of 2
63

Python's standard float type is a C double: http://docs.python.org/2/library/stdtypes.html#typesnumeric

NumPy's standard numpy.float is the same, and is also the same as numpy.float64.

2 of 2
3

Data type-wise numpy floats and built-in Python floats are the same, however boolean operations on numpy floats return np.bool_ objects, which always return False for val is True. Example below:

In [1]: import numpy as np
   ...: an_np_float = np.float32(0.3)
   ...: a_normal_float = 0.3
   ...: print(a_normal_float, an_np_float)
   ...: print(type(a_normal_float), type(an_np_float))

0.3 0.3
<class 'float'> <class 'numpy.float32'>

Numpy floats can arise from scalar output of array operations. If you weren't checking the data type, it is easy to confuse numpy floats for native floats.

In [2]: criterion_fn = lambda x: x <= 0.5
   ...: criterion_fn(a_normal_float), criterion_fn(an_np_float)

Out[2]: (True, True)

Even boolean operations look correct. However the result of the numpy float isn't a native boolean datatype, and thus can't be truthy.


In [3]: criterion_fn(a_normal_float) is True, criterion_fn(an_np_float) is True
Out[3]: (True, False)

In [4]: type(criterion_fn(a_normal_float)), type(criterion_fn(an_np_float))
Out[4]: (bool, numpy.bool_)

According to this github thread, criterion_fn(an_np_float) == True will evaluate properly, but that goes against the PEP8 style guide.

Instead, extract the native float from the result of numpy operations. You can do an_np_float.item() to do it explicitly (ref: this SO post) or simply pass values through float().

🌐
Python⇒Speed
pythonspeed.com › articles › float64-float32-precision
The problem with float32: you only get 16 million values
February 1, 2023 - The short version of the above is that 32-bit floats at a given level of precision can express 16 million positive and 16 million negative values, centered around zero.
🌐
NumPy
numpy.org › doc › stable › user › basics.types.html
Data types — NumPy v2.5 Manual
Which is more efficient depends on hardware and development environment; typically on 32-bit systems they are padded to 96 bits, while on 64-bit systems they are typically padded to 128 bits. np.longdouble is padded to the system default; np.float96 and np.float128 are provided for users who ...
🌐
University of Texas
cs.utexas.edu › ~mitra › csSpring2017 › cs303 › lectures › math.html
Doing Math in Python
There is also a limit to how big or how small a floating point number you can represent. For a 32-bit representation the range is (+/-) 3.4E38 and for 64-bit representation the range is (+/-) 1.8E308.
🌐
Quora
quora.com › What-is-np-float32-and-np-float64-in-numpy-in-simple-terms
What is np.float32 and np.float64 in numpy in simple terms? - Quora
Answer (1 of 2): np.float32 - It means that each value in the numpy array would be a float of size 32 bits. np.float64- It means that each value in the numpy array would be a float of size 64. If you are concerned about storing big numbers you should consider using float64, however, it takes mo...
🌐
Modular
forum.modular.com › mojo
How do I convert a python float to a Float32? - Mojo - Modular
February 10, 2026 - I am trying to iterate over a Python list and compare the values to those in a Mojo Float32 list, but I have not found a way of converting a Python float to any Mojo type for comparison. I’ve tried Float32(f.to_float64()), but to_float64() returns a PythonObject, and Float32 cannot convert a PythonObject.
🌐
Readthedocs
bitstring.readthedocs.io › en › stable › exotic_floats.html
Exotic Floating Point Formats — bitstring 4.3 documentation
Python floats are typically 64 bits long, but 32 and 16 bit sizes are also supported through the struct module. These are the well-known IEEE formats.
Find elsewhere
🌐
Edureka Community
edureka.co › home › community › categories › python › difference between python float and numpy float32
Difference between Python float and numpy float32 | Edureka Community
March 4, 2019 - What is the difference between the built in float and numpy.float32? For example, here is a code: ... > 58682.8 What is the built in float format?
🌐
KooR.fr
koor.fr › Python › API › scientist › numpy › float32 › Index.wp
KooR.fr - classe float32 - module numpy - Description de quelques librairies Python
Single-precision floating-point ... on this platform (win32 AMD64): `numpy.float32`: 32-bit-precision floating-point number type: sign bit, 8 bits exponent, 23 bits mantissa....
🌐
GitHub
github.com › numpy › numpy › issues › 14150
How to convert np.float32 to Python float easily? · Issue #14150 · numpy/numpy
July 29, 2019 - Hi, I try to convert np.float32 to a Python float in my project, and I find it's not eaisly. I have to convert it to str and then convert to float. Here is the code: Reproducing code example: import numpy as np x = np.float32(1.9) x.toli...
Author: numpy
Top answer
1 of 5
13

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:  01000111011001010011101011000010
sign    :  0
exponent:  10001110
fraction:  11001010011101011000010

64 bit:  0100000011101100101001110101100001000000000000000000000000000000
sign    :  0
exponent:  10000001110
fraction:  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 np

a = 58682.7578125
f32 = 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 0s
print('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 0s
print('64 bit: ', b64)
print('sign    : ', b64[0])
print('exponent: ', b64[1:12])
print('fraction: ', b64[12:])
2 of 5
2

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

🌐
GitHub
github.com › numpy › numpy › issues › 6860
How to set float32 as default · Issue #6860 · numpy/ ...
December 19, 2015 - I use cuBLAS + numpy, cuBLAS run very fast on float32, 10times faster than CPU. However, I need to set dtype=float32 everytime by hand, it's tedious. random.rand() even doesn't support to create float32 array.
Author: numpy
🌐
Leancrew
leancrew.com › all-this › 2025 › 06 › in-defense-of-floating-point
In defense of floating point - All this
June 28, 2025 - But here’s the thing: a 32-bit float can represent exactly every integer from -16,777,216 to 16,777,216 ( ... python: >>> import numpy as np >>> n = 2**24 >>> ai = np.linspace(-n, n, 2*n+1, dtype=np.int32) >>> af = np.linspace(-n, n, 2*n+1, ...
🌐
GitHub
github.com › numpy › numpy › issues › 25836
BUG: Weird conversion behavior from np.float32 to Python float · Issue #25836 · numpy/numpy
February 16, 2024 - Describe the issue: I found out that converting np.float32 to a Python float via .item() gives a weird result. While I understand NumPy retains the float32 internal representation of the value, I feel that for such a simple value the fol...
Author: numpy
Top answer
1 of 2
2

That's just because Python shows you the nicest representation of that number. The value actually is exactly this:

>>> '%.60f' % fl
'0.100000000000000005551115123125782702118158340454101562500000'

Which is exactly what the literal 0.1 turns into:

>>> '%.60f' % 0.1
'0.100000000000000005551115123125782702118158340454101562500000'

(Oh and it's not 0.10000000149011612 because that's done with 32 instead of 64 bits. And actually that one should be 0.100000001490116119384765625, that converter page is inaccurate.)

2 of 2
1

You can use the gmpy2 library to work with arbitrary precision binary numbers, including the standard 32-bit and 64-bit IEEE formats.

Here is an example:

>>> import gmpy2
>>> gmpy2.set_context(gmpy2.ieee(64))
>>> gmpy2.mpfr("0.1").__format__(".60f")
'0.100000000000000005551115123125782702118158340454101562500000'
>>> gmpy2.set_context(gmpy2.ieee(32))
>>> gmpy2.mpfr("0.1").__format__(".60f")
'0.100000001490116119384765625000000000000000000000000000000000'

Edit: Added example function to convert mpfr to 32-bit IEEE format.

import gmpy2
gmpy2.set_context(gmpy2.ieee(32))

def mpfr_to_float(x):
    '''Convert an mpfr object created by the IEEE 32-bit compatible
    context to a 32 character string containing 0 and 1.'''

    # Check for special values first.

    if gmpy2.is_infinite(x):
        if gmpy2.is_signed(x):
            return "1" * 9 + "0" * 23
        else:
            return "0" + "1" * 8 + "0" * 23

    if gmpy2.is_nan(x):
        return "0" + "1" * 31

    if gmpy2.is_zero(x):
        if gmpy2.is_signed(x):
            return "1" + "0" * 31
        else:
            return "0" * 32

    # Extract the mantissa, exponent, and precision. Note that the
    # values are slightly different than the IEEE 32-bit standard.

    mnt, exp, prc = x.digits(2)

    # MPFR explicitely stores the leading bit of the mantissa so the
    # precision is 24. To support subnormals, MPFR also uses a more
    # negative minimum exponent and decreases the precision of the
    # mantissa but maintains the leading '1' bit.

    # Remove any leading sign bit from the mantissa string.
    if mnt[0] == "-":
        sign_char = "1"
        mnt = mnt[1:]
    else:
        sign_char = "0"

    # Check for subnormals
    if exp + 126 <= 0:
        # Drop the last bit since it will always be '0' and after the
        # adjustments for subnormals, the leading bit will be '0'.
        mnt = mnt[:-1]
    else:
        # Drop the leading '1' bit for normal numbers.
        mnt = mnt[1:]

    # Handle subnormals by shifting trailing bits from the mantissa
    # string to the beginning. Adjust the exponent to match.
    while exp + 126 < 0:
        mnt = mnt[-1] + mnt[:-1]
        exp = exp + 1

    # Adjust the exponent to account for removing a bit from the
    # mantissa string.
    exp = exp - 1

    # Add 127 to the exponent to account for the IEEE encoding.
    exp = exp + 127

    # Validate exponent range.
    if (exp > 255) or (exp < 0):
        raise ValueError("exp is out of bounds")

    # Build and return the binary string.
    result = sign_char + format(exp, "08b") + mnt
    if len(result) != 32:
        raise ValueError("something is wrong....")

    return result


if __name__ == "__main__":
    print(mpfr_to_float(gmpy2.mpfr("0.1")))

Disclaimer #1: This should really be a comment to @Stefan Pochmann's answer but I thought a code example would be helpful.

Disclaimer #2: I maintain gmpy2.