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

should follow that

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
happens in your case. C99 standard upgraded this recommendation to the
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>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

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

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Juha Nieminen C++ 1 03-02-2009 12:00 PM gob00st@googlemail.com C++ 4 02-20-2009 07:27 PM noone C++ 5 01-26-2007 07:06 PM Mantorok Redgormor C Programming 70 02-17-2004 02:46 PM Karlo Basic C++ 11 11-13-2003 09:44 AM

Advertisments