----- Original Message ----- 
From: "deepak none gopal" 
To: 
Sent: Monday, February 23, 2004 10:51 PM
Subject: [UTTARA] signed or unsigned.

> hello fellow Uttarites,
> 
> This is Deepak. I hav few doubts. 
> 
> 1)
> main() {
>         unsigned int i = -1;
>         
>         printf ("%d\n", i);
>       }
> 
> I expected this to print just 1 but it was -1 

Before we see why the output is not what you expect, let us first observe the 
following the point:

    [1]
    For a %d or %i specifier, the int argument is converted to 
    *signed decimal* in the style [-]dddd. The precision specifies 
    the minimum number of digits to appear; if the value being 
    converted can be represented in fewer digits, it is expanded 
    with leading zeros. The default precision is 1. 

In the above printf(), though, "i" is an unsigned int, it will be extracted as
an signed int from the variable argument list of the printf ().  The object
representation of "i" corresponds to -1.  See the below exaplaination.  

    (Object representation is simply the bit pattern that appears in 
    the memory of any object, say int or float or struct.)

>
> on the screen. But when u say %u instead of %d 
> i get only 1. Why is this?
> 

It is unlikely that you will get 1 as the output.  In my system (Win XP, GCC)
the value printed was 4294967295.  

    [2]
    When a value with integer type is converted to an unsigned type, 
    and if the value is outside the range of unsigned type, the value 
    is converted by repeatedly adding or subtracting *one more* than 
    the maximum value that can be represented in the new type until 
    the value is in the range of the new type.  

The following program conveys the fact:

     F:\Vijay\C> type unsigned.c
    
     #include 
     #include 
     #include 
    
     int
     main ( void ) 
     {
         unsigned int i = -1;

         printf ("%u\n", i);
         printf ("%u\n", (UINT_MAX+1) + i); 
         return EXIT_SUCCESS;
     }

     F:\Vijay\C> gcc unsigned.c -Wall -o un.exe
     F:\Vijay\C> un
     4294967295
     4294967295
 
> 2)
> main() {
>           unsigned int i ;
>         
>           for (i = -10; i <= -1; i++)
>               printf ("%d\n", i);
>       }
> 
> This goes into an infinte loop. 
>

My compiler (GCC, Win XP) defines UINT_MAX as:

 #define UINT_MAX  4294967295U 

-10 is not in the range of "i", so the rulee [2] (above) is applied.  The value
initialized to i is (UINT_MAX+1) + (-10).  The above loop is, thus, equivalent
to:

    for ( i = 4294967286; i <= 4294967295; i++ )
        ...

In the next nine iterations, the value of "i" will reach to UINT_MAX and then
goes outside the range of unsigned int.  The rule [2] is again applied to bring
the value back within the representable range, which happens to be less than
4294967295!  That's why the loop is infinite.
 

> And when unsigned int is changed to unsigned short 
> nothing is printed. 
> why?
> 

    F:\Vijay\C> type unsigned2.c

    #include 
    #include 
   
    int
    main ( void ) 
    {
        unsigned short i ;
            
        for ( i = -10; i <= -1; i++ )
            printf ("%u\n", i);
   
        return EXIT_SUCCESS;
    }

    F:\Vijay\C> gcc unsigned2.c -Wall 
    unsigned2.c: In function `main':
    unsigned2.c:10: warning: comparison is always false due to limited range of 
    data type

> 
> DEEPAK. 
> 

    Source: geocities.com/vijoeyz/faq/c

               ( geocities.com/vijoeyz/faq)                   ( geocities.com/vijoeyz)