By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,406 Members | 954 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,406 IT Pros & Developers. It's quick & easy.

char confusion

P: n/a
I'm trying to find out the ranges of different data types through
direct computation........this is what I did.......

Code:

#include <stdio.h>
main()
{
char ch;
signed short sh;
signed int in;
signed long lo;
unsigned short ush;
unsigned int uin;
unsigned long ulo;
ch = sh = in = lo = ush = uin = ulo = 0;

printf("Ranges through computation:\n\n");

/* while (ch < (ch+1))
ch++;
printf("The range of a char is from %d to %d\n", ch+1, ch);
*/
while (sh < (sh+1))
sh++;
printf("The range of a short is from %d to %d\n", sh+1, sh);

while (in < (in+1))
in++;
printf("The range of an int is from %d to %d\n", in+1, in);

while (lo < (lo+1))
++lo;
printf("The range of a long is from %ld to %ld\n", lo+1, lo);

while (ush < (ush+1))
++ush;
printf("The range of an unsigned short is from %u to %u\n", ush+1,
ush);

while (uin < (uin+1))
++uin;
printf("The range of an unsigned int is from %u to %u\n", uin+1, uin);

while (ulo < (ulo+1))
++ulo;
printf("The range of an unsigned long is from %lu to %lu\n", ulo+1,
ulo);

return 0;
}

The ranges of all data types in the program print correctly, except for
the char type (the corresponding code is commented out) in which the
loop continues for ever ........why is it so?

Thanks.

Jun 21 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a

poodles wrote:
I'm trying to find out the ranges of different data types through
direct computation........this is what I did.......

Code:

#include <stdio.h>
main()
{
char ch;
signed short sh;
signed int in;
signed long lo;
unsigned short ush;
unsigned int uin;
unsigned long ulo;
ch = sh = in = lo = ush = uin = ulo = 0;

printf("Ranges through computation:\n\n");

/* while (ch < (ch+1))
ch++;
printf("The range of a char is from %d to %d\n", ch+1, ch);
*/
<snip>
return 0;
}

The ranges of all data types in the program print correctly, except for
the char type (the corresponding code is commented out) in which the
loop continues for ever ........why is it so?


Most likely because your `char` is of `unsigned` variety, so `ch+1`
wraps around to 0, instead of the smallest negative value.

Anyway, there's <limits.h> which can tell you all of the above without
breaking a sweat.

Jun 21 '06 #2

P: n/a
poodles wrote:
I'm trying to find out the ranges of different data types through
direct computation........this is what I did.......

[..skip some code...]

/* while (ch < (ch+1))
ch++;
printf("The range of a char is from %d to %d\n", ch+1, ch);
*/
while (sh < (sh+1))
sh++;
printf("The range of a short is from %d to %d\n", sh+1, sh);

[... skip some code ...]
The ranges of all data types in the program print correctly, except for
the char type (the corresponding code is commented out) in which the
loop continues for ever ........why is it so?

Thanks.


On my computer, a sun solaris workstation, compiled with gcc 3.1, it
does endless-loops for all types except long and int types.
The problem you face has nothing to do with char, but how (xx+1) is
treated by your compiler. If xx is a char variable (8bit), but int
on your computer is 16 bit wide then (c+1) has the width of an int.
The same applies for short types on 32 bit machines.

I recommend changing the prog into something like this and it may
function:

while (ch < (char)(ch+1))
ch++;

while (sh < (signed short)(sh+1))
sh++;

or like this (without type casts)

char c1, c2;
for ( c1=0, c2=1; c1 < c2; c1 = c2++ );

Dont forget type casting your (xx+1) in all printf calls.

Best regards,
Bart
Jun 21 '06 #3

P: n/a

Vladimir Oka wrote:
poodles wrote:
I'm trying to find out the ranges of different data types through
direct computation........this is what I did.......

Code:

#include <stdio.h>
main()
{
char ch;
signed short sh;
signed int in;
signed long lo;
unsigned short ush;
unsigned int uin;
unsigned long ulo;
ch = sh = in = lo = ush = uin = ulo = 0;

printf("Ranges through computation:\n\n");

/* while (ch < (ch+1))
ch++;
printf("The range of a char is from %d to %d\n", ch+1, ch);
*/
<snip>
return 0;
}

The ranges of all data types in the program print correctly, except for
the char type (the corresponding code is commented out) in which the
loop continues for ever ........why is it so?


Most likely because your `char` is of `unsigned` variety, so `ch+1`
wraps around to 0, instead of the smallest negative value.


Strike the above monstrosity! I left the brain on the train...
(See other replies in the thread instead.)
Anyway, there's <limits.h> which can tell you all of the above without
breaking a sweat.


This is still good advice. Relying on overflow behaviour to determine
the ranges of integers is a bad idea in any case.

Jun 21 '06 #4

P: n/a
poodles wrote:

I'm trying to find out the ranges of different data types through
direct computation........this is what I did.......

Code:

