UINT_MAX == INT_MAX possible?

K

Keith Thompson

Chris Torek said:
Indeed, because signed arithmetic is loosely defined, one should
be able to get away with a lot of perversity (e.g., on the DS9k).



This implementation is not conforming. For instance:

unsigned int u = UINT_MAX; /* ie 0x7fffffff */
u += 3; /* must put 2 in u */

Hence, if you make the above change to a typical 32-bit machine,
you must also make changes so that unsigned arithmetic masks out
the top bit.

Quite right, thanks.

Removing the wording about trap representations doesn't help; you
still need, for example, printf("%u\n", UINT_MAX + 3) to print 2,
which means the implementation really has to do some extra work,
either to zero the padding bit or to ignore it.

I think you can still play some tricks by defining padding bits for
*signed* int, though. For example, if you change INT_MAX from 2**31-1
to 2**30-1, and document that signed int has a padding bit, and that
setting that bit creates a trap representation, I think you can still
have a conforming implementation. (A trap representation, of course,
isn't required to cause a trap; it just invokes undefined behavior --
which signed overflow does anyway.)

If Chris doesn't shoot this one down, I'll begin to suspect that I'm
right.
 
P

pete

Yevgen Muntyan wrote:
Sure, I was rather wondering about "That's the tricky part when
implementing itoa." - are there portable implementations of it
where INT_MIN is a tricky part. As I said, I guess that C
implementations do not implement it in a portable way. Maybe
some usual programmers did implement portable atoi, just for fun.

To me, itoa is just exercize 3-4
from the latest edition of the K&R book,
(or 3-3 in the original K&R book).
In that context, itoa should be implemented portably.

void i_to_a(int n, char *s)
{
int tenth, min_offset;
char *p, swap;

min_offset = -INT_MAX > n;
if (0 > n) {
n += min_offset;
n = -n;
*s++ = '-';
}
p = s;
tenth = n;
do {
tenth /= 10;
*p++ = (char)(n - 10 * tenth + '0');
n = tenth;
} while (tenth != 0);
*s = (char)(*s + min_offset);
*p-- = '\0';
while (p > s) {
swap = *s;
*s++ = *p;
*p-- = swap;
}
}
 
P

Peter Nilsson

pete said:
...
To me, itoa is just exercize 3-4
from the latest edition of the K&R book,
(or 3-3 in the original K&R book).
In that context, itoa should be implemented portably.

void i_to_a(int n, char *s)
{
int tenth, min_offset;
char *p, swap;

min_offset = -INT_MAX > n;

Personally, I prefer (n < -INT_MAX), because it makes
better 'left to right' sense to put numbers in ascending
order. [Of course, some people are confused by -5 < -4.]
if (0 > n) {
n += min_offset;
n = -n;
*s++ = '-';
}
p = s;

Not sure why you have 'tenth' in the following...
tenth = n;
do {
tenth /= 10;
*p++ = (char)(n - 10 * tenth + '0');
n = tenth;
} while (tenth != 0);

do { *p++ = '0' + (n % 10); } while (n /= 10);

Are you just trying to avoid 2 'division' instructions?
*s = (char)(*s + min_offset);
*p-- = '\0';
while (p > s) {
swap = *s;
*s++ = *p;
*p-- = swap;
}

}

Can't say I like the redundant (char) casts either. Looks like
you've been using Jacob's compiler on high redundant warning
mode. ;)
 
P

pete

Peter said:
pete said:
...
To me, itoa is just exercize 3-4
from the latest edition of the K&R book,
(or 3-3 in the original K&R book).
In that context, itoa should be implemented portably.

void i_to_a(int n, char *s)
{
int tenth, min_offset;
char *p, swap;

min_offset = -INT_MAX > n;

Personally, I prefer (n < -INT_MAX), because it makes
better 'left to right' sense to put numbers in ascending
order. [Of course, some people are confused by -5 < -4.]

The "less than" operator
dropped out of my repertoire a few years ago
for a few very weak reasons.
Not sure why you have 'tenth' in the following...


do { *p++ = '0' + (n % 10); } while (n /= 10);

Are you just trying to avoid 2 'division' instructions?

Yes.
Can't say I like the redundant (char) casts either. Looks like
you've been using Jacob's compiler on high redundant warning
mode. ;)

Not Jacob's,
but you are correct in that I am kowtowing
to my compiler at high warning level.
 
P

pete

Not sure why you have 'tenth' in the following...


do { *p++ = '0' + (n % 10); } while (n /= 10);

Are you just trying to avoid 2 'division' instructions?

Yes and but I also may have been influenced
by a previously written version of itoa which had more use
for the "tenth" variable.

void (itoa)(int n, char *s);
static char *sput_u(unsigned n, char *s);
static char *sput_up1(unsigned n, char *s);

void (itoa)(int n, char *s)
{
if (0 > n) {
*s++ = '-';
*sput_up1(-(n + 1), s) = '\0';
} else {
*sput_u(n, s) = '\0';
}
}

static char *sput_u(unsigned n, char *s)
{
unsigned digit, tenth;

tenth = n / 10;
digit = n - 10 * tenth;
if (tenth != 0) {
s = sput_u(tenth, s);
}
*s = (char)(digit + '0');
return s + 1;
}

static char *sput_up1(unsigned n, char *s)
{
unsigned digit, tenth;

tenth = n / 10;
digit = n - 10 * tenth;
if (digit == 9) {
if (tenth != 0) {
s = sput_up1(tenth, s);
} else {
*s++ = '1';
}
*s = '0';
} else {
if (tenth != 0) {
s = sput_u(tenth, s);
}
*s = (char)(digit + '1');
}
return s + 1;
}
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,142
Messages
2,570,819
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top