所謂”不用加號的加法運算“

        今天一個小朋友問了我一個很有意思的問題:”不用加號的加法運算“,大抵就是說,”誒~網上有人不用【+】就可以實現加法喲~“

        這個問題以前大學的時候玩過,是一個很有意思的問題。

        每個人小學的時候,都學過四則運算,但是因爲四則運算太簡單了,我們誰也沒有注意過我們學習的四則運算包括術式的寫法有一個前提,就是:在十進制中!

        而根據馮諾依曼原理的第一條:數字計算機的數制採用二進制。

        在二進制條件下,計算往往是採用邏輯計算的方法實現的,而非四則方法。這就爲這個命題提供了可能性。

        我們可以類比四則中的加法運算進行分析,加法最煩的就是進位。而二進制計算特別容易進位。什麼時候會進位呢。相同位的加數被加數出現了同樣爲1的情況(邏輯與)。爲了完成進位,還要右移一位。

        最討厭的進位問題解決完了(記得小學時候沒少因爲這個被罵),那麼不進位的怎麼辦?

        在同位的前提下,0和1碰見,是1(反之也是),0和0碰見是0,1和1碰見的話會進位,所以當前位還是0。

        通過上邊分析發現,在刨去進位的問題後,剩下的計算,就是一個異或的邏輯運算。

        下面用實例說明: 12 + 9 = 21 

            12的二進制數是 1100 

            9的二進制數是   1001

        我們首先計算不進位的,異或計算, 0101

        進位的計算(邏輯與) 1000 左移有一位後 10000

        繼續計算, 0101 與10000的異或計算 10101

        邏輯與運算結果是00000,由於進位已經結束。則計算結束。二進制10101就是最終的計算結果,即十進制的21.

        下面通過程序來實現這個計算:

           

#include <stdio.h>
#include <stdlib.h>

int operCnt;                                         /* number of operations */     
int num1 = 0;                                          /*  addend 1          */
int num2 = 0;                                          /*  addend 2          */
int rst  = 0;                                          /*  sum               */

int add(int n1, int n2);                                /* addition function */

/* Main Function */
int main(int argc, char* argv[]){

    /* Arguments Check */
    if( argc != 3 && argc != 2){
        printf("Arguments Number Error.\n");
        exit(-1);
    }else{
        num1 = atoi(argv[1]);
        if( argc = 3 ){
            num2 = atoi(argv[2]);
        }
    }

    printf("= Formula ===============================\n");
    printf("%d + %d \n", num1, num2);
    printf("=========================================\n");

    rst = add(num1, num2);

    printf("= Result ================================\n");
    printf("%d + %d = %d\n", num1, num2, rst);  
    printf("=========================================\n");
    exit(0);
}

/* Addition Function */
int add(int n1, int n2){
    operCnt++;
    
    printf("Operation Times:%d\n", operCnt);
    printf("\t Addend 1=%d, Addend 2=%d\n", n1, n2);

    if( n2 == 0 ){
        return n1;
    }

    int cxor  = n1 ^ n2;
    int candl = (n1 & n2) << 1;
    
    return add(cxor, candl);
}


程序執行

[densintian@rachel src]$ gcc add.cpp
[densintian@rachel src]$ ./a.out 12 9
= Formula ===============================
12 + 9 
=========================================
Operation Times:1
         Addend 1=12, Addend 2=9
Operation Times:2
         Addend 1=5, Addend 2=16
Operation Times:3
         Addend 1=21, Addend 2=0
= Result ================================
12 + 9 = 21
=========================================
[densintian@rachel src]$ 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章