openlang

round(2.5) gives 2, and learners don't believe it

Learners keep guessing that round(2.5) is 3, and both languages I reach for say 2. Python gives the integer 2, Julia gives 2.0. Both send a tie to the even neighbour, so round(0.5) is 0 and round(1.5) is 2, and the pattern only shows once a few ties sit side by side.

print([round(x) for x in (0.5, 1.5, 2.5, 3.5)])

That prints [0, 2, 2, 4], and Julia gives the same values as floats. My hunch is that four ties at once teach better than stating the rule, because the 2 next to the other 2 is what looks broken, and then the question turns into why anyone would want this.

What I keep wondering is whether to add negative ties to the first example, where the sign gets involved too, or whether that only adds noise.

后续讨论 4

顺着彼此的依据读下去
  1. 固定链接

    The why is a count. Sum the four ties exactly and you get 8. Round every tie up first and you get 1 + 2 + 3 + 4 = 10. Round ties to even and you get 0 + 2 + 2 + 4 = 8. Rounding up pushes every tie the same way, so the error grows with the number of ties. To even sends as many down as up, and on average it cancels. A learner moving between languages will hit both, since Go's math.Round rounds ties away from zero and math.RoundToEven is the separate function.

  2. 固定链接

    One thing to keep apart from this lesson, I think. round(2.675, 2) gives 2.67 in Python, and learners file it under the same surprise, but it has a different cause. The float closest to 2.675 sits a little below it, so there's no tie to break at all, and the Python docs use this very example. So ties first, with values that are exact in binary such as 0.5 and 2.5, and representation as a second step.

    from decimal import Decimal, ROUND_HALF_UP
    print(Decimal(2.675))
    print(Decimal('2.675').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))

    The first line shows the stored value, 2.67499999999999982236431605997495353221893310546875. The second gives 2.68, because a string keeps the decimal value the learner actually typed.

  3. 固定链接

    Python's round(-0.5) gives the int 0, while round(-0.5, 0) and Julia's round(-0.5) give -0.0. Nobody notices until Julia divides by it and hands back -Inf.

同一个问题的其他角度

  1. Notation first, machine later

    APL was a notation before it was a program. Iverson used it on paper to describe algorithms, and the 1962 book A Programming…

    回复 1最近活动 apl
  2. Where Pharo code actually lives

    Poking at Pharo after a long time with Ruby, and I'm stuck on something embarrassingly basic for someone used to files. I mad…

    回复 1最近活动 smalltalk
  3. A useful review comment on a retain cycle names the owner

    “Just use weak everywhere” is a review comment the author can't really answer. The usual case is a child object holding a del…

    回复 1最近活动 swift