Sign in to follow this  
fpsgamer

When to use Signed and Unsigned types....

Recommended Posts

fpsgamer    856
I have a question about when it would be best to use unsigned vs signed types. (1) For instance if have a function where I expect the parameter to always be positive it seems like a good idea to use an unsigned type. Is this a good practice? (2) But I am unclear how the compiler enforces this. I did a small experiement in visual studio just now... code:
signed in a = 5;
unsgined int b = -11;
signed int c = a  b;



The debugger output:
NAME... VALUE.......TYPE
c	-6	    int   (the number -6 is flagged in red)
b	4294967285  unsigned int
a	5	    int



I violated the unsigned type for "b", but somehow I get the correct answer? What is going on?

Share this post


Link to post
Share on other sites
Driv3MeFar    1080
Quote:

I violated the unsigned type for "b", but somehow I get the correct answer? What is going on?


When you store a negative value in a unsigned variable, the negative "wraps around" and becomes a large positive number (-1 = 2^32 - 1 in the case of unsigned 32-bit integers). This is because negative numbers are stored using the twos compliment method. Basically, the binary representation of a negative number looks like a very large positive number because the most significant bit is always set. Since the binary representation of unsigned 4294967285 and signed -11 are the same, you get the (un?)expected result from your addition.

Share this post


Link to post
Share on other sites
fpsgamer    856
Quote:
Original post by Driv3MeFar
Quote:

I violated the unsigned type for "b", but somehow I get the correct answer? What is going on?


When you store a negative value in a unsigned variable, the negative "wraps around" and becomes a large positive number (-1 = 2^32 - 1 in the case of unsigned 32-bit integers). This is because negative numbers are stored using the twos compliment method. Basically, the binary representation of a negative number looks like a very large positive number because the most significant bit is always set. Since the binary representation of unsigned 4294967285 and signed -11 are the same, you get the (un?)expected result from your addition.


Oh that explains it. But what about using unsigned types as parameters when unsigned values are expected. It doesnt seem like there is any enforcement so if the caller inputs a negative number, I will be faced with a very large positive number instead. It now seems better to just use a signed value and check for "var < 0"

Which would be better?

Share this post


Link to post
Share on other sites
torakka    193
No, you should and could not check if the value is < 0, because the type of the value is *unsigned* -- it is *always* >= 0, checking for this would be redundant.

It would be much more pragmatic to check for < 0 BEFORE you assign signed to unsigned and trap depending on the rules you are trying to enforce.

Share this post


Link to post
Share on other sites
Driv3MeFar    1080
Quote:
Original post by fpsgamer
But what about using unsigned types as parameters when unsigned values are expected. It doesnt seem like there is any enforcement so if the caller inputs a negative number, I will be faced with a very large positive number instead. It now seems better to just use a signed value and check for "var < 0"

Which would be better?


It depends on the situation. If it is a case in which you should never really get a negative number, I would use unsigned values, and only used signed ones where negatives can/should appear.

Consider a function where you are passed in an array index. Since your indices should only be positive, I would use an unsigned value here. Presumably, in this function you would want to verify the index provided:

assert(index < arraySize);

Now, consider if you were to be passed in a -1 for your index. As an unsigned, with a 32-bit integer size, that -1 would be interpreted as 4294967295. I think its pretty safe to assume that such a value would cause your assertion to fail.

Share this post


Link to post
Share on other sites
Conner McCloud    1135
Quote:
Original post by fpsgamer
Oh that explains it. But what about using unsigned types as parameters when unsigned values are expected. It doesnt seem like there is any enforcement so if the caller inputs a negative number, I will be faced with a very large positive number instead. It now seems better to just use a signed value and check for "var < 0"

Which would be better?

The enforcement comes in the form of a warning...unless you have disabled it, the compiler should emit a warning about passing a signed value into an unsigned variable. If you use a signed value and check for negative values manually, then the compiler can't provide any hints and you have to rely on a runtime check catching the negative values for you. Whenever possible, you should always prefer to let the compiler tell you when you've messed up.

CM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
I don't personally use signed/unsigned qualifiers in function parameters, but that may be just me. I usually only declare something unsigned if I know that logically it can never be negative (or if I want to store a larger positive number, but that never usually happens for me). If a function should only act on positive input then I generally just test the input and deal with it accordingly.

Share this post


Link to post
Share on other sites
Ebola0001    138
this one i know... ;)

the integers signed or unsigned are just a collection of 32 bits.

if it is unsigned the number can be 0 - 4294967296, or 32-bit resolution

if it is signed the number can be -2147483649 - 2147483648 or 31-bit resolution wiht 1 bit (#32) as the sign bit

when math is done it just rolls over the top or under the bottom. the same thing would happen if you were using signed bits and did

signed int x = -2147483649;
signed int y = 20;
signed int z;

z = x-y;


then z should equal 2147483628







Share this post


Link to post
Share on other sites
JohnBolton    1372
I use unsigned only when the allowed range of the variable does not fit in a signed variable or when using the value as a bit field.

The reason for using unsigned with a bit field is that the result of a right-shift is defined by the standard (unlike the result of a right-shifted signed value).

There is no benefit to making a variable unsigned because it is expected to hold only non-negative numbers. In fact, it is a bad idea because it gives you a false sense of security. In addition, the conversion between signed and unsigned is different for each size of variable: (char)-1 == (int)-1, but (unsigned char)-1 != (unsigned int)-1. Also, it is annoying because it frequently requires you to do a lot of otherwise unnecessary casting.

[Edited by - JohnBolton on August 20, 2006 8:46:33 AM]

Share this post


Link to post
Share on other sites
JohnBolton    1372
Quote:
Original post by Conner McCloud
The enforcement comes in the form of a warning...unless you have disabled it, the compiler should emit a warning about passing a signed value into an unsigned variable.

VC 2005 does not warn about unsigned/signed assignment or comparison. I believe GCC does, but I don't remember the details.

Share this post


Link to post
Share on other sites
workingclass77    156
slightly off-topic, but does ms's code even compile without warnings at level 4? i could swear last time i tried anything above warning level 3, the platform sdk headers gave me pages full of warnings.

Share this post


Link to post
Share on other sites
Deventer    263
In my experience it does compile without warnings at warning level 4.
However, there is actually a higher warning level -Wall, which you can specify as a command line argument, last time I tried that, I got pages and pages of warnings. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this