Why the absolute value of the max negative integer -2147483648 is still -2147483648?

匿名 (未验证) 提交于 2019-12-03 00:48:01

问题:

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

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

output:

abs(-2147483648): -2147483648

回答1:

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.



回答2:

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



回答3:

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



回答4:

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 

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



回答5:

Try this

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!