Velocity Reviews > Modulus and negative operands

# Modulus and negative operands

August Karlstrom
Guest
Posts: n/a

 01-12-2006
Hi,

How come the modulus operator doesn't always yield non-negative values?
I expect e.g. (-1) % 3 to be 2 but I get -1. If I want to decrement a
cyclic variable n by k I have to write something like

n = ((n - k) % length + length) % length

where as in e.g. Pascal i can simply write

n := (n - k) MOD length

to get the desired result.

August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU

Michael Mair
Guest
Posts: n/a

 01-12-2006
August Karlstrom wrote:
> Hi,
>
> How come the modulus operator doesn't always yield non-negative values?
> I expect e.g. (-1) % 3 to be 2 but I get -1. If I want to decrement a
> cyclic variable n by k I have to write something like
>
> n = ((n - k) % length + length) % length
>
> where as in e.g. Pascal i can simply write
>
> n := (n - k) MOD length
>
> to get the desired result.

% is defined in terms of / (see below).
If / rounds down, then % yields positive values.
If / rounds to zero, you get the observed behaviour.
C89 allows both, C99 only round-to-zero.

From the last public draft of C89:
,---
3.3.5 Multiplicative operators

Syntax

multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression

Constraints

Each of the operands shall have arithmetic type. The operands of
the % operator shall have integral type.

Semantics

The usual arithmetic conversions are performed on the operands.

The result of the binary * operator is the product of the operands.

The result of the / operator is the quotient from the division of
the first operand by the second; the result of the % operator is the
remainder. In both operations, if the value of the second operand is
zero, the behavior is undefined.

When integers are divided and the division is inexact, if both
operands are positive the result of the / operator is the largest
integer less than the algebraic quotient and the result of the %
operator is positive. If either operand is negative, whether the
result of the / operator is the largest integer less than the
algebraic quotient or the smallest integer greater than the algebraic
quotient is implementation-defined, as is the sign of the result of
the % operator. If the quotient a/b is representable, the expression
(a/b)*b + a%b shall equal a .
`---

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.

August Karlstrom
Guest
Posts: n/a

 01-12-2006
Michael Mair wrote:
> % is defined in terms of / (see below).
> If / rounds down, then % yields positive values.
> If / rounds to zero, you get the observed behaviour.

[snip]

OK, but what's the benefit of this behavior?

August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU

Michael Mair
Guest
Posts: n/a

 01-12-2006
August Karlstrom wrote:
> Michael Mair wrote:
>
>> % is defined in terms of / (see below).
>> If / rounds down, then % yields positive values.
>> If / rounds to zero, you get the observed behaviour.

>
> [snip]
>
> OK, but what's the benefit of this behavior?

- It is well-defined.
- Probably historical reasons.

If you are asking for more of a rationale,
http://www.lysator.liu.se/c/rat/c3.html#3-3-5 comes to mind.
Probably this is not enough, either. Maybe someone else
can contribute more.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.

Eric Sosman
Guest
Posts: n/a

 01-12-2006

August Karlstrom wrote On 01/12/06 14:01,:
> Michael Mair wrote:
>
>>% is defined in terms of / (see below).
>>If / rounds down, then % yields positive values.
>>If / rounds to zero, you get the observed behaviour.

>
> [snip]
>
> OK, but what's the benefit of this behavior?

The benefit of "truncate toward zero" on division are
mostly conventional: That's the way practically all known
hardware does division, and that's also the way Fortran
defines it. According to the C99 Rationale, compatibility
with Fortran was the main reason for requiring "truncate
toward zero."

Quotient and remainder are governed by the identity

(a / b) * b + (a % b) == a

(unless the division itself is undefined). Whichever
way the quotient is chosen on an inexact division, the
modulus must "balance" the truncation error. If division
truncates toward zero, the truncated negative quotient
will be larger than the true mathematical quotient, so
the "correction" must be negative.

> If I want to decrement a
> cyclic variable n by k I have to write something like
>
> n = ((n - k) % length + length) % length

If k <= length, this can be simplified to

n = (n - k + length) % length

or to

if ((n -= k) < 0)
n += length;

--
http://www.velocityreviews.com/forums/(E-Mail Removed)