It is a rule in math that the absolute value of a number must be no less than zero. Is it true in computer languages? Well, most of the case except one. Let me take C language for example.

For a 32-bits C interger, its value ranges from **[-2147483648, 2147483647]** .So for `x = -2147483648`

, what is the result of `abs(x)`

? `2147483648`

, `-2147483648`

, `2147483647`

, `0`

or something else?

**The result depends on your compiler!** Please be careful to handle this undefined result in your coding.

Let’s look into the implementation of the `abs`

function in C:

1 2 3 4 5 6 7 8 9 10 11 12 13 |
#define INT_MIN -2147483648 #define INT_MAX 2147483647 // the simplest way to implement the abs function // it varies from the C version template <class T> T abs(const T& x) { return x > 0 ? x : -x; } int x = INT_MIN; x = abs(x); bool x_is_positive = x > 0; // false! x still equals to INT_MIN </class> |

So a potential bug may skip into your code like this situration:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int arr[] = {1001, -999, -1000, INT_MIN, INT_MAX}; int size = sizeof(arr) / sizeof(int); const int threshhold = 999; for (int i = 0; i < size; ++i) { if (abs(arr[i] > threshhold)) { // do something to arr[i] // e.g print arr[i] cout < < arr[i] << endl; } } // RESULT // Expected: 1001, -1000, 2147483648, 2147483647 // Actual Output: 1001, -1000, 2147483647 |

But if you really test the above code in your computer, probobly you will find that the computer gives you the expected output. Here is a Demo on ideone.com; You are suggested trying on your machine!

What happens to the correct output occassion is that the compiler actually return a longer integer type like `long long`

which is 8 bytes usually. For `long long y = abs(INT_MIN);`

, y is equal to `INT_MAX + 1`

for sure.

This is as much as the modern compiler can help you reduce your bugs. If you code in this way:

1 2 3 4 |
int value = abs(arr[i]); if (value > threshhold)) { // do something to arr[i] } |

This time bugs are more likely to happen on you. Nigel Jones gives some good solutions to the problem in his article: The absolute truth about abs().

In summary, there are several ways to avoid the abs bug: 1. Always use a longer type to store your abs result, like `long long`

for `int`

. But what type for `long long`

? Therefore the better one is `double`

, in the cost of casting time and more CPU cycles. 2. Write your own abs function like this one: safe abs function; 3. Carry out the comparision in the negative space because negetive space is larger than the postive space.

Both solution 2 & 3 require you to use your own abs function.

That’s my report on delving the absolute function in C language. Just as a saying goes: **Think twice before you code** 🙂