Is this how the + operator is implemented in C?

后端 未结 9 1705
抹茶落季
抹茶落季 2021-01-30 06:21

When understanding how primitive operators such as +, -, * and / are implemented in C, I found the following snippet from an

相关标签:
9条回答
  • 2021-01-30 06:48

    When you add two bits, following is the result: (truth table)

    a | b | sum (a^b) | carry bit (a&b) (goes to next)
    --+---+-----------+--------------------------------
    0 | 0 |    0      | 0
    0 | 1 |    1      | 0
    1 | 0 |    1      | 0
    1 | 1 |    0      | 1
    

    So if you do bitwise xor, you can get the sum without carry. And if you do bitwise and you can get the carry bits.

    Extending this observation for multibit numbers a and b

    a+b = sum_without_carry(a, b) + carry_bits(a, b) shifted by 1 bit left
        = a^b + ((a&b) << 1)
    

    Once b is 0:

    a+0 = a
    

    So algorithm boils down to:

    Add(a, b)
      if b == 0
        return a;
      else
        carry_bits = a & b;
        sum_bits = a ^ b;
        return Add(sum_bits, carry_bits << 1);
    

    If you get rid of recursion and convert it to a loop

    Add(a, b)
      while(b != 0) {
        carry_bits = a & b;
        sum_bits = a ^ b;
    
        a = sum_bits;
        b = carrry_bits << 1;  // In next loop, add carry bits to a
      }
      return a;
    

    With above algorithm in mind explanation from code should be simpler:

    int t = (x & y) << 1;
    

    Carry bits. Carry bit is 1 if 1 bit to the right in both operands is 1.

    y ^= x;  // x is used now
    

    Addition without carry (Carry bits ignored)

    x = t;
    

    Reuse x to set it to carry

    while(x)
    

    Repeat while there are more carry bits


    A recursive implementation (easier to understand) would be:

    int add(int x, int y) {
        return (y == 0) ? x : add(x ^ y, (x&y) << 1);
    }
    

    Seems that this function demonstrates how + actually works in the background

    No. Usually (almost always) integer addition translates to machine instruction add. This just demonstrate an alternate implementation using bitwise xor and and.

    0 讨论(0)
  • 2021-01-30 07:01

    To be pedantic, the C specification does not specify how addition is implemented.

    But to be realistic, the + operator on integer types smaller than or equal to the word size of your CPU get translated directly into an addition instruction for the CPU, and larger integer types get translated into multiple addition instructions with some extra bits to handle overflow.

    The CPU internally uses logic circuits to implement the addition, and does not use loops, bitshifts, or anything that has a close resemblance to how C works.

    0 讨论(0)
  • 2021-01-30 07:06

    In case a breakdown of the code helps anyone else, take the example x=2, y=6:


    x isn't zero, so commence adding to y:

    while(2) {
    

    x & y = 2 because

            x: 0 0 1 0  //2
            y: 0 1 1 0  //6
          x&y: 0 0 1 0  //2
    

    2 <<1 = 4 because << 1 shifts all bits to the left:

          x&y: 0 0 1 0  //2
    (x&y) <<1: 0 1 0 0  //4
    

    In summary, stash that result, 4, in t with

    int t = (x & y) <<1;
    

    Now apply the bitwise XOR y^=x:

            x: 0 0 1 0  //2
            y: 0 1 1 0  //6
         y^=x: 0 1 0 0  //4
    

    So x=2, y=4. Finally, sum t+y by resetting x=t and going back to the beginning of the while loop:

    x = t;
    

    When t=0 (or, at the beginning of the loop, x=0), finish with

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