The Wisdom of 6.5.5(6)

I

Ian Pilcher

As I was setting out from base camp to climb the "itoa mountain", full
of trepidation about crossing the "INT_MIN chasm", my wise old Sherpa
told me meditate on the meaning of section 6.5.5(6) of the C99 standard:

When integers are divided, the result of the / operator is the
algebraic quotient with any fractional part discarded.(87) If the
quotient a/b is representable, the expression (a/b)*b + a%b shall
equal a.

(87) This is often called "truncation toward zero".

To my shallow occidental eye, this seems to provide a solid definition
of both the / and % operators (division and modulisation?) for negative
integers, eliminating the traditional need to convert the integer being
formatted to its absolute value.

Question #1: Am I right about this?

Question #2: In what circumstances can "the quotient a/b" not be
representable? I can think of two:

* division by zero

* negative zero - only possible if a or b is negative
zero

Actually, I'm not sure that the second really qualifies as
not representable.

So, as usual, the real question is did I miss something?

Thanks!
 
K

Keith Thompson

Ian Pilcher said:
Question #2: In what circumstances can "the quotient a/b" not be
representable? I can think of two:

* division by zero

* negative zero - only possible if a or b is negative
zero

If b is negative zero, it's a division by zero. If a is negative zero
(and b is not), it's unspecified whether the result is negative zero
or plain zero; see C99 6.2.6.2.
Actually, I'm not sure that the second really qualifies as
not representable.

There's another case: overflow. For division, this can only happen
for a case like INT_MIN/(-1), and only if INT_MIN < -INT_MAX (i.e.,
for a two's-complement representation, which doesn't have a negative
zero).
 
I

Ian Pilcher

Keith said:
If b is negative zero, it's a division by zero. If a is negative zero
(and b is not), it's unspecified whether the result is negative zero
or plain zero; see C99 6.2.6.2.




There's another case: overflow. For division, this can only happen
for a case like INT_MIN/(-1), and only if INT_MIN < -INT_MAX (i.e.,
for a two's-complement representation, which doesn't have a negative
zero).

Sounds like I'm good as long as I'm dividing by a positive number.

Thanks!
 
T

Tim Rentsch

Peter Nilsson said:

Here's some code that I believe handles all values, works with both
C89 and C99 division rules, and is not sensitive to the relative
ranges of positive int's and negative int's.

Exercise for the obsessively-concerned-with-efficiency: modify this
function to use CPP functionality so that the expressions '(r>0)'
and/or '(r<0)' are optimized away on platforms where they are compile
time constants. (I believe the '(r<0)' expression in the 'else'
branch is always zero, but I included it for symmetry.)

void
portable_itoa( int n, char * s ){
char *p = s;
int r, t = n;

if( n < 0 ){
const char *digits = "9876543210987654321" + 9;
do *p++ = digits[ r = t%10 ]; while( t = t/10 + (r>0) );
*p++ = '-';
} else {
const char *digits = "1234567890123456789" + 9;
do *p++ = digits[ r = t%10 ]; while( t = t/10 - (r<0) );
}
*p = 0;

while( s < --p ) t = *s, *s++ = *p, *p = t;
}
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top