0

I am playing around with python print function and came across this problem.

print('%.2f' % (0.665)) # 0.67
print('%.3f' % (0.0625))# 0.062

Since when two decimal places are kept for 0.665 and the result is 0.67, I expect that the output of keeping three decimal places of 0.0625 to be 0.063 but the result is 0.062.

wkkxixi
  • 13
  • 2
  • I don't understand what you added in your edit. The behavior you describe (round ->0.063, print->0.062) is the one that I have with Python 2. With Python 3, both methods yield the same result, 0.063. – Thierry Lathuille Aug 10 '19 at 12:45

2 Answers2

3

The general rule is that when the rounded-off part of a number is exactly 5, you choose the direction that makes the final resulting digit even - this avoids any systematic bias in these halfway cases. This applies in the case of 0.0625, which is one of the uncommon decimal numbers that have an exact representation in floating-point binary - its final digit truly is a 5. (For an example of a number that rounds up in this case, try 0.375 to two places.) The number 0.665, on the other hand, does not actually exist - the closest floating-point value is actually 0.6650000000000000355271. The rounded-off part is definitely (although only slightly) greater than 5, so it necessarily rounds up.

jasonharper
  • 9,450
  • 2
  • 18
  • 42
  • Also note: Python uses a round half-even strategy, so even for exactly representable `float`s, you will sometimes see it round a trailing `5` up, and sometimes down (it rounds in favor of making the last digit even). That's why `0.0625` rounds down, while `0.375` rounds up. Per [the docs](https://docs.python.org/3/library/functions.html#round): "if two multiples are equally close, rounding is done toward the even choice (so, for example, both `round(0.5)` and `round(-0.5)` are 0, and `round(1.5)` is `2`)." – ShadowRanger Aug 07 '19 at 14:29
1

It is, as often, the annoying problem with floating point rounding.

.0625 can be represented in an exact way, so it is rounded down. (2 is even, so the most usual rounding algorithm decides to round down in these cases.)

.665 cannot be represented in an exact way (its internal representation is either slightly smaller or slightly bigger than the given number. In this case it is probably slightly bigger, so despite the 6 before the 5 being even, it rounds up.

glglgl
  • 89,107
  • 13
  • 149
  • 217