不用加减乘除做加法

【题目】

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

【分析】

(1)十进制加法分三步:(以5+17=22为例)

  1. 只做各位相加不进位,此时相加结果为12(个位数5和7相加不进位是2,十位数0和1相加结果是1);

  2. 做进位,5+7中有进位,进位的值是10;

  3. 将前面两个结果相加,12+10=22

(2)这三步同样适用于二进制位运算

  1. 不考虑进位对每一位相加。0加0、1加1结果都是0,0加1、1加0结果都是1。这和异或运算一样;

  2. 考虑进位,0加0、0加1、1加0都不产生进位,只有1加1向前产生一个进位。可看成是先做位与运算,然后向左移动一位;

  3. 相加过程重复前两步,直到不产生进位为止。

【思路】

● step1:
按位与是查看两个数哪些二进制位都为1,这些都是进位位,结果需左移一位,表示进位后的结果
● step2:
异或是查看两个数哪些二进制位只有一个为1,这些是非进位位,可以直接加、减,结果表示非进位位进行加操作后的结果
● step3:
n1&n2是查看有没有进位位了,如果有,需要重复step1、step2;如果没有,保留n1、n2上二进制为1的部分,用或将之合为一个数,即为最后结果

【代码】

    public static void main(String[] args) {
         System.out.println(add(12,19));//31
         System.out.println(add(190,19));//209  
         int[] num={3,2};
         changeAB1(num);//2,3
         System.out.println(String.valueOf(num[0])+","+String.valueOf(num[1]));
         changeAB2(num);//3,2
         System.out.println(String.valueOf(num[0])+","+String.valueOf(num[1]));
         changeAB3(num);//2,3
         System.out.println(String.valueOf(num[0])+","+String.valueOf(num[1]));
    }  

    //不用加减乘除做加法
    public static int add(int num1,int num2){
        int n1=num1&num2;//考虑进位,看成是位与运算,再左移一位
        n1<<=1;
        int n2=num1^num2;//不考虑进位对每一位相加,异或运算
        if((n1&n2)!=0){//相加过程重复前两步,直到不产生进位为止
            return add(n1,n2);
        }
        return n1|n2;       //用或将之合为一个数
    }

    //不用新变量,交换两个变量的值
    public static void changeAB1(int[] num){
        num[0]=(num[0]+num[1])-(num[1]=num[0]);
    }

    public static void changeAB2(int[] num){
        num[0]=num[0]+num[1];//a=a+b
        num[1]=num[0]-num[1];//b=a-b
        num[0]=num[0]-num[1];//a=a-b
    }

    public static void changeAB3(int[] num){
        num[0]=num[0]^num[1];//a=a^b
        num[1]=num[0]^num[1];//b=a^b
        num[0]=num[0]^num[1];//a=a^b
    }
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页