Wednesday, 22 February 2012

Why The abs Function in C++ Returns A Negative Value

I played around with the abs function in Visual C++ 2010 from the <cstdlib> header file, and in one instance, the function returned a negative value.

Note the parameter for the abs in <cstdlib> is integer and it returns the absolute value.

Here’s the code:

#include <cstdlib>
...
int iVal = -2147483648;
iVal = abs(iVal);

After the call to the abs function, iVal held -2147483648. It was as if nothing had happened. Why? What happened? It has to do with the range for the int data type.

The range of a 32-bit integer is -2,147,483,648 to 2,147,483,647. As you can see, the positive value of the largest negative value is outside the range.

The abs function did work. Here’s a brief explanation of how it worked and why the result is what it is.

A signed integer uses the two’s complement binary number system. That means the left most bit is used as a sign bit (0 for positive and 1 for negative). The remaining bits are used to represent the number.

To simplify things. I’ll use a 4-bit integer. The maximum number of combinations is 2^4 or 16. The largest negative number is 2^(4-1) or 8. The largest positive number is 2^(4-1)-1 or 7. The range is therefore -8 to 7.

In binary we have:

0 1 1 1   equals +7
1 0 0 0   equals -8

So lets take the absolute value of -8 at the bit level.

Start:              1 0 0 0       equals -8
Negate bits:        0 1 1 1       equals  7
Add one             1 0 0 0       equals -8

And so we start with -8 and end up with -8. The same result happens regardless of the size of the signed integer.

Try it with a value that is in range.

Start:             1 1 0 1       equals -3
Negate bits:       0 0 1 0       equals  2
Add one            0 0 1 1       equals  3

No comments:

Post a Comment