#include <stdio.h>
main()
{
char ch; [...] /* while (ch < (ch+1))
ch++;
printf("The range of a char is from %d to %d\n", ch+1, ch);
*/ [...] The ranges of all data types in the program print correctly, except for
the char type (the corresponding code is commented out) in which the
loop continues for ever ........why is it so?


Someone will jump in to correct me if I'm wrong, but I believe it has
to do with type promotions. When you do "ch+1", the result is going
to be protmoted to int (or unsigned int).

So, if you have 8-bit signed chars, then when ch==127, the compare
will be (127 < 128), which is true. But, ch++ results in ch holding
the value -128.

And, if you have 8-bit unsigned chars, then a similar situation
occurs when ch==255. In that case, (255 < 256) is true, but ch++
gives you ch==0.

(Well, actually, I believe that both of the above situations cause
ch++ to be undefined. However, your implementation probably
behaves as I've described.)

Try:

while ( ch < (char)(ch+1) )
ch++;
Now, can someone explain why the same code is working for "short"?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Jun 21 '06 #5

P: n/a
Kenneth Brody wrote:
poodles wrote:

I'm trying to find out the ranges of different data types through
direct computation........this is what I did.......

Code:

#include <stdio.h>
main()
{
char ch; [...]
/* while (ch < (ch+1))
ch++;
printf("The range of a char is from %d to %d\n", ch+1, ch);
*/

[...]
The ranges of all data types in the program print correctly, except for
the char type (the corresponding code is commented out) in which the
loop continues for ever ........why is it so?


Someone will jump in to correct me if I'm wrong, but I believe it has
to do with type promotions. When you do "ch+1", the result is going
to be protmoted to int (or unsigned int).

So, if you have 8-bit signed chars, then when ch==127, the compare
will be (127 < 128), which is true. But, ch++ results in ch holding
the value -128.

And, if you have 8-bit unsigned chars, then a similar situation
occurs when ch==255. In that case, (255 < 256) is true, but ch++
gives you ch==0.

(Well, actually, I believe that both of the above situations cause
ch++ to be undefined. However, your implementation probably
behaves as I've described.)


Assuming char promotes to int, ch++ means "ch = (char) ((int) ch + 1)".
Behaviour after overflow in signed arithmetic (which can happen only if
CHAR_MAX == INT_MAX, so never if CHAR_MAX == 127) is undefined, but
overflow in signed conversions results either in an
implementation-defined value, or an implementation-defined signal
(which can but doesn't have to have UB).

And for unsigned char, behaviour is defined (this time assuming
UCHAR_MAX != INT_MAX) as you expected the implementation would behave.
Try:

while ( ch < (char)(ch+1) )
ch++;
Now, can someone explain why the same code is working for "short"?


Possibly because on that particular system, SHRT_MAX == INT_MAX.

Jun 21 '06 #6

P: n/a
Thanks a lot Bart Rider, Kenneth Brody and Harald van Dijk; that's the
solution I was looking for. Perhaps it is a "bad idea", but I was
trying to solve Exercise 2-1, page 36 in K&R's book.:

"Write a program to determine the ranges of char , short , int , and
long variables, both signed and unsigned , by printing appropriate
values from standard headers and by direct computation. Harder if you
compute them: determine the ranges of the various floating-point
types."

Please let me know a better idea to solve the above problem..........
Also I can't think of a way to *compute* the ranges of floating point
types....I'd be grateful if someone can help.....

Thanks

Jun 21 '06 #7

P: n/a
poodles wrote:

Thanks a lot Bart Rider, Kenneth Brody and Harald van Dijk; that's the
solution I was looking for. Perhaps it is a "bad idea", but I was
trying to solve Exercise 2-1, page 36 in K&R's book.:

"Write a program to determine the ranges of char , short , int , and
long variables, both signed and unsigned , by printing appropriate
values from standard headers and by direct computation. Harder if you
compute them: determine the ranges of the various floating-point
types."

Please let me know a better idea to solve the above problem..........
Well, if you're not strictly concerned about portability, the odds
are that something like this will work on your platform:

unsigned whatever u = (unsigned whatever)-1L;
signed whatever s = (signed whatever)(u >> 1);

where "whatever" is char/short/int/long.

Again, note my qualifier "the odds are", since the above is bound to
cause problems on some platforms.

And note that this only gives the high end of the range. I suppose
that, once again, "the odds are" that incrementing each of the
variables will wrap to the low end.

A quick test on my platform shows this technique "works" on this
particular hardware/software combination.

char: -128/127 0/255
short: -32768/32767 0/65535
int: -2147483648/2147483647 0/4294967295
long: -2147483648/2147483647 0/4294967295
Also I can't think of a way to *compute* the ranges of floating point
types....I'd be grateful if someone can help.....


I don't think that's computable. (Note that the K&R assignment
doesn't ask about those.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Jun 21 '06 #8

P: n/a
Thanks for the reply, Kenneth Brody

Jun 23 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.