我之前的博客里有讲到cpu是怎么做加减乘除的
偶然间看到一个面试题说的是不用加法去做加运算
其实仔细想想,就是以二进制的方式来运算咯,只不过把计算机组成原理里的那套搬到编程里来
复习一下加法:

cpu首先对加法的ADD指令是这样做的:
比如0001+0001
首先进行&运算等于0001+0001=0001 这里顺便复习一下与运算0&0=0,1&1=1,1&0或0&1=0
也就是说两数相等等于这个数,两数不相等等于0
进行与运算后,cpu有个进位条件,当两数为1时,就满足进位条件,所以需要做一个<<1的运算,除非两数为0则不做
这样就完成了一次运算,但是到这还没有结束
cpu还要检查一下其它的bit位有没有做完运算,所以cpu会把进位后的结果放到通用寄存器里存储着
如何判断其它bit位有没有做完运算?很简单,只需要进行一次xor运算就可以了
xor的运算是0任何数都等于任何数,而1任何数都等于任何数取反
cpu会将加数和被加数做一次xor运算,注意这里的加数与被加数不是进位后的数
0001^0001=0000
其结果会放在加数寄存器里
然后在把进位结果放到被加数寄存器里
那么此时加数寄存器=0000 而被加数寄存器=0010
cpu会判断一次被加数寄存器是否为0000如果不为0就代表还有位需要运算

那么cpu开始了第二次运算,重复上面的步骤
也就是 0000&0010
那么结果就是0000
如果是0000那么就不用进位了,直接进入下一个步骤
xor运算,注意结果被放入到了一个临时的通用寄存器里了,并不会放在加数与被加数的寄存器上,所以它们的值还是0000和0010
0000^0010=0010
这样看会更清晰吧:
0000
^^^^
0010
———
0010
0^任何数都等于任何数
然后在将结果放入到加法寄存器里,被加数寄存器里放入刚刚的临时通用寄存器里的结果0000
然后cpu判断被加数的bit位算完了就跳出循环
那么加法寄存器里就是答案
也成累加器寄存器
那么换算成c语言怎么换算呢?
1.函数:

int add(int a,int b);

a与b就是加数与被加数
这里我们直接使用,cpu的话会放入到累加器,这里我们省略一个变量
声明一个变量用来用临时的通用寄存器

int temp_reg = 0;

根据上面说的,是一个循环,每次循环判断被加数也就是b的进制位是否运算完,判断方法就是是否等于0,如果为0那么bit位都是0

while(b != 0){

}

根据上面说的,第一步做与运算然后把结果放入到临时寄存器里

temp_reg = a & b;

判断一下临时寄存器是否需要进位,上面说过进位的条件是bit位是否为0
如果每次&运算后bit位有一个不为0那么都需要进位一次

if(temp_reg != 0){
temp_reg = temp_reg << 1
}

然后根据上面说的做一次与运算,结果放入到加法寄存器里,这里你也可以在申请一个变量做累加器寄存器,这里我只是觉得这样写比较节省内存。因为cpu本身不是用加法寄存器保存这个数的,用的是累加器寄存器

a ^= b;

最后再把通用寄存器的结果放入到被加数寄存器里

b = temp_reg;

这样模拟cpu二进制加法运算的工作就完成了
最后一步直接return a即可
完整代码:

int add(int a, int b) {
unsigned int temp_reg=0;
while(b != 0){
temp_reg = a & b;
if(temp_reg != 0){
temp_reg=temp_reg<<1;
}
a ^= b;
b = temp_reg;
}
return a;
}

力扣:

还有一种写法
是利用编译器的解析器
但是这种方法是耍个小聪明原则上编译内部还是用了+符号
如,假设有一个char指针指向了一个包含’abcd’的字符串
char p;
那么p[2]编译器会翻译成
(p+2) 这个是指针的用法
是解引用,对这个地址取值,而&则是取这个地址
所以当我们用指针的方式来对变量进行运算:
int a,int b;
(char
)a[b]; 这样写可以让编译器帮我们隐式翻译成*(a+b)
那么问题是会对这块地址取值,解引用,但是这个地址是不安全的,因为这不是指针,实际地址就是a的值+b的值,但是这不是我们想要的,上面说了用&,只要在前面加一个&编译起会翻译成返回这块地址
也就是说把*(a+b)不对它解引用了,直接把它们当地址返回,就是返回a+b的值了
代码:
int add(int a,int b){

return (long)&(((char*)a)[b]);

}
注意返回的地址是指针,所以我们转换一下就可以了
这样的代码本质上还是使用了+

