劍指Offer(Java版):不用加減乘除作加法

題目:寫一個函數,求兩個整數之和,要求在函數體內不得適用+,-,* ,./  四則運算符號面試

面試的時候被問道這個問題,首先咱們分析人們是如何進行十進制的加法 的,好比是如何得出5+17=22的結果的,實際上,咱們能夠分三步進行:第一步只作各位相加不進位,此時相加的結果是12,第二步作進位,5+7中有進 位,進位的值爲10;第三步,把前面的兩個結果加起來12+10的結果是22,恰好5+17=22函數

咱們一直在想,求兩個樹之和四則運算都不能用,還能用什麼?對數字作運算,除了四則運算以外,也就只剩下位運算了。位運算是針對二進制的,咱們就以二進制再來分析一下前面的三步走的策略對二進制是否是也適用。class

5的二進制是101,17的二進制是10001,仍是試着把計算分紅 三步:第一步各位相加但不計進位,獲得的結果是10100;第二步記下進位。在這個例子中只在最後一位相加時產生進位,結果是二進制的10,第三步把前兩 步的結果相加,獲得的結果是10110,轉換成十進制恰好是22,因而可知三步走的策略對二進制也是適用的。二進制

接下來咱們試着把二進制的加法用位運算來替換。第一步不考慮進位對每 一位相加。0+0,1+1的結果都是0,1+0的結果是1。0+1的結果是1,咱們注意到這和異或的結果是同樣的。對異或而言,0和0,1和1異或的結果 是0,而0和1,1和0的結果異或是1,接着考慮第二步進位,對0+0,0+1,1+0而言,都不會產生進位,只有1+1時,會向前差生一個進位。此時 咱們能夠想象成是兩個數先作位運算,而後再向前左移動一位。只有兩個數都是1的時候。第三步相加的過程是重複前面的兩步,直到不產生進位爲止。static

把這個過程想清楚以後,寫出代碼很是簡介。以下:移動

 

package cglib;while

public class jiekou {數字

    public static void main(String[] args) {
        jiekou p=new jiekou();
        System.out.println(p.add(5, 17));
        }
        public int add(int num1,int num2){
        int sum,carray;
        do{
        sum=num1^num2;//5的二進制是00101,17的二進制是10001,異或後爲10100,20
        carray=(num1&num2)<<1;//5的二進制是00101,17的二進制是10001,與後爲00001,左移後爲00010
        num1=sum;
        num2=carray;
        System.out.println("num1="+sum);
        System.out.println("num2="+carray);
        }while(num2!=0);
        System.out.println("num1="+sum);
        return num1;//第二次是10100^00010=10110;10100&00010=00000,左移後是00000,因此返回10110
        }
    }位運算


輸出:new

num1=20 num2=2 num1=22 num2=0 num1=22 22

相關文章
相關標籤/搜索