Question

#include<stdio.h>
int main()
{
unsigned short a=-1;
printf("%d",a);
return 0;
}
  1. This is giving me output 65535. why?
  2. When I increased the value of a in negative side the output is (2^16-1=)65535-a.
  3. I know the range of unsigned short int is 0 to 65535. But why is rotating in the range 0 to 65535.What is going inside?

    #include<stdio.h>
    int main()
    {
    unsigned int a=-1;
    printf("%d",a);
    return 0;
    }
    
  4. Output is -1.
  5. %d is used for signed decimal integer than why here it is not following the rule of printing the largest value of its(int) range.
  6. Why the output in this part is -1?
  7. I know %u is used for printing unsigned decimal integer.

    Why the behavioral is undefined in second code and not in first.?

    This I have compiled in gcc compiler. It's a C code On my machine sizeof short int is 2 bytes and size of int is 4 bytes.

Was it helpful?

Solution

In your implementation, short is 16 bits and int is 32 bits.

unsigned short a=-1;
printf("%d",a);

First, -1 is converted to unsigned short. This results in the value 65535. For the precise definition see the standard "integer conversions". To summarize: the value is taken modulo USHORT_MAX+1.

This value 65535 is assigned to a.

Then for the printf, which uses varargs, the value is promoted back to int. varargs never pass integer types smaller than int, they're always converted to int. This results in the value 65535, which is printed.

unsigned int a=-1;
printf("%d",a);

First line, same as before but modulo UINT_MAX+1. a is 4294967295.

For the printf, a is passed as an unsigned int. Since %d requires an int the behavior is undefined by the C standard. But your implementation appears to have reinterpreted the unsigned value 4294967295, which has all bits set, as as a signed integer with all-bits-set, i.e. the two's-complement value -1. This behavior is common but not guaranteed.

OTHER TIPS

Variable assignment is done to the amount of memory of the type of the variable (e.g., short is 2 bytes, int is 4 bytes, in 32 bit hardware, typically). Sign of the variable is not important in the assignment. What matters here is how you are going to access it. When you assign to a 'short' (signed/unsigned) you assign the value to a '2 bytes' memory. Now if you are going to use '%d' in printf, printf will consider it 'integer' (4 bytes in your hardware) and the two MSBs will be 0 and hence you got [0|0](two MSBs) [-1] (two LSBs). Due to the new MSBs (introduced by %d in printf, migration) your sign bit is hidden in the LSBs and hence printf considers it unsigned (due to the MSBs being 0) and you see the positive value. To get a negative in this you need to use '%hd' in first case. In the second case you assigned to '4 bytes' memory and the MSB got its SIGN bit '1' (means negative) during assignment and hence you see the negative number in '%d' of printf. Hope it explains. For more clarification please comment on the answer.

NB: I used 'MSB' for a shorthand of higher-order byte(s). Please read it according to the context (e.g., 'SIGN bit' will make you read like 'Most Significant Bit'). Thanks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top