473,802 Members | 2,015 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Direct computation of integer limits in K&R2?

Hello all,

In K&R2 one exercise asks the reader to compute and print the limits for
the basic integer types. This is trivial for unsigned types. But is it
possible for signed types without invoking undefined behaviour
triggered by overflow? Remember that the constants in limits.h cannot
be used.

Mar 11 '08
88 3805
On Mar 14, 5:59*am, Martin <m...@b.cwrot e:
Displaying the limits using the macros is easy: the C89 Standard mandates *
that the macros in <limits.hmust have the same type as an expression *
that is an object of the corresponding type converted according to the *
integral promotions (this excludes CHAR_BIT and MB_LEN_MAX). So this is *
perfectly reasonable:

* * printf("char signed min = %d\n", SCHAR_MIN);
* * printf("signed int min *= %d\n", INT_MIN);
* * printf("signed int max *= %d\n", INT_MAX);
* * /* etc. */

For calculating them, Tondo & Gimpel suggest this in "The C Answer Book":

* * printf("signed char min * *= %d\n", ~(char)((unsign ed char) ~0 >1));
* * printf("signed char max * *= %d\n", *(char)((unsign ed char) ~0 >1));
* * printf("unsigne d short min = %d\n", ~(short)((unsig ned short) ~0>1));
* * printf("unsigne d short max = %d\n", *(short)((unsig ned short) ~0 >1));

and so on.

Obviously, I don't know to what peer review T&G's Answer Book was subject,*
but if their solutions are not correct, I would like to know.
It works for two's complement. Maybe that's just the trick:
You have to write a different solution for each possible number
format.
Mar 14 '08 #71
user923005 wrote:
On Mar 14, 5:59*am, Martin <m...@b.cwrot e:
>Displaying the limits using the macros is easy: the C89 Standard
mandates that the macros in <limits.hmust have the same type as an
expression that is an object of the corresponding type converted
according to the integral promotions (this excludes CHAR_BIT and
MB_LEN_MAX). So this is perfectly reasonable:

printf("char signed min = %d\n", SCHAR_MIN);
printf("sign ed int min *= %d\n", INT_MIN);
printf("sign ed int max *= %d\n", INT_MAX);
/* etc. */

For calculating them, Tondo & Gimpel suggest this in "The C Answer
Book":

printf("sign ed char min * *= %d\n", ~(char)((unsign ed char) ~0 >>
1)); printf("signed char max * *= %d\n", *(char)((unsign ed char) ~0
>1)); printf("unsigne d short min = %d\n", ~(short)((unsig ned short)
~0 >1)); printf("unsigne d short max = %d\n", *(short)((unsig ned
short) ~0 >1));

and so on.

Obviously, I don't know to what peer review T&G's Answer Book was
subject, but if their solutions are not correct, I would like to
know.

It works for two's complement. Maybe that's just the trick:
You have to write a different solution for each possible number
format.
The question doesn't mention the word "portable" at all anywhere, so I
guess that a machine specific answer will count as a solution too.

Mar 14 '08 #72
On Mar 14, 1:43 pm, Ioannis Vranos <ivra...@nospam .no.spamfreemai l.gr>
wrote:
Micah Cowan wrote:
Ioannis Vranos <ivra...@nospam .no.spamfreemai l.grwrites:
ymunt...@gmail. com wrote:
What did you do in this code? Did you compute INT_MAX and
INT_MIN using INT_MAX and INT_MIN? Note that (unsigned)-1 / 2
may be out of range of int (by the way, C99 rationale says
that the committee was told that there actually was an
implementati on where UINT_MAX + 1 was *four* times INT_MAX + 1).
How can this happen given that sizeof(int)== sizeof(unsigned it)?
Not all the bits in int are required to be value or sign bits (some
may be padding bits). And some of the bits that are value bits in an
unsigned int are allowed to be padding bits in the signed int.

OK it is allowed, but is there any existing system where the value
ranges of signed int and unsigned int are different?
See above. You decide whether C rationale is lying or C committee
was lied to. I have no idea :)

Yevgen
Mar 14 '08 #73
On Mar 14, 1:58 pm, santosh <santosh....@gm ail.comwrote:
user923005 wrote:
On Mar 14, 5:59 am, Martin <m...@b.cwrot e:
Displaying the limits using the macros is easy: the C89 Standard
mandates that the macros in <limits.hmust have the same type as an
expression that is an object of the corresponding type converted
according to the integral promotions (this excludes CHAR_BIT and
MB_LEN_MAX). So this is perfectly reasonable:
printf("char signed min = %d\n", SCHAR_MIN);
printf("signed int min = %d\n", INT_MIN);
printf("signed int max = %d\n", INT_MAX);
/* etc. */
For calculating them, Tondo & Gimpel suggest this in "The C Answer
Book":
printf("signed char min = %d\n", ~(char)((unsign ed char) ~0 >>
1)); printf("signed char max = %d\n", (char)((unsigne d char) ~0
1)); printf("unsigne d short min = %d\n", ~(short)((unsig ned short)
~0 >1)); printf("unsigne d short max = %d\n", (short)((unsign ed
short) ~0 >1));
and so on.
Obviously, I don't know to what peer review T&G's Answer Book was
subject, but if their solutions are not correct, I would like to
know.
It works for two's complement. Maybe that's just the trick:
You have to write a different solution for each possible number
format.

The question doesn't mention the word "portable" at all anywhere, so I
guess that a machine specific answer will count as a solution too.
But then the following is a solution too:

int intmax = 2147483647;
int intmin = -2147483647 - 1;

Or, for "quite portable" version, look at glibc's limits.h.
And of course SCHAR_MAX = 127 :)

