27

The result of abs(-2147483648) is -2147483648, isn't it? it seems unacceptable.

printf("abs(-2147483648): %d\n", abs(-2147483648));

output:

abs(-2147483648): -2147483648
Victor S
  • 4,021
  • 15
  • 43
  • 54

5 Answers5

33

The standard says about abs():

The abs, labs, and llabs functions compute the absolute value of an integer j. If the result cannot be represented, the behavior is undefined.

And the result indeed cannot be represented because the 2's complement representation of signed integers isn't symmetric. Think about it... If you have 32 bits in an int, that gives you 232 distinct values from INT_MIN to INT_MAX. That's an even number of values. So, if there's only one 0, the number of values greater than 0 cannot be the same as the number of values less than 0. And so there's no positive counterpart to INT_MIN with a value of -INT_MIN.

So, what's unacceptable is calling abs(INT_MIN) on your platform.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
18

Negative numbers are usually represented whit binary complement.

To convert positive to negative it is used logic

x -> not(x)+1

For 8 bits arithmetic

01111111b is 127 and -127 becomes
10000000b + 1 = 10000001b

and to opposite direction -127 10000001b becomes
01111110b + 1 = 01111111b

What about -128?

-128 is 10000000b and there is no positive counterpart of it, because there is no 128 in 8 bits signed arithmetic.

10000000 -> 01111111 + 1 = 10000000 and -128 again

Same applies to original question

Luka Rahne
  • 10,336
  • 3
  • 34
  • 56
10

Since 2147483648 is greater than INT_MAX on your implementation, then abs(-2147483648) is undefined.

Alexandre C.
  • 55,948
  • 11
  • 128
  • 197
5

This is code in abs.c in GNU glibc source code.

/* Return the absolute value of I.  */
int
DEFUN(abs, (i), int i)
{
  return(i < 0 ? -i : i);
}

So,abs(-2147483648) return -(-2147483648) . In x86,it is implement by this two instruction

movl    $-2147483648, %eax
negl    %eax

negl instruction is implemented by this way: num=0-num; sbb is implemented by this way: Subtracts the source from the destination, and subtracts 1 extra if the Carry Flag is set. So abs(-2147483648) (hex is 0x80000000 ) --> -(-2147483648) --> 0-(-2147483648) becomes (0x80000000) finally.

details of negl instruction,please visit http://zsmith.co/intel_n.html#neg

details of sbb instruction ,please visit http://web.itu.edu.tr/kesgin/mul06/intel/instr/sbb.html

Mazheng
  • 166
  • 4
-5

Try this

printf("abs(-2147483648): %u\n", abs(-2147483648));
Kijewski
  • 25,517
  • 12
  • 101
  • 143
Superman
  • 3,027
  • 1
  • 15
  • 10
  • 6
    This, my friend, has undefined behavior. You're printing a signed integer with the unsigned formatter. I -1 because it moreover does not answer the question. – Alexandre C. Jun 28 '12 at 11:16