quo vs. //
Last updated at 3:18 pm UTC on 14 January 2006
Question: Andreas Raab April 06, 2004 I got very subtly bitten by // truncating towards negative infinity rather than zero, e.g.,
3//2 -> 1
-3//2 -> -2 “However”
3 quo: 2 -> 1
-3 quo: 2 -> -1
The reason I got bitten is that the C translator generates // as C / which has the semantics of #quo:. Meaning that any translated code which uses integer divide with negative numbers will be subtly off. My question here (and that's the historical part) how comes that // rounds towards negative infinity?
Answer: Dan Ingalls I have always strongly disliked this particular convention.
Someone else was in charge of arithmetic (mainly LargeInts) when we settled on the ST-80 standard and I withdrew from the fray after expressing my opposition. I was told that a lot of mathematicians (which I am not, in the formal sense) expect integer division to truncate toward negative infinity, and I had to trust that this was a good decision for Smalltalk.
I seriously considered "fixing" this when we did Squeak, but it would have been a disastrous incompatibility with the rest of the community.
Answer: Hans-Martin Mosner There are good reasons for both points of view, and it's good to have both operations around. One nice property of \\ and // as they are defined right now is that
(a // b) = ((a + (nb)) // (b + n))
even if n is negative (that is, the operation is invariant under translation )
As you have noted, especially in computer graphics this is an important
property, as you will have weird effects around zero if you round towards zero.
bQuestion: /bAndreas RaabDo you have any examples for [weird effects around zero]? Right now I would've claimed the opposite since I don't remember any such problematic cases from the "C days" (which are a little back admittedly) and the situation in which I was got bitten was a classic one from graphics and sound, namely sampling:
| (b - a) // n n | = | (b - a) |
e.g., if we sample the range (b - a) n times we want to get a step size which ensures that it doesn't exceed the range (b - a) regardless of direction. Right now, using Squeaks // semantics you get:
(100 - 50) // 3 3 ->48
(50 - 100) // 3 3 -> -51