Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

INT_MAX

12 views
Skip to first unread message

Regis

unread,
Nov 16, 2001, 9:25:03 AM11/16/01
to

Hi,

INT_MAX and UINT_MAX have implementation-defined values
such that:
INT_MAX must be at least 2^15-1, and
UINT_MAX must be at least 2^16-1.

My questions are:

- Is UINT_MAX required to be of the form 2^N-1, for some N?
- If so, is UINT_MAX required to be of the form 2^(N-1)-1?

- If none of above holds,
is it possible or impossible to portably
compute INT_MAX (not UINT_MAX) at run-time
(i.e., without using <limits.h>)? If so:
- without using sizeof?
- without using bitwise operations?

Thanks.

--
Regis

Dan Pop

unread,
Nov 16, 2001, 10:41:19 AM11/16/01
to
Note to the pedants: in this article, ^ is used as the exponentiation
operator.

I have also taken the liberty to transparently correct an obvious typo
in the included text.

>INT_MAX and UINT_MAX have implementation-defined values
>such that:
>INT_MAX must be at least 2^15-1, and
>UINT_MAX must be at least 2^16-1.
>
>My questions are:
>
>- Is UINT_MAX required to be of the form 2^N-1, for some N?

Yes.

>- If so, is INT_MAX required to be of the form 2^(N-1)-1?

No. It is required to be of the form 2^M - 1, where M <= N.

>- If none of above holds,
>is it possible or impossible to portably
>compute INT_MAX (not UINT_MAX) at run-time
>(i.e., without using <limits.h>)? If so:
> - without using sizeof?
> - without using bitwise operations?

There is no (portable) way to compute INT_MAX. OTOH, UINT_MAX can be
trivially computed as -1u or (unsigned)-1.

Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch
Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland

Tim Prince

unread,
Nov 16, 2001, 10:48:39 AM11/16/01
to

"Regis" <re...@info.unicaen.fr> wrote in message
news:3BF521BF...@info.unicaen.fr...

>
> is it possible or impossible to portably
> compute INT_MAX (not UINT_MAX) at run-time
> (i.e., without using <limits.h>)? If so:
> - without using sizeof?
> - without using bitwise operations?
Programs such as enquire.c (in the gcc source distribution) do this quite
successfully, as far as examination of the hardware on which it is running
is concerned. You don't want to bury such an analysis in your application.
There's no way it can guess the properties of a cross-compilation target.


Regis

unread,
Nov 16, 2001, 11:09:29 AM11/16/01
to
Dan Pop wrote:
>
> Note to the pedants: in this article, ^ is used as the exponentiation
> operator.
>
> I have also taken the liberty to transparently correct an obvious typo
> in the included text.
>
> Regis <re...@info.unicaen.fr> writes:
>
> >INT_MAX and UINT_MAX have implementation-defined values
> >such that:
> >INT_MAX must be at least 2^15-1, and
> >UINT_MAX must be at least 2^16-1.
> >
> >My questions are:
> >
> >- Is UINT_MAX required to be of the form 2^N-1, for some N?
>
> Yes.
>
> >- If so, is INT_MAX required to be of the form 2^(N-1)-1?
>
> No. It is required to be of the form 2^M - 1, where M <= N.

Thanks.
I just found the relevant section 6.2.6.2 in the draft.
Are there existing implementations where M is not N-1 ?

--
Regis

Lawrence Kirby

unread,
Nov 16, 2001, 12:01:05 PM11/16/01
to
In article <3BF521BF...@info.unicaen.fr>
re...@info.unicaen.fr "Regis" writes:

>
>Hi,
>
>INT_MAX and UINT_MAX have implementation-defined values
>such that:
>INT_MAX must be at least 2^15-1, and
>UINT_MAX must be at least 2^16-1.
>
>My questions are:
>
>- Is UINT_MAX required to be of the form 2^N-1, for some N?

Yes, this is a consequence of the requirement that the representation
if an integer must be binary.

>- If so, is UINT_MAX required to be of the form 2^(N-1)-1?

I don't follow. If you mean INT_MAX then there is no requirement that
it be (UINT_MAX-1)/2 although in practice it typically is. INT_MAX
is allowed to have the same value as UINT_MAX or any smaller value
of the form 2^^N-1 where N is at least 15.

>- If none of above holds,

Well, part of the above holds.

>is it possible or impossible to portably
>compute INT_MAX (not UINT_MAX) at run-time
>(i.e., without using <limits.h>)? If so:
> - without using sizeof?

Yes.

> - without using bitwise operations?

In C90 something like this should work

unsigned value = -1;
int ivalue;

while ((ivalue = value) < 0 || ivalue != value)
value /= 2;

However in C99 the conversion of an out of range value to int can result
in a signal.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------

Peter Pichler

unread,
Nov 16, 2001, 6:06:01 PM11/16/01
to
"Dan Pop" <Dan...@cern.ch> wrote...

<snip notes to pedants>

