Velocity Reviews > The behavior of the operator %

# The behavior of the operator %

PengYu.UT@gmail.com
Guest
Posts: n/a

 03-18-2005
Hi All,

I know the result of the operator % is the remainder. But I don't find
the detailed descriptions, for example from K&R's book
http://freebooks.by.ru/view/CProgram...ter2.html#s2.5

I tried -1 % 10. It gave me -1. How can I make the remainder has the
same sign as the divider? How to get -1 % 10 = 9? Thanks!

Best wishes,
Peng

Walter Roberson
Guest
Posts: n/a

 03-18-2005
In article <(E-Mail Removed). com>,
http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:
:I know the result of the operator % is the remainder.

:I tried -1 % 10. It gave me -1. How can I make the remainder has the
:same sign as the divider? How to get -1 % 10 = 9? Thanks!

In C89, the sign of the result is implimentation dependant.
In C99, they mandated one of the two reasonable behaviours -- and
the behaviour they mandated was the one that will give you negative
results.

There is no standard C pragma or control that can be used to
force one behaviour over the other [though an implimentation might
choose to provide a mechanism], so you will pretty much just have
to test the result -- perhaps with something like

R = M % N;
R += N * ((R < 0 && N > 0) || (R > 0 && N < 0));

Or to be more obtruse,

R += N * (copysign(1,R) * copysign(1,N) < 0);

--
This signature intentionally left... Oh, darn!

Andrey Tarasevich
Guest
Posts: n/a

 03-18-2005
(E-Mail Removed) wrote:

> Hi All,
>
> I know the result of the operator % is the remainder. But I don't find
> the detailed descriptions, for example from K&R's book
> http://freebooks.by.ru/view/CProgram...ter2.html#s2.5
>
> I tried -1 % 10. It gave me -1. How can I make the remainder has the
> same sign as the divider? How to get -1 % 10 = 9? Thanks!
> ...

It makes sens to have the result of % operator to be in agreement with
the result of / operator (integral division) in a sense that from

q = a / b
r = a % b

a = b * q + r

Now, what do you think is the result of -1/10? In C89/90, both 0 and -1
are acceptable results. The standard leaves this decision to the
implementation (i.e. it is implementation-defined). If some
implementation decides to evaluate -1/10 as 0, then normally it will
evaluate -1%10 as -1. If some other implementation evaluates -1/10 as
-1, then normally it will evaluate -1%10 as 9.

The C89/90 standard _recommends_ that implementation use the former
variant (Fortran-style division, rounding to 0), meaning that most of
the time you'll see -1/10 == 0 and -1/10 == -1. That's probably what
level of mandatory requirement.

If you want the other behavior, you have to implement it manually. If
you are using a C89/90 compiler, you can also try to look for a compiler
option that control this behavior on program-wide scale (if that's what
you need).

--
Best regards,
Andrey Tarasevich

osmium
Guest
Posts: n/a

 03-18-2005
<(E-Mail Removed)> wrote:

> I know the result of the operator % is the remainder. But I don't find
> the detailed descriptions, for example from K&R's book
> http://freebooks.by.ru/view/CProgram...ter2.html#s2.5
>
> I tried -1 % 10. It gave me -1. How can I make the remainder has the
> same sign as the divider? How to get -1 % 10 = 9? Thanks!

The phrase "machine dependant" means the sign depends on the machine on
which the program is being run. The language does not specify a result.

Andrey Tarasevich
Guest
Posts: n/a

 03-18-2005
Andrey Tarasevich wrote:
>
> The C89/90 standard _recommends_ that implementation use the former
> variant (Fortran-style division, rounding to 0), meaning that most of
> the time you'll see -1/10 == 0 and -1/10 == -1. That's probably what

A typo. Should be:

[...] you'll see -1/10 == 0 and -1%10 == -1. [...]

> happens in your case. C99 standard upgraded this recommendation to the
> level of mandatory requirement.

--
Best regards,
Andrey Tarasevich

Mark McIntyre
Guest
Posts: n/a

 03-18-2005
On 18 Mar 2005 13:09:09 -0800, in comp.lang.c , "(E-Mail Removed)"
<(E-Mail Removed)> wrote:

>Hi All,
>
>I know the result of the operator % is the remainder. But I don't find
>the detailed descriptions, for example from K&R's book
>http://freebooks.by.ru/view/CProgram...ter2.html#s2.5
>
>I tried -1 % 10. It gave me -1. How can I make the remainder has the
>same sign as the divider? How to get -1 % 10 = 9? Thanks!

AFAIR in C89, this is platform specific and you need to work around it.

Bear in mind that both -1 and 9 are valid answers as long as both operands are
integers, since the result must satisfy (a/b)*b+a%b =a, and its
implementation-defined whether -1/10 is -1 or 0 (round down or up). I seem to
recall that C99 changed this to always round towards zero, but I can't find the
reference.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>

Christian Bau
Guest
Posts: n/a

 03-19-2005
In article <(E-Mail Removed). com>,
"(E-Mail Removed)" <(E-Mail Removed)> wrote:

> Hi All,
>
> I know the result of the operator % is the remainder. But I don't find
> the detailed descriptions, for example from K&R's book
> http://freebooks.by.ru/view/CProgram...ter2.html#s2.5
>
> I tried -1 % 10. It gave me -1. How can I make the remainder has the
> same sign as the divider? How to get -1 % 10 = 9? Thanks!

If the result has the wrong sign, then just add the divisor and the sign
will be correct.

Andrey Tarasevich
Guest
Posts: n/a

 03-19-2005
P.J. Plauger wrote:
> ...
>> If you want the other behavior, you have to implement it manually. If
>> you are using a C89/90 compiler, you can also try to look for a compiler
>> option that control this behavior on program-wide scale (if that's what
>> you need).

>
> How 'bout div and ldiv?
> ...

According to what I see in C89/90, these functions are required to round
the quotient towards zero.

--
Best regards,
Andrey Tarasevich

Richard Bos
Guest
Posts: n/a

 03-21-2005
http://www.velocityreviews.com/forums/(E-Mail Removed)-cnrc.gc.ca (Walter Roberson) wrote:

> (E-Mail Removed) <(E-Mail Removed)> wrote:
> >I tried -1 % 10. It gave me -1. How can I make the remainder has the
> >same sign as the divider? How to get -1 % 10 = 9? Thanks!

> There is no standard C pragma or control that can be used to
> force one behaviour over the other [though an implimentation might
> choose to provide a mechanism], so you will pretty much just have
> to test the result -- perhaps with something like
>
> R = M % N;
> R += N * ((R < 0 && N > 0) || (R > 0 && N < 0));
>
> Or to be more obtruse,
>
> R += N * (copysign(1,R) * copysign(1,N) < 0);

Or replace the whole lot by

R = ((M%N)+N) % N);

if you know that it'll always be used with positive N.

Richard