Modulus and negative operands

Discussion in 'C Programming' started by August Karlstrom, Jan 12, 2006.

  1. 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
    General Public License.
     
    August Karlstrom, Jan 12, 2006
    #1
    1. Advertising

  2. August Karlstrom

    Michael Mair Guest

    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.
     
    Michael Mair, Jan 12, 2006
    #2
    1. Advertising

  3. 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
    General Public License.
     
    August Karlstrom, Jan 12, 2006
    #3
  4. August Karlstrom

    Michael Mair Guest

    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.
     
    Michael Mair, Jan 12, 2006
    #4
  5. August Karlstrom

    Eric Sosman Guest

    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;

    --
     
    Eric Sosman, Jan 12, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. prem_eda
    Replies:
    5
    Views:
    7,869
    Pieter Hulshoff
    Oct 11, 2004
  2. Frank Buss
    Replies:
    5
    Views:
    10,276
    Duane Clark
    Jul 1, 2006
  3. Jim Hunter

    Modulus of a negative number

    Jim Hunter, Feb 23, 2005, in forum: C Programming
    Replies:
    3
    Views:
    6,822
    ruang
    May 4, 2010
  4. Kavya
    Replies:
    9
    Views:
    513
    Dik T. Winter
    Oct 28, 2006
  5. somenath
    Replies:
    11
    Views:
    814
Loading...

Share This Page