signed and unsigned Sign bit doubt

H

hari

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
 
E

Eric Sosman

hari said:
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).

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.
 
K

Keith Thompson

hari said:
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).
 
E

Eric Sosman

Eric said:
hari said:
[...]
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.
 
C

CBFalconer

hari said:
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.
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top