Yevgen
Mar 14 '08 #74
Ioannis Vranos wrote:
>
.... snip ...
>
OK it is allowed, but is there any existing system where the value
ranges of signed int and unsigned int are different?
Yes. Consider a 16 bit system. INT_MAX is 32767. INT_MIN is
-32768 (or -32767). UINT_MAX is 65536 (UINT_MIN is naturally 0).
It is allowable to reserve the value that would represent -32768 to
indicate a special condition, such as uninitialized. Or, for a 1's
complement machine, the bit pattern for -0 is forbidden.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Mar 14 '08 #75
Harald van D?k wrote:
CBFalconer wrote:
>Harald van D?k wrote:
.... snip ...
>>
>>#include <stdio.h>
int main(void) {
unsigned u = -1;
int i;
while ((i = u) < 0 || i != u)
u = u >1;
printf("INT_MAX == %u\n", u);
}

This is not guaranteed to work in C99, where the conversion of
an out-of- range integer may raise a signal, but it's valid C90,
since the result of the conversion must be a valid int, and
therefore between INT_MIN and INT_MAX.

This CAN'T work everywhere.

Yes, it can.
>The u = -1 statement is legal, and results in UINT_MAX value.
However the first i = u statement always overruns the INT_MAX
value for i, unless the system has INT_MAX defined to be equal
to UINT_MAX. Very rare. So the result of that statement is
implementati on defined.

Of course. And any of the permissible implementation-defined
values of i will result in the intended behaviour.
I think you have a misinterpretati on of 'implementaion-defined'.
This means that the action, on a particular implementation, is
defined. However that may well be "*** ABORT in line nnn, integer
overflow ***".

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Mar 14 '08 #76
On Fri, 14 Mar 2008 14:08:48 -0500, CBFalconer wrote:
Harald van D?k wrote:
>CBFalconer wrote:
>>Harald van D?k wrote:
... snip ...
>>>
#include <stdio.h>
int main(void) {
unsigned u = -1;
int i;
while ((i = u) < 0 || i != u)
u = u >1;
printf("INT_MAX == %u\n", u);
}

This is not guaranteed to work in C99, where the conversion of an
out-of- range integer may raise a signal, but it's valid C90, since
the result of the conversion must be a valid int, and therefore
between INT_MIN and INT_MAX.

This CAN'T work everywhere.

Yes, it can.
>>The u = -1 statement is legal, and results in UINT_MAX value. However
the first i = u statement always overruns the INT_MAX value for i,
unless the system has INT_MAX defined to be equal to UINT_MAX. Very
rare. So the result of that statement is implementation defined.

Of course. And any of the permissible implementation-defined values of
i will result in the intended behaviour.

I think you have a misinterpretati on of 'implementaion-defined'. This
means that the action, on a particular implementation, is defined.
However that may well be "*** ABORT in line nnn, integer overflow ***".
If the result is implementation-defined, any result is permissible, but
there must be a result. If the behaviour is implementation-defined, any
behaviour (including, as you mention, exiting the program) is
permissible. In this case, the result is implementation-defined, and
exiting the program is not allowed.
Mar 14 '08 #77
user923005 <dc*****@connx. comwrites:
On Mar 14, 5:59Â*am, Martin <m...@b.cwrot e:
<snip>
> printf("unsigne d short max = %d\n", (short)((unsign ed short) ~0 >1));

and so on.

Obviously, I don't know to what peer review T&G's Answer Book was subject, Â*
but if their solutions are not correct, I would like to know.

It works for two's complement.
Are you sure? What happens when both signed and unsigned short (or
indeed, int in the "and so on" case) have the same number of value
bits? I think this is permitted and causes the wrong answer to be
printed, but my brain is already hurting from thinking about this
exercise.
Maybe that's just the trick:
You have to write a different solution for each possible number
format.
I hoped I could find a portable solution that way, but I drew a blank.

--
Ben.
Mar 15 '08 #78
On Mar 14, 5:18*pm, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
user923005 <dcor...@connx. comwrites:
On Mar 14, 5:59*am, Martin <m...@b.cwrot e:
<snip>
* *printf("unsign ed short max = %d\n", (short)((unsign ed short) ~0 >1));
and so on.
Obviously, I don't know to what peer review T&G's Answer Book was subject, *
but if their solutions are not correct, I would like to know.
It works for two's complement.

Are you sure? *What happens when both signed and unsigned short (or
indeed, int in the "and so on" case) have the same number of value
bits? *I think this is permitted and causes the wrong answer to be
printed, but my brain is already hurting from thinking about this
exercise.
*Maybe that's just the trick:
You have to write a different solution for each possible number
format.

I hoped I could find a portable solution that way, but I drew a blank.
You're right.
I think that every solution I have seen posted so far (including mine)
only works on a very limited subset of possible integer limit sets.
That makes this a very interesting exercise. And we have not even
touched the floating point yet.
Mar 15 '08 #79
On Mar 12, 5:37 am, santosh <santosh....@gm ail.comwrote:
Hello all,

In K&R2 one exercise asks the reader to compute and print the limits for
the basic integer types. This is trivial for unsigned types. But is it
possible for signed types without invoking undefined behaviour
triggered by overflow? Remember that the constants in limits.h cannot
be used.
Hi santosh

Maybe you could take this book for reference:
the c answer book 2Edtion by Clovis L. Tondo & Scott E. Gimpel

And,there is a way about signed char on that book
printf("signed char min = %d\n", -(char)((unsigne d char) ~0 >1));

but i think it should be that
printf("signed char min = %d\n", -1 -(char)((unsigne d char) ~0 >1));
maybe it's a little mistake of press :)

There aren't solutions about floats, i think the other book
Computer Systems A Programmer's Perspective by Randal E. Bryant &
David O'Hallaron
of CMU could help.

Good luck!
yalong
Mar 15 '08 #80

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.