What is wrong with this code?

So I spend a few frustrating hours tracking down a bug in this seemingly simple idiot proof code:

long labs(long val)
  long retval;
  if (val < 0) 
    retval = -val;
  } else {
    retval = val;
  return retval;

So most of the time this code does exactly what you might expect. It returns the absolute value of the parameter you pass in. All except in one case. Can you figure it out? Answer after the break.

So it happens that for the vast majority of the numbers you can pass in to this function work. The only number that it fails on is -2,147,483,648. This is because there is no positive version of that number! longs range from -2,147,483,648 to +2,147,483,647. The assembler code for “val = -val” expands to “val = 0 – val”. 0 minus -2,147,483,648  should be +2,147,483,648 but as it does not exist, it ends up rolling over and becoming -2,147,483,648.

This entry was posted in Software. Bookmark the permalink.