signed and unsigned Sign bit doubt

Discussion in 'C Programming' started by hari, Dec 22, 2008.

  1. hari

    hari Guest

    Hi all,
    Sorry to ask the same type of question again,My understanding is

    1. whenever a unsigned number(short) is assigned to a signed number
    (inetger type),its sign bit is not extended. (i.e when assigning FROM
    UNSIGNED SMALLER DATA TYPE TO OTHER DATA TYPE WHIC HAS HIGHER SIZE).

    But when I asssign a unsigned integer with neagtive value to signed or
    unsigned number,sign bit is extended.

    Is this is right, pleasegive me brief explanation if Im wrong? Sorry..

    #include<stdio.h>
    int main()
    {
    unsigned int y =255;
    unsigned short my=-255;
    int gm;

    int imy =-255;

    unsigned int uy = imy;

    gm = my;

    printf("\ny-> %x,\nmy-> %x,\n imy->%x,\n uy->%x,\n gm->
    %x",y,my,imy,uy,gm);
    return 0;
    }

    My output

    y-> ff,
    my-> ffffff01,
    imy->ffffff01
    uy->0xffffff01
    gm->ffffff01
     
    hari, Dec 22, 2008
    #1
    1. Advertising

  2. hari

    Eric Sosman Guest

    hari wrote:
    > Hi all,
    > Sorry to ask the same type of question again,My understanding is
    >
    > 1. whenever a unsigned number(short) is assigned to a signed number
    > (inetger type),its sign bit is not extended. (i.e when assigning FROM
    > UNSIGNED SMALLER DATA TYPE TO OTHER DATA TYPE WHIC HAS HIGHER SIZE).


    The conversion preserves the value. Since the unsigned
    value is non-negative, the converted signed value is also
    non-negative.

    Also, there is no question about "extending the sign bit"
    of an unsigned integer, because an unsigned integer has no
    sign bit at all.

    > But when I asssign a unsigned integer with neagtive value to signed or
    > unsigned number,sign bit is extended.


    I'm not sure what you mean. No unsigned integer can ever
    have a negative value, and no unsigned integer has a sign bit.

    > Is this is right, pleasegive me brief explanation if Im wrong? Sorry..
    >
    > #include<stdio.h>
    > int main()
    > {
    > unsigned int y =255;


    A conversion occurs in this initialization. The initializer
    is an int with the value 255, and the thing being initialized is
    an unsigned int. The int 255 is converted to unsigned int, giving
    the value 255u, and that is the initial value of `y'.

    > unsigned short my=-255;


    A conversion occurs in this initialization. The initializer
    is an int with the value -255, and the thing being initialized
    is an unsigned short. The int -255 is converted to unsigned short,
    but since the unsigned short cannot have a negative value this
    conversion must produce some other value. By the rules of signed-
    to-unsigned conversion, the new value is (short)(USHRT_MAX+1-255),
    which on many machines will be (short)(65535+1-255) or (short)65281,
    which can also be written as (short)0xFF01. (Larger values for
    USHRT_MAX are possible, but seldom seen.)

    > int gm;
    >
    > int imy =-255;


    No conversion occurs: Both the initializer and the variable
    being initialized are int.

    > unsigned int uy = imy;


    A conversion occurs in this initialization. The initializer
    is an int with the value -255, and the thing being initialized is
    an unsigned int. Since an unsigned int cannot have a negative
    value, conversion alters the value, as above. This time the rules
    produce UINT_MAX+1-255, typically 4294967295+1-255 or 4294967041u,
    which can also be written as 0xFFFFFF01 (on some systems UINT_MAX
    may be 65535, and you'll get 65281u==0xFF01; still other values are
    possible but rare).

    > gm = my;


    This is just a little bit problematic. On many machines the
    range of int is wider than that of unsigned short, and all will
    be well: gm will be assigned the value USHRT_MAX+1-255, which
    is likely to be 65281. But on some machines int and short will
    have the same number of bits, and USHRT_MAX > INT_MAX. On these,
    it will turn out that the value in my is outside the range that
    the int gm can express, and you'll get an implementation-defined
    outcome (which might include raising a signal). Usually, the
    implementation-defined outcome is to deliver a "wrapped around"
    result, but this isn't absolutely guaranteed.

    > printf("\ny-> %x,\nmy-> %x,\n imy->%x,\n uy->%x,\n gm->
    > %x",y,my,imy,uy,gm);


    Additional conversions occur here, and there's also some
    undefined behavior (whose consequences are probably not serious,
    but in principle anything can happen).

    printf() is a "variadic" function, one that can accept
    different argument lists in different calls. The first argument
    is always the format string, but the remaining arguments can
    be pretty much anything. These extra arguments are subject to
    the "default argument promotions," so the argument values you
    supply are sometimes converted to different types by the time
    printf() actually receives them.

    Your five extra arguments are of three types: y and uy
    are unsigned int, imy and gm are (signed) int, and my is
    an unsigned short. Arguments that are int or unsigned int
    are not affected by the promotions, but the unsigned short
    argument may be. If an int can hold all possible values of
    an unsigned short, the unsigned short is converted to an
    int; this is the commonest outcome. But on machines with
    "narrow" ints, where USHRT_MAX > INT_MAX, the conversion is
    to unsigned int instead. Either way the value is preserved,
    but the type that printf() receives will in no case be an
    unsigned short. The arguments received by printf() will be
    two or three unsigned ints, and three or two signed ints.

    The (probably harmless) undefined behavior arises from
    using the "%x" conversion specifier, which requires a matching
    argument of type unsigned int. As we've seen above, either
    two or three of the arguments are signed int, not unsigned int,
    so this is an error. What usually happens is that printf()
    displays the value the argument would have had if its bits
    were interpreted as an unsigned int, but this behavior is not
    actually guaranteed and in principle anything could happen.

    > return 0;
    > }
    >
    > My output
    >
    > y-> ff,
    > my-> ffffff01,
    > imy->ffffff01
    > uy->0xffffff01
    > gm->ffffff01



    --
    Eric Sosman
    lid
     
    Eric Sosman, Dec 22, 2008
    #2
    1. Advertising

  3. hari <> writes:
    > Sorry to ask the same type of question again,My understanding is
    >
    > 1. whenever a unsigned number(short) is assigned to a signed number
    > (inetger type),its sign bit is not extended. (i.e when assigning FROM
    > UNSIGNED SMALLER DATA TYPE TO OTHER DATA TYPE WHIC HAS HIGHER SIZE).
    >
    > But when I asssign a unsigned integer with neagtive value to signed or
    > unsigned number,sign bit is extended.
    >
    > Is this is right, pleasegive me brief explanation if Im wrong? Sorry..

    [...]

    Sign bit extension is something that happens on the hardware level.
    The C language defines things differently.

    When you assign a value of one type to an object of another type, the
    value must be converted before it can be stored. If both types are
    numeric, this conversion is done implicitly (no cast is required).
    The language defines the rules for these conversions, not in terms of
    bits, but in terms of values. (Initialization works like assignment;
    I'll use initialization in my examples for the sake of brevity.)

    In the following, I'll assume 16-bit int and 32-bit long, with no
    padding bits, so:
    INT_MAX == 32767 (2**15-1)
    UINT_MAX == 65535 (2**16-1)
    LONG_MAX == 2147483647 (2**31-1)
    ULONG_MAX == 4294967295 (2**32-1)

    If you convert a value to a signed type:
    If the value can be represented in the target type, the conversion
    yields the same value.
    Example:
    unsigned int u = 30000;
    int i = u; /* i == 30000 */
    If the value can't be represented in the target type, the
    conversion yields an implementation-defined value (or raises
    an implementation-defined signal, but this is rare).
    Example:
    unsigned int u = 40000;
    int i = u; /* i has a value determined by the implementation */
    In many implementations, the value of i will be -25536. This is
    the result of blindly copying the bits of the unsigned object into
    the signed object, assuming a 2's-complement representation for
    signed int. The language allows this behavior, but doesn't
    require it.

    Note that the rules for operations other than conversion that yield
    signed values are different. A conversion that yields a signed value
    outside the range of the type gives an implementation-defined result
    (or raises a signal); an arithmetic operation, such as addition, that
    yields such a value invokes undefined behavior (it can crash your
    program).

    If you convert a value to an unsigned type:
    If the value can be represented in the target type, the conversion
    yields the same value.
    Example:
    int i = 30000;
    unsigned int u = i; /* u == 30000 */
    If the value can't be represented in the target type, the result
    is reduced modulo UINT_MAX+1 for unsigned int, modulo ULONG_MAX+1
    for unsigned long, and so sorth. The effect is the same as
    repeatedly adding or subtracting 2**N until the result is within
    the representtable range.
    Example:
    long int l = 300000;
    unsigned int u = l; /* u == 37856 */
    (In effect, the high-order bits are ignored, but as I said, the
    standard defines the conversion in terms of values, not bits.)

    The rules are designed to allow a straightforward 2's-complement
    implementation that silently ignores overflow to work properly, while
    allowing enough flexibility for other implementations.

    You'll notice that the treatment of overflow is very different for
    signed and unsigned types, and for signed types it's very different
    for conversions and for other operations. This can be inconvenient at
    times, but it's a fairly reasonable compromise (the language is full
    of such compromises).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Dec 22, 2008
    #3
  4. hari

    Eric Sosman Guest

    Eric Sosman wrote:
    > hari wrote:
    >> [...]
    >> unsigned short my=-255;

    >
    > A conversion occurs in this initialization. The initializer
    > is an int with the value -255, and the thing being initialized
    > is an unsigned short. The int -255 is converted to unsigned short,
    > but since the unsigned short cannot have a negative value this
    > conversion must produce some other value. By the rules of signed-
    > to-unsigned conversion, the new value is (short)(USHRT_MAX+1-255),


    Er, um, make that (unsigned short)(USHRT_MAX+1-255), and
    similarly elsewhere. Sorry for the slip-up.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Dec 22, 2008
    #4
  5. hari

    CBFalconer Guest

    hari wrote:
    >
    > Sorry to ask the same type of question again, My understanding is
    >
    > 1. whenever a unsigned number(short) is assigned to a signed number
    > (inetger type),its sign bit is not extended. (i.e when assigning FROM
    > UNSIGNED SMALLER DATA TYPE TO OTHER DATA TYPE WHIC HAS HIGHER SIZE).


    No, an unsigned object has no sign bit. If the bit that would be a
    sign in a corresponding signed object is set, the behaviour is
    undefined or implementation defined.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Dec 23, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fore
    Replies:
    29
    Views:
    15,299
    Rashad
    Sep 21, 2008
  2. Replies:
    3
    Views:
    427
    James Kanze
    Nov 19, 2008
  3. hari
    Replies:
    4
    Views:
    351
    James Kuyper
    Dec 23, 2008
  4. pozz
    Replies:
    12
    Views:
    749
    Tim Rentsch
    Mar 20, 2011
  5. Steffen Koepf

    Converted signed 16 Bit to unsigned?

    Steffen Koepf, Dec 14, 2011, in forum: VHDL
    Replies:
    1
    Views:
    1,476
    Gabor
    Dec 14, 2011
Loading...

Share This Page