I am trying to round some Float64 values and don’t understand the behavior of the round() function for specific values.

If I take:

round(0.585, digits=2, RoundNearestTiesUp)

I get 0.59, as expected, since I want values to be rounded up when ending in a 5.

However, for:

round(0.575, digits=2, RoundNearestTiesUp)

I get 0.57, which I don’t understand. This goes for 0.565 as well for some reason.

My question is why does this happen, particularly when I get the expected behavior for 0.505,0.515…0.595, except for 0.565 and 0.575?

I assume this has to do with the RoundingMode, but does anyone have any suggestions as to how I can consistently get the appropriate rounding of Float64s that I’m looking for; a work around perhaps?

Float64(0.585) is exactly halfway between Float64(0.58) and Float64(0.59). However, the same is true for Float64(0.575), which is exactly halfway between Float64(0.57) and Float64(0.58):

Well, strangely, it might not be as rare in real application.

In my case, I was trying to verify a min-max normalization on a fairly large data-set of around 42000 entries. I used DataFrames’ transform function to apply the calculation and rounding of the result across each value in the DataFrame.

And since, I already have a normalized version of the data (I was just checking them), I found some inaccuracies in comparing my results and to those of the pre-normalized data.

With that said, unexpected rounding was on average extremely infrequent. Nevertheless, I could see decimal floating point having a place in data manipulations that require a great deal of accuracy.