c语言不使用加运算符做加法运算相关推荐

  1. shell 做加法运算_C语言探索之旅 | 第一部分第七课:运算那点事

    上一课是 C语言探索之旅 | 第一部分第六课:变量的世界(三),显示变量内容 今天,我们一起来学习 C语言(对大多数编程语言也类似)中的运算. 之前的课中,我们已经说过:电脑是一台"笨笨&q ...

  2. 不用加减乘除做加法运算

    不用加减乘除法,只能用位运算来代替做加法了. 第一步:不考虑进位,0加0与 1加1的结果都0,0加1与1加0的结果都是1.我们可以注意到,这和异或的结果是一样的. 第二部:只考虑运算进位,对0加0.0 ...

  3. 程序员面试100题之三:不用+、-、×、÷数字运算符做加法

    题目:写一个函数,求两个整数的之和,要求在函数体内不得使用+.-.×.÷. 分析:这又是一道考察发散思维的很有意思的题目.当我们习以为常的东西被限制使用的时候,如何突破常规去思考,就是解决这个问题的关 ...

  4. shell 做加法运算_Shell数学计算(算术运算,加减乘除运算)

    如果要执行算术运算(数学计算),就离不开各种运算符号,和其他编程语言类似,Shell 也有很多算术运算符,下面就给大家介绍一下常见的 Shell 算术运算符,如下表所示.Shell 算术运算符一览表算 ...

  5. shell 做加法运算_使用shell脚本实现加法乘法运算

    编写一个shell脚本,实现加法和乘法运算. #!/bin/bash #Function:num1+num2 num3*num4 sum(){ read -p "please key in ...

  6. c语言中 加法符号如何定义,【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】...

    第一题 #include int main() { unsigned int a=6; int b=-20; printf("%d\n",a+b); (a+b)>6? put ...

  7. 【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】

      第一题 #include<stdio.h>  int main()  {  unsigned int a=6;  int b=-20;  printf("%d\n" ...

  8. 面试问题-使用Java线程做数学运算

    这是一个展示如何使用join()方法的例子. 问题: 使用Java多线程计算表达式1*2/(1+2)的值. 解决方案: 使用一个线程做加法运算,另一个线程做乘法运算,还有一个主线程main做除法运算. ...

  9. DHU 9 长整数加法运算

    9 长整数加法运算 作者: Turbo时间限制: 1S章节: 链表 问题描述 假设2个任意长度的整数x.y分别由双向链表A和B存储,现要求设计一个算法,实现x+y.计算结果存储在链表C中. 说明: 由 ...

最新文章

  1. Java知识点总结——装箱与拆箱
  2. mysql java datetime_Java向mysql数据库插入datetime类型数据实例(精)
  3. android singleInstance返回问题
  4. 站立会议(11月19日)
  5. sqoop从mysql到hive问题
  6. 沉淀一年零八个月,我也拿到了博客专家
  7. Python import导入模块与函数方法 Python语言基础【1】
  8. ajax项目中使用模板
  9. 反斜杠在C/C++中的作用
  10. 关于sql安装,升级,卸载时需要重启的解决方法
  11. 时间序列-Auto-ARIMA模型
  12. PTV-VISSIM交通仿真
  13. 离线安装包_Altium Designer 19.0.14离线安装包
  14. android keytool工具,keytool工具的使用
  15. linux开远程连接,Linux/Ubuntu 怎么设置打开远程桌面登录连接
  16. win10设置保护色
  17. 腾讯组织了一个联盟,但无法阻止字节跳动拿走一半游戏广告
  18. js监听只读文本框_js设置input文本框只读
  19. pip install下载速度太慢
  20. UNR2 黎明前的巧克力

热门文章

  1. linux编译命令io,Hadoop 用命令行编译URLCat
  2. mysql多表关联update
  3. pdfdom将pdf转成html,使用pdfdom将pdf转为html(示例代码)
  4. mysql同步多主,MySQL多主一从同步配置
  5. java生日验证_Java验证身份证号码是否有效
  6. linux fread 头文件,Linux文件操作
  7. zabbix中mysql连不上的排错_zabbix使用排错 - oschina130111的个人空间 - OSCHINA - 中文开源技术交流社区...
  8. mysql -e -f_twitter-不正确的字符串值:'\ xF0 \ x9F \ x8E \ xB6 \ xF0 \ x9F ...'MySQL
  9. html立方体旋转展开,css3技术设计立方体旋转发光效果动图
  10. matlab打包多个m文件,MATLAB GUI多个m文件和fig如何生成exe文件