# When to use Signed and Unsigned types....

This topic is 4134 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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 on other sites
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 on other sites
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 on other sites
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 on other sites
Quote:
 Original post by fpsgamerBut 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 on other sites
Quote:
 Original post by fpsgamerOh 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 on other sites
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 on other sites
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 on other sites
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 on other sites
Quote:
 Original post by Conner McCloudThe 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 on other sites
VC++ 2005 EE sure warns me about signed/unsigned mismatches. I've got warnings at level 4 (highest).

##### Share on other sites
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 on other sites
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 on other sites

This topic is 4134 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628686
• Total Posts
2984234

• 14
• 13
• 13
• 10
• 10