Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signed vs Unsigned operations in C

Tags:

c

unsigned

Very simple question:

I have a program doing lots and lots of mathematical computations over ints and long longs. To fit in an extra bit, I made the long longs unsigned, since I only dealt with positive numbers, and could now get a few more values.

Oddly enough, this gave me a 15% performance boost, which I confirmed to be in simply making all the long long's unsigned.

Is this possible? Are mathematical operations really faster with unsigned numbers? I remember reading that there would be no difference, and the compiler automatically picks out the fastest way to go whether signed or unsigned. Is this 15% boost really from making the vars unsigned, or could it be something else affected in my code?

And, if it really is from making the vars unsigned, should I aim to make everything (even ints) unsigned, as I never need negative numbers, and every second is important if I can save it.

like image 394
Jeff Avatar asked Mar 05 '11 03:03

Jeff


People also ask

What is the difference between unsigned and signed in C?

A signed integer is a 32-bit datum that encodes an integer in the range [-2147483648 to 2147483647]. An unsigned integer is a 32-bit datum that encodes a nonnegative integer in the range [0 to 4294967295]. The signed integer is represented in twos complement notation.

What is the difference between signed and unsigned instructions?

Variables such as integers can be represent in two ways, i.e., signed and unsigned. Signed numbers use sign flag or can be distinguish between negative values and positive values. Whereas unsigned numbers stored only positive numbers but not negative numbers.

How do you know if its signed or unsigned?

An unsigned number contains just zero or positive values, whereas a signed number has both positive and negative numbers along with the value zero. The maximum value of signed numbers is half that of unsigned numbers.

What is unsigned operator in C?

An unsigned Integer means the variable can hold only a positive value. This format specifier is used within the printf() function for printing the unsigned integer variables. Syntax: printf(“%u”, variable_name);


2 Answers

In some operations, signed integers are faster, in others, unsigned are faster:

  • In C, signed integer operations can be assumed not to wrap. The compiler will take advantage of this in loop optimization, for example. Comparisons can be optimized away similarly. (This can also lead to subtle bugs if you don't expect this).

  • On the other hand, unsigned integers do not have this assumption. However, not having to deal with a sign is a big advantage for some operations, for example: division. Unsigned division by a constant power of two is a simple shift, but (depending on your rounding rules) there's a conditional off-by-1 for negative numbers.

Personally, I make a habit of only using unsigned integers unless I really, really do have a value which needs to be signed. It's not so much for performance as correctness.

You may see the effect magnified with long long, which (I'm guessing) is 64 bits in your case. The CPU usually doesn't have single instructions do deal with these types (in 32 bit mode), so the slight added complexity for signed operations will be more noticeable.

like image 191
John Ripley Avatar answered Oct 04 '22 22:10

John Ripley


On a 32-bit processor, 64-bit integer operations are emulated; using unsigned instead of signed means the emulation library doesn't have to do extra work to propagate carry bits etc.

like image 23
geekosaur Avatar answered Oct 04 '22 20:10

geekosaur