【问题标题】:Subtract two numbers without using arithmetic operators不使用算术运算符减去两个数字
【发布时间】:2019-05-27 07:14:44
【问题描述】:

我面临的问题是:-

位运算符的逻辑在下面的代码中是如何工作的?

代码:

#include <stdio.h>

int subtract(int x, int y)
{
    while (y != 0)
    {
        int borrow = (~x) & y;
        x = x ^ y;
        y = borrow << 1;
    }
    return x;
}

int main()
{
    int x = 29, y = 13;
    printf("\nx - y is %d", subtract(x, y));
    return 0;
}

subtract(x,y) 函数是如何工作的?

【问题讨论】:

  • “调试”它使用笔和纸。在纸上写下所有的数字(作为位),并一个一个地做所有的操作(仍然使用位)。并将复杂的操作(例如(~x) &amp; y)拆分成最简单的部分(例如int temp = ~x; int borrow = temp &amp; y;
  • 简而言之:首先设置borrow 变量来识别进位位。然后,xor 进行(无进位)加法/减法,这在基数 2 中是相同的。然后,进位在步骤 3 中处理。我想知道这是否也适用于波纹进位

标签: c bitwise-operators subtraction


【解决方案1】:

二进制,

 x   y  | x-y
--- ---   ---
 0   0  |  0
 0   1  |  1 (with a borrow)
 1   0  |  1
 1   1  |  0

也就是说

 x   y  |       x-y
--- ---   ---------------
 0   0  |  0 - ( 0 << 1 )
 0   1  |  1 - ( 1 << 1 )
 1   0  |  1 - ( 0 << 1 )   
 1   1  |  0 - ( 0 << 1 )

也就是说

x - y

等价于

( x ^ y ) - ( ( (~x) & y ) << 1 )

因为减法的结果可以由x ^ y给出

 x   y  | x^y
--- ---   ---
 0   0  |  0
 0   1  |  1
 1   0  |  1
 1   1  |  0

可以通过(~x) &amp; y给出借款金额

 x   y  | (~x) & y
--- ---   --------
 0   0  |     0
 0   1  |     1
 1   0  |     0
 1   1  |     0

检查(正负)溢出时发生的情况留给用户。

【讨论】:

    【解决方案2】:

    使用递归函数

    int reduce(int a, int b){
        if(b == 0){
            return a;
        }
        int value, carry;
        carry = ((~a) & b) << 1;
        value = a ^ b;
        return reduce(value,carry);
    }
    

    使用 while 循环

    int reduce(int a, int b){
        while(b){
            int carry = ((~a) & b) << 1;
            a = a ^ b;
            b = carry;
        }
        return a;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多