Numpy float32 and floating point comparison

Continued Difference between Python float and numpy float32 :

import numpy as np

a = 58682.7578125
print(type(a), a)
float_32 = np.float32(a)
print(type(float_32), float_32)
print(float_32 == a)

Print

<class 'float'> 58682.7578125
<class 'numpy.float32'> 58682.8
True

I fully understand that comparing a float for equality is not a good idea, but still it should not be False (are we talking about differences in the first decimal digit, not 0.000000001)? Does it depend on the system? Is this documented somewhere?

EDIT: Well, this is the third decimal digit:

print(repr(float_32), repr(a))
# 58682.758 58682.7578125

but if I can trust repr? How are they stored internally?

EDIT2: People insist that printing float_32 with more accuracy will give me their idea. However, as I already commented according to nympy docs :

the% formatting operator requires its arguments to be converted to standard python types

and

print(repr(float(float_32)))

prints

58682.7578125

@MarkDickinson , repr ( , np.float32).

, :

  • float_32 a ? , , ,
  • up/downcasting python float np.float32? , float_32 float, @WillemVanOnsem

python:

Python 3.5.2 (v3.5.2: 4def2a2901a5, 25 2016, 22:18:55) [MSC v.1900 64 (AMD64)] win32

+4
5

, 58682.7578125 32-, 64- . :

32 bit:  01000111011001010011101011000010
sign    :  0
exponent:  10001110
fraction:  11001010011101011000010

64 bit:  0100000011101100101001110101100001000000000000000000000000000000
sign    :  0
exponent:  10000001110
fraction:  1100101001110101100001000000000000000000000000000000

, - 64- .

, , . , 58682.757812 4, , ; 32 , .

( , float32 float64 . , numpy, .)

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:])
+4

, print

Try:

 print "%0.8f" % float_32

. numpy.float64

+2

58682.7578125 (7511393/128).

2 (2**7), - 23 . , float32 ( 24 ), float64.

, : .

, true , , , (2 == 2.0)?

+2

. , . ​​

float_32 a ?

, , " ". , :

>>> b = numpy.float32(a)
>>> numpy.unpackbits(numpy.array([b]).view(numpy.uint8))
array([1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,
       1, 0, 1, 0, 0, 0, 1, 1, 1], dtype=uint8)

" ", . ( , , .)

C, NumPy float32 C... , C. C, C- . , , - C float, ! ! , , , , .

, , str.format float, decimal.Decimal .

>>> b
58682.758
>>> decimal.Decimal(float(b))
Decimal('58682.7578125')

58682.7578125 float, , , . , , .

up/downcasting python float np.float32?

Float32 float64 .

+2

58682.8

58682,758 .

, float - .

" ", . , , .

? - ?

. , float32 . , float32 7 , Python, float64 ( , x86). . float - , . , 58682.7578125 58682.758: ULP.

, "float" numpy float64, , :

>>> 58682.758 == 58682.7578125
False
>>> numpy.float32(58682.758) == numpy.float32(58682.7578125)
True
>>> print(repr(numpy.float32(58682.758).data[0:4]))
'\xc2:eG'
>>> print(repr(numpy.float32(58682.7578125).data[0:4]))
'\xc2:eG'
>>> numpy.float64(58682.758) == numpy.float64(58682.7578125)
False
>>> print(numpy.float64(58682.758).hex(), numpy.float64(58682.7578125).hex())
('0x1.ca7584189374cp+15', '0x1.ca75840000000p+15')

You are fortunate that these two values ​​are equal in float32 with this particular value (was it intentional?), But it could be different with another.

0
source

Source: https://habr.com/ru/post/1680695/


All Articles