5 ms·
Careful what you wish for. What should -7 / 2 return? -3 kind of makes sense, because 7/2 is 3. It also desirable to have the remainder consistent with the res
by superjan 5y ago
Careful what you wish for. What should -7 / 2 return? -3 kind of makes sense, because 7/2 is 3.
It also desirable to have the remainder consistent with the result of division, such that x = d*r + mod, where r is the result of division. Combine that with the above requires negative mods.
- masklinn 5y ago> Careful what you wish for. What should -7 / 2 return? -3 kind of makes sense, because 7/2 is 3. -4 also makes sense. > It also desirable to have the remainder consistent with the result of division, such that x = d*r + mod, where r is the result of division. Combine that with the above requires negative mods. Python's behaviour is consistent with that definition: >>> divmod(-7, 2) (-4, 1) -7 = -4 * 2 + 1
- naniwaduni 5y agoIt's highly desirable for -7/2 to equal -4, since this lets integer division by powers of two be exactly equivalent to a two's complement arithmetic right shift. In a C mindset, rounding toward zero is pretty much an objectively wrong holdover from before we knew better.
- Laremere 5y agoMoving past the intuition for how division and remainders work for real numbers, there are other ways to look at "obvious" answers that suggests -7/2=4. Consider x/3=y. For real numbers, it's trivial to manipulate this equation into (x-3)/3=y-1. However, this only works when integer division rounds down. 5/3 = 1 rem 2 or 1 rem 2 4/3 = 1 rem 1 or 1 rem 1 3/3 = 1 rem 0 or 1 rem 0 2/3 = 0 rem 2 or 0 rem 2 1/3 = 0 rem 1 or 0 rem 1 0/3 = 0 rem 0 or 0 rem 0 -1/3 = -1 rem 2 or 0 rem -1 -2/3 = -1 rem 1 or 0 rem -2 -3/3 = -1 rem 0 or -1 rem 0 One of these has a consistent pattern, the other doesn't. All of this is a fairly moot point: The answer is it should do what the algorithm using it needs it to do.
- superjan 5y agoIt is not so much my intuition but the intuition of the language designers. I would prefer euclidian division personally.
- strenholme 5y agoTrue, but both Python’s “int()” operation and the C99 and C11 standard for division operators truncate towards 0. [1] [1] e.g. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf PDF page 94/physical page 82
- housecarpenter 5y agoPython's int() truncates towards 0, but (at least in Python 3, I don't know if it was always the same in older versions) its division operator always floors, so -7 // 2 gives -4 even though int(-3.5) is 3. (The int() function is best thought of as just "make this float into an integer, I don't really care how"; if you want to be more specific, you have math.floor(), math.ceil() and math.trunc(), and you also have round(), which rounds towards the closest integer; if the float is evenly between the two integers, it goes towards 0 when the integer part is even and away from 0 when the integer part is odd.)
- strenholme 5y agoIn my experience, when looking at how division should operate for a given well-established language, it doesn’t matter what you and I think should be the result of the operation; it matters what the standard says on it. From PDF page 94 (physical page 82) of the draft C99 standard: [1] The result of the / operator is the quotient from the division of the first operand by the second This is a little vague; it would be better if they called it the “quotient from Euclidean division” (EDIT: This was incorrect. Actually, it’s the quotient from algebraic division, with the fraction truncated, also called “truncation towards zero”. See discussion below.), which is well defined as being -3 in the above example; see https://en.wikipedia.org/wiki/Euclidean_division https://en.wikipedia.org/wiki/Euclidean_division (EDIT: Euclidean is -4; truncation towards 0 is -3) [1] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
- naniwaduni 5y agoEuclidian division actually gives -7 = -4*2 + 1
- strenholme 5y agoIt’s -3 in GCC 11.2.0 main() { printf("%d\n",-7/2);} Let’s look at, oh, C11: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf PDF page 110, physical page 92: When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded. with a footnote: This is often called ‘‘truncation toward zero’’ -7/2 is -3.5, so discarding the fractional part gives us -3
- naniwaduni 5y agoYes, and this is not Euclidean division in the usual sense.
- strenholme 5y agoIndeed. The C99 and C11 standards define integer division as the “algebraic quotient with any fractional part discarded”, not as Euclidean division.