> In <3BF521BF...@info.unicaen.fr> Regis <re...@info.unicaen.fr>
writes:
>
> >INT_MAX and UINT_MAX have implementation-defined values
> >such that:
> >INT_MAX must be at least 2^15-1, and
> >UINT_MAX must be at least 2^16-1.
> >
> >My questions are:
> >
> >- Is UINT_MAX required to be of the form 2^N-1, for some N?
>
> Yes.

I can understand that. Otherwise,
(unsigned)(-n) == (unsigned)(UINT_MAX + 1 - n)
wouldn't work. However,...

> >- If so, is INT_MAX required to be of the form 2^(N-1)-1?
>
> No. It is required to be of the form 2^M - 1, where M <= N.

...I am a bit uneasy with this restriction. There goes my plan
to build a DS9k2 with sizeof(int) == 3, INT_MAX == 99999.

I wanted to use it for financial operations: I'm only interested
in whole currency units (I don't want small potatoes), and 99,999
of them ought to be enough for everybody!

--
Peter Pichler, Abingdon, Oxfordshire, UK
My "From" address is valid; try pichloN+1 should pichloN bounce.


Dan Pop

unread,
Nov 16, 2001, 6:30:40 PM11/16/01
to

>>is it possible or impossible to portably
>>compute INT_MAX (not UINT_MAX) at run-time
>>(i.e., without using <limits.h>)? If so:
>> - without using sizeof?
>
>Yes.
>
>> - without using bitwise operations?
>
>In C90 something like this should work
>
> unsigned value = -1;
> int ivalue;
>
> while ((ivalue = value) < 0 || ivalue != value)
> value /= 2;

What part of C90 guarantees that this code works as intended?

AFAICT, the result of the assignment ivalue = value is implementation
defined and needs not be negative when "value" cannot be represented
in "ivalue". Or am I missing something?

Lawrence Kirby

unread,
Nov 16, 2001, 7:27:31 PM11/16/01
to
In article <9t47j0$1l6$1...@sunnews.cern.ch> Dan...@cern.ch "Dan Pop" writes:

>In <100593...@genesis.demon.co.uk> fr...@genesis.demon.co.uk (Lawrence
> Kirby) writes:
>
>>>is it possible or impossible to portably
>>>compute INT_MAX (not UINT_MAX) at run-time
>>>(i.e., without using <limits.h>)? If so:
>>> - without using sizeof?
>>
>>Yes.
>>
>>> - without using bitwise operations?
>>
>>In C90 something like this should work
>>
>> unsigned value = -1;
>> int ivalue;
>>
>> while ((ivalue = value) < 0 || ivalue != value)
>> value /= 2;
>
>What part of C90 guarantees that this code works as intended?

In C90 the result of an out-of-range conversion is implementation-defined.
This means that there has to be a valid result and since it has type int it
has to be in the range INT_MIN to INT_MAX. When that is less than
``value'' the while condition is true and the loop repeats. As soon as
value is reduced to INT_MAX the conversion to int leaves the value
unchagned and the loop terminates.

>AFAICT, the result of the assignment ivalue = value is implementation
>defined and needs not be negative when "value" cannot be represented
>in "ivalue". Or am I missing something?

The while test tests whether converting ``value'' to int changes its
value. A changed result could be either a negative or non-negative value.
The first comparison checks negative results and the 2nd checks
non-negative results.

Joe Wright

unread,
Nov 16, 2001, 11:53:08 PM11/16/01
to
All of one's and two's complement and signed magnitude implementations
will implement 'int_max' as 0111 1111 .... 1111. Without 'bitwise
operations' this value can be calculated at runtime with (unsigned)~0/2
since time began (K&R1 1978).
--
Joe Wright mailto:joeww...@earthlink.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

Lawrence Kirby

unread,
Nov 17, 2001, 9:38:14 AM11/17/01
to
In article <3BF5EE...@earthlink.net>
joeww...@earthlink.net "Joe Wright" writes:

...

>All of one's and two's complement and signed magnitude implementations
>will implement 'int_max' as 0111 1111 .... 1111. Without 'bitwise
>operations' this value can be calculated at runtime with (unsigned)~0/2
>since time began (K&R1 1978).

While this is typically true in practice the standard does not
guarantee it. Also (unsigned)~0 will not give the value of UINT_MAX on
anything other than 2's complement systems. Your expression can be
corrected to ~0U/2 or -1U/2 however.

Joe Wright

unread,
Nov 17, 2001, 11:32:16 AM11/17/01
to
Lawrence Kirby wrote:
>
> In article <3BF5EE...@earthlink.net>
> joeww...@earthlink.net "Joe Wright" writes:
>
> ...
>
> >All of one's and two's complement and signed magnitude implementations
> >will implement 'int_max' as 0111 1111 .... 1111. Without 'bitwise
> >operations' this value can be calculated at runtime with (unsigned)~0/2
> >since time began (K&R1 1978).
>
> While this is typically true in practice the standard does not
> guarantee it. Also (unsigned)~0 will not give the value of UINT_MAX on
> anything other than 2's complement systems. Your expression can be
> corrected to ~0U/2 or -1U/2 however.
>
I learned long ago not to argue with you. And I do like -1U/2. But
please explain how (unsigned)~0 will be other than all 1's. Is UINT_MAX
other than all 1's?

Joe Maun

unread,
Nov 17, 2001, 11:28:43 PM11/17/01
to
Joe Wright wrote:
>
> Lawrence Kirby wrote:
[...]

> > While this is typically true in practice the standard does not
> > guarantee it. Also (unsigned)~0 will not give the value of UINT_MAX on
> > anything other than 2's complement systems. Your expression can be
> > corrected to ~0U/2 or -1U/2 however.
> >
> I learned long ago not to argue with you. And I do like -1U/2. But
> please explain how (unsigned)~0 will be other than all 1's.

The conversion of an int with a negative value to unsigned does not
necessarily preserve the bit pattern. It's defined in terms of values,
not bit patterns. So the value -1 when converted to unsigned int will
always be UINT_MAX, -2 UINT_MAX-1 and so on. Think what *value* will ~0
have on anything other than two's complement systems?

--
Joe Maun
Montreal, QC
Canada

Regis

unread,
Nov 19, 2001, 4:08:05 AM11/19/01
to
Lawrence Kirby wrote:

> re...@info.unicaen.fr "Regis" writes:
>
> >INT_MAX and UINT_MAX have implementation-defined values
> >such that:
> >INT_MAX must be at least 2^15-1, and
> >UINT_MAX must be at least 2^16-1.
> >My questions are:
> >- Is UINT_MAX required to be of the form 2^N-1, for some N?
>
> Yes, this is a consequence of the requirement that the representation
> if an integer must be binary.

Yes, but a-priori, some of the highest values could have been reserved.

> >- If so, is UINT_MAX required to be of the form 2^(N-1)-1?
>
> I don't follow. If you mean INT_MAX then there is no requirement that
> it be (UINT_MAX-1)/2 although in practice it typically is. INT_MAX
> is allowed to have the same value as UINT_MAX or any smaller value
> of the form 2^^N-1 where N is at least 15.

Yes, I meant INT_MAX. It's a typo.

> In C90 something like this should work
>
> unsigned value = -1;
> int ivalue;
> while ((ivalue = value) < 0 || ivalue != value)
> value /= 2;
>
> However in C99 the conversion of an out of range value to int can result
> in a signal.

Ah. Interesting. The standards differ on this point.
I didn't even imagine that when I posted my question.

--
Regis

Lawrence Kirby

unread,
Nov 19, 2001, 7:26:30 AM11/19/01
to
In article <3BF8CBF5...@info.unicaen.fr>
re...@info.unicaen.fr "Regis" writes:

>Lawrence Kirby wrote:
>> re...@info.unicaen.fr "Regis" writes:
>>
>> >INT_MAX and UINT_MAX have implementation-defined values
>> >such that:
>> >INT_MAX must be at least 2^15-1, and
>> >UINT_MAX must be at least 2^16-1.
>> >My questions are:
>> >- Is UINT_MAX required to be of the form 2^N-1, for some N?
>>
>> Yes, this is a consequence of the requirement that the representation
>> if an integer must be binary.
>
>Yes, but a-priori, some of the highest values could have been reserved.

C requires a "pure" binary representation, not a binary representation
with parts missing. Reserved or "trap" representations can only occur as
a consequence of padding bits that don't contribute to the value, or
if the implementation chooses, for one bit pattern in a signed integer
representation. For 2's complement this bit pattern corresponds to what
would have been the largest negative value, for 1's complement and
sign-magnitude it corresponds to the bit pattern that would have been
for negative zero.

Dan Pop

unread,
Nov 19, 2001, 10:28:50 AM11/19/01
to

>In article <9t47j0$1l6$1...@sunnews.cern.ch> Dan...@cern.ch "Dan Pop" writes:
>
>>In <100593...@genesis.demon.co.uk> fr...@genesis.demon.co.uk (Lawrence
>> Kirby) writes:
>>
>>>>is it possible or impossible to portably
>>>>compute INT_MAX (not UINT_MAX) at run-time
>>>>(i.e., without using <limits.h>)? If so:
>>>> - without using sizeof?
>>>
>>>Yes.
>>>
>>>> - without using bitwise operations?
>>>
>>>In C90 something like this should work
>>>
>>> unsigned value = -1;
>>> int ivalue;
>>>
>>> while ((ivalue = value) < 0 || ivalue != value)
>>> value /= 2;
>>
>>What part of C90 guarantees that this code works as intended?
>
>In C90 the result of an out-of-range conversion is implementation-defined.
>This means that there has to be a valid result and since it has type int it
>has to be in the range INT_MIN to INT_MAX. When that is less than
>``value'' the while condition is true and the loop repeats. As soon as
>value is reduced to INT_MAX the conversion to int leaves the value
>unchagned and the loop terminates.

What happens if INT_MAX == UINT_MAX?

0 new messages