-1

I noticed when converting from numpy array to list that python adds extra decimals. For example here I have some bytes that I convert to a numpy array with float32 elements:

import numpy as np

b = bytes([174, 153, 92, 59])
a = np.frombuffer(b, dtype=np.float32)
print(a[0])
print(a.tolist()[0])

Output:

0.0033660936
0.0033660936169326305

On the conversion with a.tolist() it adds extra decimals.

What is happening here? Do I loose some precision, or where is python finding these extra decimals?

TryingMyBest
  • 131
  • 1
  • 1
  • 7
  • NumPy is just providing a different way of representing a float compared to standard Python. The underlying binary value is the same. (Potentially, you go from 32 bit floating point to 64 bit floating point, but as far as I know, a 32 bit floating point number can be exactly contained in a 64 bit floating point number.) – 9769953 Feb 17 '22 at 07:05
  • 2
    Obligatory reading: [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken). – 9769953 Feb 17 '22 at 07:05
  • Intersting read! So the main gist is to round off to how many decimals places I need? – TryingMyBest Feb 17 '22 at 07:21
  • 1
    No, it is about how many decimal places you want to *show*, while keeping in the back of your mind how many decimal places shown are actually valid (when going from binary to decimal representation). – 9769953 Feb 17 '22 at 07:29

2 Answers2

1

with .tolist you change the datatype from float32 to float. Check:

import numpy as np

b = bytes([174, 153, 92, 59])
a = np.frombuffer(b, dtype=np.float32)
a = np.array(a, dtype=np.float)
print(a[0])
print(a.tolist()[0])
Kilian
  • 468
  • 2
  • 9
  • you are right but let be more precise: it create explicetely a numpy 32bit float. when marchalling to Python 'float', it's in fact ant 64bit float. ther is in this case no way to have the exact value between floet32 and float64 – ManuGoacolou Feb 17 '22 at 07:27
0

try print out their type

print(type(a[0])) # numpy.float32
print(type(a.tolist()[0])) # float

when you call tolist(), it changes numpy scalars to Python scalars. Python default float is float64, which is the same as numpy.float64. That's why the second one shows extra decimals. If you try a = np.frombuffer(b, dtype=np.float64), and then call tolist(), two values should be the same.

CJR
  • 76
  • 4