question regarding % operator.

S

somenath

Hello All,

In the section 2.5 Arithmetic Operator of K&R2 says that "... the
sign of result for % are machine-dependent for negative operand, as
the action taken on overflow or underflow."

I have failed to understand why the sign of -2%3 or -2%-3 or 2%-3 has
to be machine dependent?
Could you please explain how the % operator behaves in C ? I
understand that in all the above case the result will be 2 if both
the number is positive. In case of negative number how it should work?

Please provide some inputs.
 
E

Eric Sosman

Hello All,

In the section 2.5 Arithmetic Operator of K&R2 says that "... the
sign of result for % are machine-dependent for negative operand, as
the action taken on overflow or underflow."

I have failed to understand why the sign of -2%3 or -2%-3 or 2%-3 has
to be machine dependent?
Could you please explain how the % operator behaves in C ? I
understand that in all the above case the result will be 2 if both
the number is positive. In case of negative number how it should work?

Please provide some inputs.

K&R II is based on the original ANSI C Standard of two decades
ago, and there have been some changes since. But let's begin at
the beginning ...

First, % is often called the "modulo" operator, but it might
have been better to call it the "remainder" operator. When an
integer division is inexact there is a non-zero remainder, and
this is the quantity % delivers. 6 / 3 is 2, exactly, so 6 % 3
is zero. 7 / 3 is 2, INexactly, so 7 % 3 is 1. For positive N,
Q = N / 3 is the quotient (exact or inexact) and R = N % 3 is the
amount of N "left over," not accounted for in the quotient. You
can always recover N from Q and R: N = Q * 3 + R.

