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
I have also taken the liberty to transparently correct an obvious typo
in the included text.
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.
>- 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
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
>
>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
-----------------------------------------
<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.
>>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?
>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.
...
>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.
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
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 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.
>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?