Algoritmo: no use símbolos de suma y resta para realizar la suma y resta de dos números, dos métodos de implementación

Leetcode-371

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

示例 1:

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

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

1. Realice la suma sin usar símbolos de suma y resta (I)

Viendo que el código dado por los grandes es realmente muy conciso, pero lo mismo también es difícil de entender. Aquí hay una solución muy intuitiva.
Ideas principales:
1. Hacer una máscara de 1 << 0 a 1 << 31, Itere y realice AND bit a bit con ayb respectivamente para detectar el bit
2 correspondiente . Si los bits correspondientes son todos 1, entonces lleve un bit: resultado | = máscara << 1;
3. Si solo uno de los bits correspondientes es 1, y el resultado es Si el bit actual es 0, establezca la posición actual en 1.
4. Si solo uno de los bits correspondientes es 1, y el resultado es 1, la posición actual es 0, entonces lleve 1 a
5 y regrese al resultado

    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;
    }

El método de escritura anterior en realidad no es un problema, aunque se usa el operador ++ al obtener la máscara.
La instrucción de ensamblaje correspondiente al operador ++ es realmente INC después de que se asigna a X86, mientras que + es ADD. Pero ++ todavía parece un poco desagradable.

Para evitar esta situación incómoda, podemos cambiar nuestra forma de pensar. La máscara puede obtenerse por sí misma, es decir, después de cada ronda del ciclo, máscara = máscara << 1; hasta máscara == 1 << 31 cuando el ciclo finaliza. De esta forma obtenemos una suma obtenida por operaciones bit a bit puro.


    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. Realizar sumas sin usar símbolos de suma y resta (II)

El código conciso dado por los grandes es el siguiente:

    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;
    }

Explique brevemente:
1. La suma sin acarreo se realiza mediante XOR
2. El valor de acarreo está determinado por el bit más alto de ay b. Si los dos bits más altos son ambos 1, entonces acarrean 1 bit, y el bit más alto de a y b puede ser determinado por a & b Es más fácil de entender, y luego, si el resultado del AND bit a bit de su bit más alto es el bit más alto 1, entonces muévase un bit a la izquierda, que es un acarreo. Hasta que el acarreo sea 0, el cálculo finaliza.

3. Realice la resta sin usar símbolos de suma y resta

¿Cómo lograr la resta? Esto debe tener en cuenta la conversión de números positivos y negativos, número negativo = número positivo invertido por +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;
    }

Supongo que te gusta

Origin blog.csdn.net/qq_23594799/article/details/105324292
Recomendado
Clasificación