Printing the range s of unsigned char and unsigned int.

J

Junmin H.

Hello, I am trying to print the range of unsigned char and unsigned int.
The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks

#include <stdio.h>

main(){
unsigned char c, temp;
c = temp = 0;
printf("the range of unsigned char is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned char is from 0 to 255





#include <stdio.h>

main(){
unsigned int c, temp;
c = temp = 0;
printf("the range of unsigned int is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned int is from 0 to -1
 
K

Keith Thompson

Junmin H. said:
Hello, I am trying to print the range of unsigned char and unsigned int.
The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks [snip]
#include <stdio.h>

main(){
unsigned int c, temp;
c = temp = 0;
printf("the range of unsigned int is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned int is from 0 to -1

The "%d" format is for signed int. Use "%u".

Incidentally, you should use 'int main(void)' rather than 'main()'.

And if your goal is merely to print the range of unsigned int, you can
use UINT_MAX, defined in <limits.h>.
 
M

Martin Ambuhl

Junmin said:
Hello, I am trying to print the range of unsigned char and unsigned int.
The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks

Because you incorrectly used "%d", the specifier for a signed int, to
print an unsigned int. As it happens, on your implementation the bit
pattern for UINT_MAX is interpreted as the bit pattern for the signed
int -1. For examples of using the correct specifier, see below:

#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("[output]\n"
"the range of unsigned char is from 0 to %u\n"
"the range of unsigned int is from 0 to %u\n", UCHAR_MAX,
UINT_MAX);
return 0;
}

[output]
the range of unsigned char is from 0 to 255
the range of unsigned int is from 0 to 4294967295
 
C

CBFalconer

Junmin H. said:
Hello, I am trying to print the range of unsigned char and unsigned
int. The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks
.... snip char version ...

#include <stdio.h>

main(){
unsigned int c, temp;
c = temp = 0;
printf("the range of unsigned int is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned int is from 0 to -1

You have failed to correctly type the printf argument. The
following works fine here, and is a just barely modified version of
your code to use a short and avoid an interminable delay. It
outputs 65535. Note that the maximum value of an unsigned int is
not normally expressible as an int, and attempting to do so
involves undefined behaviour.

#include <stdio.h>

int main(void) {
unsigned short c, temp;

c = temp = 0;
printf("the range of unsigned int is from %d to ", (int)c);
while (c >= temp) {
temp = c;
++c;
}
printf("%d\n", (int)temp);
return 0;
}
 
R

Richard Heathfield

CBFalconer said:
You have failed to correctly type the printf argument. The
following works fine here, and is a just barely modified version of
your code to use a short and avoid an interminable delay.

A type change and a cast, Chuck? Hardly "barely modified", when you
compare it to the minimum change, which is to change a couple of %d to
%u.
 
C

CBFalconer

Richard said:
CBFalconer said:

A type change and a cast, Chuck? Hardly "barely modified", when
you compare it to the minimum change, which is to change a couple
of %d to %u.

But that wouldn't avoid the ~65536 times longer run times for
checking, which is why I switched to short.
 
R

Richard Heathfield

CBFalconer said:
But that wouldn't avoid the ~65536 times longer run times for
checking, which is why I switched to short.

Oops, missed that. Sorry. Still, %hu would have been an improvement over
a cast.

Here's another optimisation, btw:

#include <limits.h>
#include <stdio.h>

int main(void)
{
unsigned int min = 0;
unsigned int max = UINT_MAX;
printf("The range of unsigned int is from %u to %u\n",
min, max);
return 0;
}

This is, of course, O(1).
 
J

Junmin H.

Junmin said:
Hello, I am trying to print the range of unsigned char and unsigned int.
The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks

#include <stdio.h>

main(){
unsigned char c, temp;
c = temp = 0;
printf("the range of unsigned char is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned char is from 0 to 255





#include <stdio.h>

main(){
unsigned int c, temp;
c = temp = 0;
printf("the range of unsigned int is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned int is from 0 to -1

Thank you very much all you guys!
 
C

Charlie Gordon

Junmin H. said:
Hello, I am trying to print the range of unsigned char and unsigned int.
The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks

#include <stdio.h>

main(){
unsigned char c, temp;
c = temp = 0;
printf("the range of unsigned char is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned char is from 0 to 255

A much simpler version, that works in C99 and before :

replace the while loop with

temp = c - 1;

and you are done.
#include <stdio.h>

main(){
unsigned int c, temp;
c = temp = 0;
printf("the range of unsigned int is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned int is from 0 to -1

temp = c - 1; works here too, and is much more efficient, O(1) obviously ;-)

it actually works for any unsigned type.
 
J

Junmin H.

A much simpler version, that works in C99 and before :

replace the while loop with

temp = c - 1;

and you are done.


temp = c - 1; works here too, and is much more efficient, O(1) obviously ;-)

it actually works for any unsigned type.

I'm sorry. I don't understand your point.
 
P

pete

Junmin said:
Hello, I am trying to print the range of unsigned char and unsigned int.
The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks

#include <stdio.h>

main(){
unsigned char c, temp;
c = temp = 0;
printf("the range of unsigned char is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned char is from 0 to 255

In "the default argument promotions",
unsigned char promotes to int
if int can cover the range of unsigned char;
which it can, on most hosted implementations.
#include <stdio.h>

main(){
unsigned int c, temp;
c = temp = 0;
printf("the range of unsigned int is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;
}

OUTPUT: the range of unsigned int is from 0 to -1

#include <stdio.h>

int main(void)
{
printf("The range of unsigned int is from 0 to %u.\n",
(unsigned)-1);
return 0;
}
 
U

user923005

Hello, I am trying to print the range of unsigned char and unsigned int.
The one for char is working good, gives me a correct output,
however the other one for int doesnt, why?? Thanks

#include <stdio.h>

main(){
unsigned char c, temp;
c = temp = 0;
printf("the range of unsigned char is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;

}

OUTPUT: the range of unsigned char is from 0 to 255

#include <stdio.h>

main(){
unsigned int c, temp;
c = temp = 0;
printf("the range of unsigned int is from %d to ", c);
while(c >= temp){
temp = c;
++c;
}
printf("%d\n", temp);
return 0;

}

OUTPUT: the range of unsigned int is from 0 to -1

#include <stdio.h>
#include <limits.h>
#include <float.h>
int main(void)
{
printf("CHAR_MIN %d\n", (int) CHAR_MIN);
printf("CHAR_MAX %u\n", (unsigned) CHAR_MAX);
printf("DBL_DIG %u\n", (unsigned) DBL_DIG);
printf("DBL_EPSILON %*.*g\n", DBL_DIG + 3, DBL_DIG,
DBL_EPSILON);
printf("DBL_MANT_DIG %u\n", (unsigned) DBL_MANT_DIG);
printf("DBL_MAX %*.*g\n", DBL_DIG + 3, DBL_DIG, DBL_MAX);
printf("DBL_MAX_10_EXP %u\n", (unsigned) DBL_MAX_10_EXP);
printf("DBL_MAX_EXP %u\n", (unsigned) DBL_MAX_EXP);
printf("DBL_MIN %*.*g\n", DBL_DIG + 3, DBL_DIG, DBL_MIN);
printf("DBL_MIN_10_EXP %d\n", DBL_MIN_10_EXP);
printf("DBL_MIN_EXP %d\n", DBL_MIN_EXP);
#ifdef DBL_RADIX
printf("DBL_RADIX %u\n", (unsigned) DBL_RADIX);
#endif
#ifdef DBL_ROUNDS
printf("DBL_ROUNDS %u\n", (unsigned) DBL_ROUNDS);
#endif
printf("FLT_DIG %u\n", (unsigned) FLT_DIG);
printf("FLT_EPSILON %*.*g\n", FLT_DIG + 3, FLT_DIG,
FLT_EPSILON);
#ifdef FLT_GUARD
printf("FLT_GUARD %u\n", (unsigned) FLT_GUARD);
#endif
printf("FLT_MANT_DIG %u\n", (unsigned) FLT_MANT_DIG);
printf("FLT_MAX %*.*g\n", FLT_DIG + 3, FLT_DIG, FLT_MAX);
printf("FLT_MAX_10_EXP %u\n", (unsigned) FLT_MAX_10_EXP);
printf("FLT_MAX_EXP %u\n", (unsigned) FLT_MAX_EXP);
printf("FLT_MIN %*.*g\n", FLT_DIG + 3, FLT_DIG, FLT_MIN);
printf("FLT_MIN_10_EXP %d\n", FLT_MIN_10_EXP);
printf("FLT_MIN_EXP %d\n", FLT_MIN_EXP);
printf("INT_MAX %d\n", INT_MAX);
printf("INT_MIN %d\n", INT_MIN);
printf("LDBL_DIG %u\n", (unsigned) LDBL_DIG);
printf("LDBL_EPSILON %*.*Lg\n", LDBL_DIG + 3, LDBL_DIG, (long
double) LDBL_EPSILON);
printf("LDBL_MANT_DIG %u\n", (unsigned) LDBL_MANT_DIG);
printf("LDBL_MAX %*.*Lg\n", LDBL_DIG + 3, LDBL_DIG, (long
double) LDBL_MAX);
printf("LDBL_MAX_10_EXP %u\n", (unsigned) LDBL_MAX_10_EXP);
printf("LDBL_MAX_EXP %u\n", (unsigned) LDBL_MAX_EXP);
printf("LDBL_MIN %*.*Lg\n", LDBL_DIG + 3, LDBL_DIG, (long
double) LDBL_MIN);
printf("LDBL_MIN_10_EXP %d\n", LDBL_MIN_10_EXP);
printf("LDBL_MIN_EXP %d\n", LDBL_MIN_EXP);
#ifdef LDBL_RADIX
printf("LDBL_RADIX %u\n", (unsigned) LDBL_RADIX);
#endif
#ifdef LDBL_ROUNDS
printf("LDBL_ROUNDS %u\n", (unsigned) LDBL_ROUNDS);
#endif
#ifdef LLONG_MAX
printf("LLONG_MAX %lld\n", LLONG_MAX);
#endif
#ifdef LLONG_MIN
printf("LLONG_MIN %lld\n", LLONG_MIN);
#endif
printf("LONG_MAX %ld\n", LONG_MAX);
printf("LONG_MIN %ld\n", LONG_MIN);
printf("MB_LEN_MAX %u\n", (unsigned) MB_LEN_MAX);
printf("SCHAR_MAX %u\n", (unsigned) SCHAR_MAX);
printf("SCHAR_MIN %d\n", (int) SCHAR_MIN);
printf("SHRT_MAX %hd\n", SHRT_MAX);
printf("SHRT_MIN %hd\n", SHRT_MIN);
printf("UCHAR_MAX %u\n", (unsigned) UCHAR_MAX);
printf("UINT_MAX %u\n", (unsigned) UINT_MAX);
#ifdef ULLONG_MAX
printf("ULLONG_MAX %llu\n", (unsigned long long)
ULLONG_MAX);
#endif
printf("ULONG_MAX %lu\n", (unsigned long) ULONG_MAX);
printf("USHRT_MAX %u\n", (unsigned) USHRT_MAX);
printf("CHAR_BIT %u\n", (unsigned) CHAR_BIT);

return 0;
}
 
B

Ben Bacarisse

Richard Heathfield said:
CBFalconer said:


Oops, missed that. Sorry. Still, %hu would have been an improvement over
a cast.

Here's another optimisation, btw:

#include <limits.h>
#include <stdio.h>

int main(void)
{
unsigned int min = 0;
unsigned int max = UINT_MAX;
printf("The range of unsigned int is from %u to %u\n",
min, max);
return 0;
}

This is, of course, O(1).

As was the original.
 
R

Richard Heathfield

Ben Bacarisse said:
As was the original.

No, the original was O(CHAR_BIT * sizeof(unsigned int)). Whilst CHAR_BIT
and sizeof(unsigned int) are constants *for a given platform*, they are
not the same on all platforms. If you call that O(1), all O(n)
algorithms are O(1) once you've decided how much data you've got.
 
B

Ben Bacarisse

Richard Heathfield said:
Ben Bacarisse said:


No, the original was O(CHAR_BIT * sizeof(unsigned int)). Whilst CHAR_BIT
and sizeof(unsigned int) are constants *for a given platform*, they are
not the same on all platforms. If you call that O(1), all O(n)
algorithms are O(1) once you've decided how much data you've got.

I knew you were going to say that!

You are, if you want, perfectly allowed to think of the program as
somehow parametrized by the types but then I can't see how you can
claim that your program is O(1) (think what will have to happen in
printf and the strings that must be printed).

Oh, you will say you mean O(1) in the umber of printf calls. Well if
so, I meant O(1) in the number of main calls and so it goes on.
 
R

Richard Heathfield

Ben Bacarisse said:
I knew you were going to say that!

Curses! You have defeated my secret weapon of surprise.
You are, if you want, perfectly allowed to think of the program as
somehow parametrized by the types but then I can't see how you can
claim that your program is O(1) (think what will have to happen in
printf and the strings that must be printed).

Yes, you're right - my claim must be modified too. The original was
O(CHAR_BIT * sizeof(unsigned int)), and mine is O(log(CHAR_BIT *
sizeof(unsigned int)), not O(1) as hitherto claimed. But I'd have got
away with it if it hadn't been for those meddling kids...
 
C

Charlie Gordon

Junmin H. said:
I'm sorry. I don't understand your point.

No loop is needed, the following code is portable to all platforms.

#include <stdio.h>
int main(void){
printf("the range of unsigned char is from 0 to %u\n",
(unsigned char)-1);
printf("the range of unsigned short is from 0 to %u\n",
(unsigned short)-1);
printf("the range of unsigned int is from 0 to %u\n",
(unsigned int)-1);
return 0;
}
 
E

Eric Sosman

Charlie Gordon wrote On 09/19/07 09:07,:
No loop is needed, the following code is portable to all platforms.

#include <stdio.h>
int main(void){
printf("the range of unsigned char is from 0 to %u\n",
(unsigned char)-1);
printf("the range of unsigned short is from 0 to %u\n",
(unsigned short)-1);
printf("the range of unsigned int is from 0 to %u\n",
(unsigned int)-1);
return 0;
}

"I ran it on my DeathStation 9000 and demons flew
out of my nose."

Suggested fix:

#include <stdio.h>
int main(void){
printf("the range of unsigned char is from 0 to %u\n",
(unsigned int)(unsigned char)-1);
printf("the range of unsigned short is from 0 to %u\n",
(unsigned int)(unsigned short)-1);
printf("the range of unsigned int is from 0 to %u\n",
(unsigned int)-1);
return 0;
}

References:

7.19.6.1p8: "[...] o,u,x,X The unsigned int argument is
converted [...]"

7.19.6.1p9: "[...] If any argument is not the correct
type for the corresponding conversion specification, the
behavior is undefined."

6.3.1.1p3: "[...] If an int can represent all values of
the original type, the value is converted to an int; [...]"
 

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

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top