Why is the absolute value of the maximum negative integer -2147483648 equal to -2147483648?

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

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

exit:

 abs(-2147483648): -2147483648 
+19
c libc
Jun 28 2018-12-12T00:
source share
5 answers

The standard says abs() :

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

And the result really cannot be represented, since the representation with two additions of signed integers is not symmetric. Think about it ... If you have 32 bits in an int , this gives you 2 32 different values ​​from INT_MIN to INT_MAX . This is an even number of values. So, if there is only one 0, the number of values ​​greater than 0 cannot be the same as the number of values ​​less than 0. And therefore there is no positive analogue of INT_MIN with a value of INT_MIN .

So, what is unacceptably calling abs(INT_MIN) on your platform.

+18
Jun 28 '12 at 13:30
source share

Since 2147483648 is more than INT_MAX for your implementation, abs(-2147483648) is undefined.

+10
Jun 28 '12 at 11:17
source share

Negative numbers are usually represented without a binary complement.

To convert positive to negative, logic is used

 x -> not(x)+1 

For 8-bit arithmetic

01111111b - 127, and -127 - 10000000b + 1 = 10000001b

and in the opposite direction -127 10000001b will become
01111110b + 1 = 01111111b

How about -128?

-128 is equal to 10000000b, and there is no positive analogue of it, since there is no 128-bit arithmetic signed in 8 bits.

10000000 → 01111111 + 1 = 10000000 and -128 again

The same goes for the original question

+9
Jun 28 2018-12-12T00:
source share

This is the code in abs.c in the 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 implemented using this two commands

 movl $-2147483648, %eax negl %eax 

Negl instruction is implemented as follows: Num = 0-Num; sbb is implemented as follows: Subtracts the source from the destination and subtracts 1 additional if the carry flag is set. So abs (-2147483648) (hex - 0x80000000) → - (- 2147483648) → 0 - (- 2147483648) finally becomes (0x80000000).

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

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

+5
Jun 28 2018-12-12T00:
source share

try it

 printf("abs(-2147483648): %u\n", abs(-2147483648)); 
-5
Jun 28 '12 at 11:10
source share



All Articles