The result of abs(-2147483648)
is -2147483648
, isn't it?
it seems unacceptable.
printf("abs(-2147483648): %d\n", abs(-2147483648));
output:
abs(-2147483648): -2147483648
The result of abs(-2147483648)
is -2147483648
, isn't it?
it seems unacceptable.
printf("abs(-2147483648): %d\n", abs(-2147483648));
output:
abs(-2147483648): -2147483648
The standard says about abs()
:
The
abs
,labs
, andllabs
functions compute the absolute value of an integerj
. 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.
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
Since 2147483648 is greater than INT_MAX
on your implementation, then abs(-2147483648)
is undefined.
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
I recall that this is an overflow error. The maximum value of an integer in S2C for signed integers is -(2^(total bits - 1)). However the maximum positive value is actually (2^(total bits - 1))-1. Bitwise, the function produces the right thing. However, the "correct" bitwise value overshoots the maximum positive value by one, rolling over to the set of negative values.
abs(INT_MIN)
. –
Slashing Try this
printf("abs(-2147483648): %u\n", abs(-2147483648));
© 2022 - 2024 — McMap. All rights reserved.
abs(int)
returns anint
? – Howlan