1

I'm having trouble working out how to round some data up to every 0.02. Here's my code:

def cpt_rnd(x):
    return np.floor(x*50)/50

x = np.array([32.16, 32.18, 32.2, 32.22])

d = cpt_rnd(x)
print(d)

Which returns:

[32.14, 32.18, 32.2,  32.22]

And is missing the 32.16 - it has been rounded down to 32.14

I'm noticing similar behaviour in both ceil and floor not returning the correct answer. Here's the output using np.ceil instead

[32.16, 32.18, 32.22, 32.22]

In this example there should be a 32.2 then 32.22, instead 32.22 is repeated. Any help would be appreciated!

8556732
  • 281
  • 2
  • 9
  • Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – MisterMiyagi Jul 28 '21 at 12:18

1 Answers1

2

This happens due to the finite resolution of floating-point numbers on a computer leading to slightly inaccurate results when you perform arithmetic operations on them (Roundoff error caused by floating-point arithmetic). You can see what happens by just performing the parts of your algorithm separately:

>>> 32.16*50
1607.9999999999998

So you see this is slightly off from the exactly accurate result of 1608.0 and will result in 1607.0 after applying np.floor().

What you could do to fix this is put a np.round() inside the np.floor() call, i.e.:

def cpt_rnd(x):
    return np.floor(np.round(x*50))/50

By default, np.round() rounds off to the nearest integer, which is exactly what we want here.

smheidrich
  • 4,063
  • 1
  • 17
  • 30