I stumpled into a test failure caused by floating point precision and am trying to understand it.
In short: Python3 round returns a different value depending on whether the type is a float or a numpy.float64 although I thought float==double==float64 and both Python3 and NumPy should round nearest to even.
Here the example:
npVal = np.float64(435)/100
pyVal = 435/100
print(round(npVal,1)) // 4.4
print(round(pyVal,1)) // 4.3
print(round(np.float64(pyVal),1)) // 4.4
print(round(float(npVal),1)) // 4.3
I understand that 4.35 and 4.4 might not be exactly representable in double but why is numpy round differently than Python although they both use the same datatypes and specify the function similar? I used the explicit division to avoid input rounding errors.
I don't know for sure, whether the double value for 4.35 is a bit more or less, so I can't say which of those implementations is (might be?) wrong.
There is a similar question: Strange behavior of numpy.round
There it was noted, that NumPy "rounds to the nearest even value" and "behaviour changed between Python 2 and Python 3; Python 3 behaves the same as NumPy here".
So both should do the same and round to nearest even value. So if 4.35 would be an exact float, 4.4 would the correct answer and needed to be returned by both.
4.35is the same distance on the number line from4.4as it is from4.3. You could try allowing a higher number of decimals to kick the can a little farther down the road.roundshould round to even as explained in a comment to the linked question: "It's worth noting that this behaviour changed between Python 2 and Python 3; Python 3 behaves the same as NumPy here." I'm asking why this is not the case?printfunction, so is using Python 3, where they should have the same behaviour.roundis correctly-rounded (but slow). NumPy's is not (but is faster). Different tradeoffs. (Agreed that this isn't a duplicate.)numpy.roundrounds to even for values exactly halfway between rounded decimal values. But thenpValin this question cannot be exactly halfway between 4.3 and 4.4 because 4.35 is not representable in 64-bit binary floating-point. The closest representable value is 4.3499999999999996447286321199499070644378662109375, which ought to round down.