2

I am attempting to do exercise 2-1 of K&R C but when I run the program, the result is this:

        UNSIGNED TYPES
UNSIGNED CHAR:  0     255
UNSIGNED SHORT: 0     65535
UNSIGNED INT:   0     -1
UNSIGNED LONG;  0     -1

The result of UNSIGNED INT and UNSIGNED LONG weren't supposed to be -1, it was supposed to be the value in the reference. (Appendix B.11 Page 213)

/* UNSIGNED TYPES */
printf("\n\tUNSIGNED TYPES\n");
printf("UNSIGNED CHAR:  %d      %d\n", 0, UCHAR_MAX);
printf("UNSIGNED SHORT: %d      %d\n", 0, USHRT_MAX);
printf("UNSIGNED INT:   %d      %d\n", 0, UINT_MAX);
printf("UNSIGNED LONG:  %d      %d\n", 0, ULONG_MAX);

The strange part is that I don't think there's something wrong with my code, the minimum range is 0 because I read that unsigned types are non-negative. I already included limits.h and float.h.

How do I solve this problem?

The link of the full program is here.

UPDATE 1: I tried replacing %d of the max range for unsigned long and that seemed to work but the unsigned int is 4294967925 instead of 65535. Thanks for helping me fix the unsigned long problem and I hope you guys can help me with the unsigned int issue.

UPDATE 2: I changed the ULONG_MAX's character sequence from %ul to %lu.

Here's the code and the result:

Code:

/* UNSIGNED TYPES */
printf("\n\tUNSIGNED TYPES\n");
printf("UNSIGNED CHAR:  %d      %u\n", 0, UCHAR_MAX);
printf("UNSIGNED SHORT: %d      %u\n", 0, USHRT_MAX);
printf("UNSIGNED INT:   %d      %u\n", 0, UINT_MAX);
printf("UNSIGNED LONG:  %d      %lu\n", 0, ULONG_MAX);

Result:

        UNSIGNED TYPES
UNSIGNED CHAR:  0     255
UNSIGNED SHORT: 0     65535
UNSIGNED INT:   0     4294967925
UNSIGNED LONG;  0     4294967925
phuclv
  • 37,963
  • 15
  • 156
  • 475
  • 1
    `%ul` should be `%lu`, and you mis-transcribed `l` as `1` in the last line of the result – M.M May 26 '14 at 05:45
  • I did that already and it seemed to work much better than `%ul` but would you care to explain (if you know) why `%ul` adds one at the end of `ULONG_MAX`? and why `%lu` doesn't? – Alexander B. Falgui May 26 '14 at 05:50
  • `%ul` is `%u` followed by the letter `l`. – M.M May 26 '14 at 05:53

3 Answers3

3

%d is for signed integers, for unsigned int and long use %u and %lu respectively.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
Rohan
  • 52,392
  • 12
  • 90
  • 87
1

You need to use a format spec of %u to print an unsigned int.

By using %d, the bit pattern is interpreted as a signed int.

ooga
  • 15,423
  • 2
  • 20
  • 21
1

Did you copy exactly the output of the program? You write UNSIGNED LONG: in the code but then in the output it becomes UNSIGNED LONG;. There's no way unsigned long is one digit longer than unsigned int

Also, you're using the wrong type specifier and that results in undefined behavior. You must use %u for unsigned int, with l length modifier for long, ll for long long.

The era of 16-bit computing has long gone decades ago, so int's size is 32 bits on most modern systems except some 8 or 16-bit embedded systems, hence the range is [0, 232-1] or [0, 4294967295] as you see. Depends on systems you're using, long will have different sizes. Typically on Windows it's a 32-bit type and on Unix/Linux it's 64 bits. C standard requires int to be at least 16 bits, long to be at least 32 bits. Only long long are guaranteed to be at least 64 bits, so you need to check for it as well.

printf("UNSIGNED CHAR:       %u    %u\n",   0U, UCHAR_MAX);
printf("UNSIGNED SHORT:      %u    %u\n",   0U, USHORT_MAX);
printf("UNSIGNED INT:        %u    %u\n",   0U, UINT_MAX);
printf("UNSIGNED LONG:       %lu   %lu\n",  0UL, ULONG_MAX);
printf("UNSIGNED LONG LONG:  %llu  %llu\n", 0ULL, ULONGLONG_MAX);

If you're on Windows, both unsigned int and unsigned long's max should be 4294967295.

Note that using ALL CAPS is a very bad choice

phuclv
  • 37,963
  • 15
  • 156
  • 475