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

前端 未结 5 1988
悲哀的现实
悲哀的现实 2020-12-03 05:14

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

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

out

相关标签:
5条回答
  • 2020-12-03 05:25

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

    0 讨论(0)
  • 2020-12-03 05:34

    Try this

    printf("abs(-2147483648): %u\n", abs(-2147483648));
    
    0 讨论(0)
  • 2020-12-03 05:36

    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.

    0 讨论(0)
  • 2020-12-03 05:39

    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

    0 讨论(0)
  • 2020-12-03 05:44

    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

    0 讨论(0)
提交回复
热议问题