Comment by xigoi

1 day ago

> Makes for horrible footguns like:

> history[counter % SIZE] = …

The footgun here is that the “modulo” operator does not actually calculate the modulo in C. In Python, this works correctly for negative values.

> In Python, this works correctly for negative values.

They’re both “broken” in different ways. Arguably C’s brokenness is more apparent and less useful but Python also has footguns: C uses truncated division for its “modulo” so the remainder has the sign of the dividend, Python uses floored division so the remainder has the sign of the divisor instead.

The wiki page for modulo has a pretty extensive page on the subject.

  • I say you want a pair of operations such that (a, b) = quotient_and_remainder(x, y) gives you a and b such that a * y + b = x

    The Euclidean division and remainder work, the other division and remainder also work, and they're both identical for the positive integers so people who only think about the positive integers won't even notice there's a choice here. So I like that Rust provides both pairs, in the same way Rust provides both Wrapping<T> and Saturating<T> because maybe you mean wrapping overflow or maybe you mean saturating overflow and we should make you choose not just assume we know best.

  • > Python uses floored division so the remainder has the sign of the divisor instead

    Serious question, how is that a footgun? In decades of software development I have never needed a negative divisor for modulo. What would you use it for?