Canuck - 2 months ago 13

Python Question

Example of this major problem:

`c=np.array([2600.0])`

In [3]: c=c.astype(np.float16)

In [4]: c

Out[4]: array([ 2600.], dtype=float16)

All good, then:

`In [5]: c=np.array([2583.0])`

In [6]: c=c.astype(np.float16)

In [7]: c

Out[7]: array([ 2584.], dtype=float16)

So 2583.0 turns to 2584.0, cool that's not going to cause any problems!!!!

I have also seen 2583.0 convert in the opposite direction to 2582.0 when I converted a large array to np.float16.

What is going on I spent a literal full day trying to find this bug

and I never imagined this was happening to my data? I am using float16

to limit my memory consumption but if its this dangerous I will move on up to 32 bits.

Can anyone shed some light on this?

Thanks very much everyone.

Answer

A 16-bit float is not a very precise data type. It has only 11 bits of precision. It cannot exactly represent all integers greater than 2048. Between 2048 and 4096, only the even integers have exact representations. Odd integers will be rounded to one of the nearest even integers.

You can read more about this in the Wikipedia page about half-width floats. Here's the most important passage for your issue:

Precision limitations on integer values

- Integers between 0 and 2048 can be exactly represented
- Integers between 2049 and 4096 round to a multiple of 2 (even number)
- Integers between 4097 and 8192 round to a multiple of 4