Algorithm-do not use addition and subtraction symbols to realize the addition and subtraction of two numbers, two implementation methods

Leetcode-371

不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。

示例 1:

输入: a = 1, b = 2
输出: 3
示例 2:

输入: a = -2, b = 3
输出: 1

1. Realize addition without using addition and subtraction symbols (I)

Seeing that the code given by the big guys is indeed very concise, but the same is also difficult to understand. Here is a very intuitive solution.
Main ideas:
1. Make a mask from 1<<0 to 1<<31, Iterate over and perform bitwise ANDs with a and b respectively to detect the corresponding bit
2. If the corresponding bits are all 1, then carry one bit: result|=mask<<1;
3. If only one of the corresponding bits is 1, and the result is If the current bit is 0, then the current position is 1.
4. If there is only one corresponding bit as 1, and the result is 1, the current position is 0, then the current position is 0, then 1 bit is
5, and the result is returned

    public int getSum1(int a, int b) {
    
    
        int result=0;
        for(int i=0;i<32;i++){
    
    
            int mask=1<<i;
            if((a&mask)!=0&&(b&mask)!=0){
    
    //两个都是1,必然进位
                result|=mask<<1;
            }else if(!(((a&mask)==0)&&((b&mask)==0))){
    
    
                if((result&mask)==0){
    
    
                    result|=mask;
                }else{
    
    
                    result&=~mask;//清除原来位
                    result|=mask<<1;//进一位
                }
            }
        }
        return result;
    }

The above writing is actually no problem, although the ++ operator is used when getting the mask.
The assembly instruction corresponding to the ++ operator is actually INC after it is mapped to X86, while + is ADD. But ++ still looks a bit unpleasant.

In order to avoid this awkward situation, we can actually change our thinking, the mask can actually be obtained by ourselves, that is, after each round of loop, mask=mask<<1; until mask==1<<31, the loop is terminated. In this way we get an addition obtained by pure bitwise operations.


    public int getSum(int a, int b) {
    
    
        int result=0;
        int mask=0;
        while(true){
    
    
            mask=mask==0?1:mask<<1;
            if((a&mask)!=0&&(b&mask)!=0){
    
    //两个都是1,必然进位
                result|=mask<<1;
            }else if(!(((a&mask)==0)&&((b&mask)==0))){
    
    //其中某一个为1
                if((result&mask)==0){
    
    //如果现在位是0,那么将现在位变成1
                    result|=mask;
                }else{
    
    //如果现在位是1,那么要将当前位置0,高位放置1
                    result&=~mask;//清除原来位
                    result|=mask<<1;//进一位
                }
            }
            if(mask==1<<31){
    
    
                break;
            }
        }
        return result;
    }

2. Realize addition without using addition and subtraction symbols (II)

The concise code given by the big guys is as follows:

    public int getSum(int a, int b) {
    
    
    	while (b != 0) {
    
    
            int temp=a^b;//无进位累加值
            int carry=(a&b)<<1;//进位值
            //a=无进位累加值 b=进位值
            a=temp;
            b=carry;
        }
        return a;
    }

Briefly explain:
1. Addition without carry is realized by XOR
2. The carry value is determined by the highest bit of a and b. If the two highest bits are both 1, then carry 1 bit, and the highest bit of a and b can be determined by a&b It is easier to understand, and then if the result of the bitwise AND of their highest bit is the highest bit 1, then move one bit to the left, which is a carry. Until the carry is 0, the calculation is over.

3. Realize subtraction without using addition and subtraction symbols

How to achieve subtraction? This must take into account the conversion of positive and negative numbers, negative number = positive number inverted by +1

    public int getSub(int a, int b) {
    
    
    	b=~b;//获得-b
    	b++;
    	while (b != 0) {
    
    
            int temp=a^b;//无进位累加值
            int carry=(a&b)<<1;//进位值
            //a=无进位累加值 b=进位值
            a=temp;
            b=carry;
        }
        return a;
    }

Guess you like

Origin blog.csdn.net/qq_23594799/article/details/105324292