From: OuFeRRaT on
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
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
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
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
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! ]