|
Prev: Getting address of enclosing object from address of inner object
Next: same name for types and variables
From: OuFeRRaT on 16 Apr 2008 18:52 Does anyone know why the remainder and the division operations are incorrect with negative numbers in C++? Is it about assembly? OuFeRRaT -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thomas Richter on 17 Apr 2008 02:36 OuFeRRaT schrieb: > Does anyone know why the remainder and the division operations are > incorrect with negative numbers in C++? Is it about assembly? In how far is this incorrect? The modulo operation and division must be defined such that (x/n) * n + (x % n) = x (1) holds, and this should be true (-1 / N = 0) unless your compiler is broken. In fact, C and C++ do not define which sign the modulo operation should have for negative arguments. It only defines that (1) must hold and that the absolute value of the reminder must be smaller than the absolute value of n. The reason for that is that C or C++ want to make "best use" of what the hardware has to offer, and apparently, chip manufacturers aren't certain either which definition to pick for the modulo operation. The one you see here, namely division as "round to zero" and the corresponding consequence, namely modulo giving negative results, is the one I know from intel and Motorola. So long, Thomas -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Marco Manfredini on 17 Apr 2008 02:41 OuFeRRaT wrote: > Does anyone know why the remainder and the division operations are > incorrect with negative numbers in C++? Is it about assembly? They aren't incorrect. They're just not required to follow the definition of "modulus", which is why "%" is called the remainder operator instead. In fact, it's implementation defined. However, C99 (IIRC) defines the result of a%b to have the sign of a, therefore I'd expect this to sneak into most C++ implementations as well. This is probably even reasonable. The basic equality I'd expect to hold is a==b*(a/b)+(a%b). If the sign of the remainder would follow the sign of the divisor, it would be necessary that -10/3==-4 and -10%3==2. In other words, ((a!=0) == ((a/b) != -(-a/b))) would always be true, quite uncomfortably. -- IYesNo yes=YesNoFactory.getFactoryInstance().YES; yes.getDescription().equals(array[0].toUpperCase()); [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Francis Glassborow on 17 Apr 2008 02:43 OuFeRRaT wrote: > Does anyone know why the remainder and the division operations are > incorrect with negative numbers in C++? Is it about assembly? > define what you mean by 'incorrect' They may not be what you expect but they are consistent for any given implementation. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: guinness.tony on 17 Apr 2008 02:41 On 17 Apr, 10:52, OuFeRRaT <oufer...(a)gmail.com> wrote: > Does anyone know why the remainder and the division operations are > incorrect with negative numbers in C++? They are not. See below. > Is it about assembly? Err, no. It's about choosing between two equally valid results. The Holy Standard has the following to say on the matter: -------- [expr.mul]5.6/4: The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined (see footnote 74) Footnote 74: According to work underway toward the revision of ISO C, the preferred algorithm for integer division follows the rules defined in the ISO Fortran standard, ISO/IEC 1539:1991, in which the quotient is always rounded toward zero. -------- When an integer division is inexact (i.e. the divisor does not evenly divide the dividend), there are always two possible choices of result that satisfy these basic requirements: (quotient * divisor) + remainder == dividend and |remainder| < |divisor| For example, when dividing -10 by +3, we could choose either of the following results: quotient = -4, remainder = +2 quotient = -3, remainder = -1 When dividing -10 by -3, we could choose either of the following results: quotient = +4, remainder = +2 quotient = +3, remainder = -1 When dividing +10 by -3, we could choose either of the following results: quotient = -4, remainder = -2 quotient = -3, remainder = +1 As quoted above, the Standard mandates that, when dividing +10 by +3, the remainder must not be negative, yielding only the following result: quotient = +3, remainder = +1 Every compiler that I use (and, clearly, the one that you use) follows the guidance given in the footnote and rounds the quotient towards zero when the dividend and/or the divisor is negative. The net effect is that, for all integer divisions, the result chosen will be the one where the remainder has the same sign as the dividend (or will be zero for exact divisions). Hope this helps, Tony. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 3 Prev: Getting address of enclosing object from address of inner object Next: same name for types and variables |