所谓”不用加号的加法运算“

        今天一个小朋友问了我一个很有意思的问题:”不用加号的加法运算“,大抵就是说,”诶~网上有人不用【+】就可以实现加法哟~“

        这个问题以前大学的时候玩过,是一个很有意思的问题。

        每个人小学的时候,都学过四则运算,但是因为四则运算太简单了,我们谁也没有注意过我们学习的四则运算包括术式的写法有一个前提,就是:在十进制中!

        而根据冯诺依曼原理的第一条:数字计算机的数制采用二进制。

        在二进制条件下,计算往往是采用逻辑计算的方法实现的,而非四则方法。这就为这个命题提供了可能性。

        我们可以类比四则中的加法运算进行分析,加法最烦的就是进位。而二进制计算特别容易进位。什么时候会进位呢。相同位的加数被加数出现了同样为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]$ 


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田辛 | 田豆芽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值