But what if N is negative? If the division is exact there's
no problem: -6 / 3 is -2, exactly, so the remainder -6 % 3 is zero.
But -7 / 3 could (under ANSI C rules) be either -2 ("round toward
zero") or -3 ("round toward minus infinity"), and implementations
were allowed to produce either result. Whichever they chose to
deliver, though, they had to make N = Q * 3 + R work correctly.
So if -7 / 3 gave Q = -2, then -7 % 3 had to deliver R = -1. If
-7 / 3 yielded Q = -3, then -7 % 3 had to produce R = +2. Similar
considerations apply for 7 / -3 and 7 % -3: The implementation had
a choice of two possible quotients, but had to deliver a remainder
that made 7 = Q * -3 + R work.

The original ANSI C Standard has been revised several times,
and the C99 revision tightened the rules a bit. Specifically, it
took away the implementation's choice of which quotient to produce:
Division must now "round toward zero," always. Nowadays, -7 / 3
must produce -2 (never -3), so the remainder must be -7 % 3 = -1,
(never +2). As before, N = Q * 3 + R always holds -- but now there's
no choice about what Q and R must be.
 
S

somenath

     K&R II is based on the original ANSI C Standard of two decades
ago, and there have been some changes since.  But let's begin at
the beginning ...

     First, % is often called the "modulo" operator, but it might
have been better to call it the "remainder" operator.  When an
integer division is inexact there is a non-zero remainder, and
this is the quantity % delivers.  6 / 3 is 2, exactly, so 6 % 3
is zero. 7 / 3 is 2, INexactly, so 7 % 3 is 1.  For positive N,
Q = N / 3 is the quotient (exact or inexact) and R = N % 3 is the
amount of N "left over," not accounted for in the quotient.  You
can always recover N from Q and R: N = Q * 3 + R.

     But what if N is negative?  If the division is exact there's
no problem: -6 / 3 is -2, exactly, so the remainder -6 % 3 is zero.
But -7 / 3 could (under ANSI C rules) be either -2 ("round toward
zero") or -3 ("round toward minus infinity"), and implementations
were allowed to produce either result.  Whichever they chose to
deliver, though, they had to make N = Q * 3 + R work correctly.
So if -7 / 3 gave Q = -2, then -7 % 3 had to deliver R = -1.  If
-7 / 3 yielded Q = -3, then -7 % 3 had to produce R = +2.  Similar
considerations apply for 7 / -3 and 7 % -3: The implementation had
a choice of two possible quotients, but had to deliver a remainder
that made 7 = Q * -3 + R work.

     The original ANSI C Standard has been revised several times,
and the C99 revision tightened the rules a bit.  Specifically, it
took away the implementation's choice of which quotient to produce:
Division must now "round toward zero," always.  Nowadays, -7 / 3
must produce -2 (never -3), so the remainder must be -7 % 3 = -1,
(never +2).  As before, N = Q * 3 + R always holds -- but now there's
no choice about what Q and R must be.

Many thanks for the great response.
So in case of 7/3 there also exist choices. It can be either 2 or 3.
But in C it is 2. So does it mean the choice was made to round toward
zero?
 
J

James Kuyper

....
So in case of 7/3 there also exist choices. It can be either 2 or 3.
But in C it is 2. So does it mean the choice was made to round toward
zero?

Well, yes - that is precisely what he said.
 
F

Fred K

Well, yes - that is precisely what he said.


One can't tell what choice was made for positive numbers - for positive numbers, "round toward zero" and "round toward negative infinity" always produce the same result.
 
J

James Kuyper

One can't tell what choice was made for positive numbers - for positive numbers, "round toward zero" and "round toward negative infinity" always produce the same result.

Yes, you can tell what choice was made. Just read what it says in the
standard: "the result of the / operator is the algebraic quotient with
any fractional part discarded.105" (6.5.5p6). The 105 refers to footnote
105, which explains that "This is often called ‘‘truncation toward
zero’’.". Alternatively, you could simply read the paraphrase of
footnote 105 that was written by Eric Sosman and quoted by me above.

I can understand questioning the accuracy of his paraphrase; but after
being told "A is true, always", to ask "Is A true in this particular
case?" seems a bit odd, unless you have some particular reason to doubt
the "always" part; somenath provided no such reason.
 
J

James Kuyper

On Monday, March 12, 2012 7:15:48 AM UTC-7, James Kuyper wrote: ....

Not necessarily - for positive numbers, "round toward zero" and "round toward negative infinity" always produce the same result.


On Monday, March 12, 2012 7:15:48 AM UTC-7, James Kuyper wrote: ....

On Monday, March 12, 2012 7:15:48 AM UTC-7, James Kuyper wrote: ....

On Monday, March 12, 2012 7:15:48 AM UTC-7, James Kuyper wrote: ....
....

Whatever method you're using to insert quotes from the message you're
responding to, it seems to have developed a stutter. Is this another
Google Groups bug?
 
S

somenath

Yes, you can tell what choice was made. Just read what it says in the
standard: "the result of the / operator is the algebraic quotient with
any fractional part discarded.105" (6.5.5p6). The 105 refers to footnote
105, which explains that "This is often called ‘‘truncation toward
zero’’.". Alternatively, you could simply read the paraphrase of
footnote 105 that was written by Eric Sosman and quoted by me above.

I can understand questioning the accuracy of his paraphrase; but after
being told "A is true, always", to ask "Is A true in this particular
case?" seems a bit odd, unless you have some particular reason to doubt
the "always" part; somenath provided no such reason.

I was not expressing my doubt rather I was trying to be assured that I
understood correctly. Also when I said the options regarding positive
number I meant truncation toward zero and truncation toward positive
infinity not toward negative infinity.
 
E

Eric Sosman

Many thanks for the great response.
So in case of 7/3 there also exist choices. It can be either 2 or 3.
But in C it is 2. So does it mean the choice was made to round toward
zero?

Yes, even before C was standardized. The original K&R (now
sometimes called "K&R I" to distinguish it from the later work)
says

When positive integers are divided truncation is toward
zero, but the form of truncation is machine-dependent if
either operand is negative. [...] It is always true
that (a/b)*b + a%b is equal to a (if b is not 0).

This particular choice was made for C in Ancient Times. One
supposes that it was inspired by the behavior of the machines
known to R, and that the leeway for negatives represented R's
caution about machines where C might someday be implemented.
The freedom was preserved in the original ANSI Standard, but
by the time C99 rolled around the Committee apparently decided
that "round toward minus infinity" machines were either non-
existent or so rare as to be negligible.
 
T

Tim Rentsch

Eric Sosman said:
Many thanks for the great response.
So in case of 7/3 there also exist choices. It can be either 2 or 3.
But in C it is 2. So does it mean the choice was made to round toward
zero?

Yes, even before C was standardized. The original K&R (now
sometimes called "K&R I" to distinguish it from the later work)
says

When positive integers are divided truncation is toward
zero, but the form of truncation is machine-dependent if
either operand is negative. [...] It is always true
that (a/b)*b + a%b is equal to a (if b is not 0).

This particular choice was made for C in Ancient Times. One
supposes that it was inspired by the behavior of the machines
known to R, and that the leeway for negatives represented R's
caution about machines where C might someday be implemented.
The freedom was preserved in the original ANSI Standard, but
by the time C99 rolled around the Committee apparently decided
that "round toward minus infinity" machines were either non-
existent or so rare as to be negligible.

I believe there was also some pressure to converge
on a single definition that would conform to other
standard languages, regardless of whether those
machines were negligibly rare or not.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top