admin管理员组

文章数量:1122832

everyone. I've been learning floating-point truncation errors recently. But I found print(np.half(500.2)) and print(f"{np.half(500.2)}") yield different results. Here are the logs I got in IPython.

In [11]: np.half(500.2)
Out[11]: np.float16(500.2)

In [12]: print(np.half(500.2))
500.2

In [13]: print(f"{np.half(500.2)}")
500.25
  1. I use half.hpp in c++ to compare results with numpy. It seems that 500.2 should be truncated into 500.25 instead of itself.
  2. In binary formats, 500.0 is 0b0_01000_1111010000. So the next float16 number should be 0b_01000_1111010001, which is 500.25 in deximal format.

So what makes print(np.half(500.2)) differs from print(f"{np.half(500.2)}")? Hope to see your answers.

everyone. I've been learning floating-point truncation errors recently. But I found print(np.half(500.2)) and print(f"{np.half(500.2)}") yield different results. Here are the logs I got in IPython.

In [11]: np.half(500.2)
Out[11]: np.float16(500.2)

In [12]: print(np.half(500.2))
500.2

In [13]: print(f"{np.half(500.2)}")
500.25
  1. I use half.hpp in c++ to compare results with numpy. It seems that 500.2 should be truncated into 500.25 instead of itself.
  2. In binary formats, 500.0 is 0b0_01000_1111010000. So the next float16 number should be 0b_01000_1111010001, which is 500.25 in deximal format.

So what makes print(np.half(500.2)) differs from print(f"{np.half(500.2)}")? Hope to see your answers.

Share Improve this question asked Nov 22, 2024 at 2:35 CestimiumCestimium 133 bronze badges 2
  • print(np.half(500.2)) shows a simplified, human-readable version (500.2), while f"{np.half(500.2)}" converts the value to Python's float and reveals the actual stored number (500.25) in the limited precision of float16. – Alexander Kolovsky Commented Nov 22, 2024 at 2:40
  • Nothing to do with your question, just playing smartass here. But 0b0_01000_1111010000 is 0.01526641845703125 in decimal not 500.25. Your forgot the 15 shift of exponent. see struct.unpack('e', struct.pack('H', 0b0_01000_1111010000)) 500.25 is bin(struct.unpack('H', struct.pack('e', 500.25))[0]) aka 0b0_10111_1111010001 (which is the same, with exponent 8 encoded as 23, with shift of 15). But the error proves that you code floating point by hand, and not a lot do that to understand things ;-) – chrslg Commented Nov 22, 2024 at 20:06
Add a comment  | 

1 Answer 1

Reset to default 4

print calls __str__, while an f-string calls __format__. __format__ with an empty format spec is usually equivalent to __str__, but not all types implement it that way, and numpy.half is one of the types that implements different behavior:

In [1]: import numpy

In [2]: x = numpy.half(500.2)

In [3]: str(x)
Out[3]: '500.2'

In [4]: format(x, '')
Out[4]: '500.25'

本文标签: pythonWhat makes print(nphalf(5002)) differs from print(fquotnphalf(5002)quot)Stack Overflow