0

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.

Canuck
  • 567
  • 1
  • 7
  • 15
  • 2
    Possible duplicate of [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Eli Sadoff Nov 17 '16 at 02:06
  • floats can't keep all real numbers so they keep only aproximation. `0.1 + 0.2 == 0.3` gives `False` – furas Nov 17 '16 at 02:09
  • Thanks for the link, I may be mistaken but it seems that this error is much more egregious then what is discussed in that link at first glance. I believe the problem I am having is indicative of a much more glaring flaw but as always I could be wrong and I will examine it more closely. Thanks! – Canuck Nov 17 '16 at 02:11
  • I understand but how is it that a whole integer can be gained or dropped? I am not utilizing any truth test here? – Canuck Nov 17 '16 at 02:14
  • 4
    https://en.wikipedia.org/wiki/Half-precision_floating-point_format: Integers between 0 and 2048 can be exactly represented; Integers between 2049 and 4096 round to a multiple of 2 (even number), etc. Just part of the standard/definition. – Benjamin Nov 17 '16 at 02:17
  • Clearly this is what is happening.Thanks Benjamin. – Canuck Nov 17 '16 at 02:20
  • There's a reason that the smallest floats you typically encounter are 32 bits - 16 bits just isn't enough for most applications. You might be able to get away with it for imaging. – Mark Ransom Nov 17 '16 at 02:50

1 Answers1

10

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
Community
  • 1
  • 1
Blckknght
  • 100,903
  • 11
  • 120
  • 169