不用加号实现两整数相加
1.减法实现
int addWithoutPlusSign(int a, int b)
{return a - (-b);
}
2.异或实现
对于二进制的加法运算,若不考虑进位,则1+1=0,1+0=1,0+1=1,0+0=0,通过对比异或,不难发现,此方法与异或运算类似。因而排出进位,加法可用异或来实现。然后考虑进位,0+0进位为0,1+0进位为0,0+1进位为0,1+1进位为1,该操作与位运算的&操作相似。
那么加法运算可以这样实现:
(1)先不考虑进位,按位计算各位累加(用异或实现),得到值a;
(2)然后再考虑进位,并将进位的值左移,得值b,若b为0,则a就是加法运算的结果,若b不为0,则a+b即得结果,此时可递归调用位运算函数。
具体实现:
#include <iostream>
using namespace std;int g_fBitAdd(int a,int b)
{if(b==0)return a;int sum = a^b;int carry =(a&b)<<1;return g_fBitAdd(sum,carry);
}int main()
{cout<<"9+1="<<g_fBitAdd(99,11)<<endl;cout<<"99+11="<<g_fBitAdd(99,11)<<endl;cout<<"-2+11="<<g_fBitAdd(-2,11)<<endl;
}
输出:
9+1=110
99+11=110
-2+11=9
计算机本质是二进制运算,许多高人和天书都展示了如何用位运算来实现让人纠结却又惊奇的事情。上面用位运算实现加法,是基于如下定理实现:
定理1:设a,b为两个二进制数,则a+b = a^b + (a&b)<<1。
**证明:**a^b是不考虑进位时加法结果。当二进制位同时为1时,才有进位,因此 (a&b)<<1是进位产生的值,称为进位补偿。将两者相加便是完整加法结果。
定理2:使用定理1可以实现只用位运算进行加法运算。
证明:利用定理1中的等式不停对自身进行迭代。每迭代一次,进位补偿右边就多一位0,因此最多需要迭代二进制数位长减一次,进位补偿就变为0,这时运算结束。
3.内嵌汇编
C/C++函数返回值是通过寄存器eax返回,所以通过内联汇编指令的方式可以实现两数相加。注意GNU C++内联汇编语法使用AT&T/UNIX语法,和Visual C++的Intel内联汇编语法不同。具体实现如下:
#include <iostream>
using namespace std;int asmAdd(int a,int b)
{asm("movl %0,%%eax\n\t""movl %1,%%ecx\n\t""addl %%ecx,%%eax"::"r"(a),"r"(b));
}int main()
{cout<<"99+1="<<asmAdd(99,11)<<endl;cout<<"99+11="<<asmAdd(99,11)<<endl;cout<<"-2+11="<<asmAdd(-2,11)<<endl;
}
使用g++ test.cpp
编译运行结果如下:
99+11=110
99+11=110
-2+11=9
关于上述内联汇编代码的有如下几点解释:
(1)多行汇编指令使用\n\t进行换行,并使用双引号将单行指令括起来;
(2)使用双百分号引用寄存器,告诉编译器引用的是寄存器而非操作数;
(3)第一个冒号表示引用的C++的变量,用于输出,因无需输出变量,所以留空;
(4)第二个冒号表示汇编代码需要读取的C++的变量,”r”表示使用任意寄存器来存放变量a和b的值,多个变量使用逗号分隔。在汇编代码中访问时,按照申请的顺序从数字0开始,使用%进行访问。比如上面代码中%0表示变量a,%1表示变量b。关于GCC的内联汇编语法,具体可以参见:GCC-Inline-Assembly-HOWTO。
参考文献
[1]不用算术运算符实现两个数的加法(按位异或).CSDN
[2]不用算术运算符实现两个数的加法(按位异或).博客园
[3]GCC-Inline-Assembly-HOWTO
不用加号实现两整数相加相关推荐
- 不用加减乘除完成两数相加
看了剑指offer一书的一个题目,然后自己写了的代码,有迭代和递归两种方式,代码如下: 1 #include <stdio.h> 2 3 int add(int a, int b) //迭 ...
- php二进制整数相加怎么解决_PHP两个n位的二进制整数相加问题的解决
两个n位的二进制整数相加问题PHP实现,供大家参考,具体内容如下 两个n位二进制数分别存储在两个n元数组A和B中,这两个整数的和存在一个n+1元的数组C中 答: 此问题主要是考察相加进位的问题,元素1 ...
- 两个整数相加减是否溢出
#include<stdio.h> #include<stdint.h>// 两个整数相加减,没有溢出时返回0 int tadd_ok(int x, int y) {int s ...
- java实现两个最大整数相加_JAVA-实现两个超大整数相加
思路: 第一步,把整数倒序存储,整数的个位存于数组0下标位置,最高位存于数组长度-1下标位置.之所以倒序存储,更加符合我们从左到右访问数组的习惯. 我们以 426709752318 + 9548125 ...
- -9 逆序输出一个整数的各位数字_leetcode两数相加(大整数相加)
题目来源于leetcode第二题两数相加. 题目描述 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字. 如果,我们将这两个数相 ...
- php写两个数相加方法_【PHP学习】实现两个n位二进制整数相加
详细内容 本篇文章讲述的是用PHP实现两个n位二进制整数相加 ,具有参考价值,感兴趣的朋友可以学习了解一下. 问题:两个n位二进制数分别存储在两个n元数组A和B中,这两个整数的和存在一个n+1元的数组 ...
- 作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)
题目描述 给定一个整数数组,找出其中两个数相加等于目标值输入 [1,3,5,7,9,11] 10输出 1,9 3,7 代码: import java.util.HashMap; import java ...
- 编写一个Java应用程序,从键盘读取用户输入两个字符串,并重载3个函数分别实现这两个字符串的拼接、整数相加和浮点数相加。要进行异常处理,对输入的不符合要求的字符串提示给用户,不能使程序崩溃。
编写一个Java应用程序,从键盘读取用户输入两个字符串,并重载3个函数分别实现这两个字符串的拼接.整数相加和浮点数相加.要进行异常处理,对输入的不符合要求的字符串提示给用户,不能使程序崩溃. pack ...
- 数组两个整数相加 c语言,作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)...
题目描述 给定一个整数数组,找出其中两个数相加等于目标值 输入 [1,3,5,7,9,11] 10 输出 1,9 3,7 代码: import java.util.HashMap; import ja ...
最新文章
- 不容错过的Pandas小技巧:万能转格式、轻松合并、压缩数据,让数据分析更高效...
- python_day2_数据格式
- 华为云查询弹性云服务器规格信息,通用计算型弹性云服务器规格介绍详情-华为云...
- 1、MySQL性能优化简述
- python加载包出错_python导入Pmw包运行提示一下错误
- 夺命雷公狗---PDO NO:3与连接有关的选项
- 谷歌再获语音识别新进展:利用序列转导来实现多人语音识别和说话人分类
- linux 下查看硬件信息
- 【python】打造一款自动扫描全网漏洞的扫描器
- ClassNotFoundException: com.lowagie.text.pdf.PdfGState
- Scrapy实战:使用IDE工具运行爬虫
- 魔百盒CM201-1,YS代工-免拆-线刷固件及教程
- 无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装
- JAVA Signal Handing
- 做游戏,学编程(C语言) 15 太鼓达人
- Excel库存表通过吉度PDA盘点机形成盘点差异表
- 荣誉加持,驭势科技近期斩获奖项回顾
- 采用ODC改善软件质量:一个案例研究
- 华擎主板安装linux系统,J3455 篇一:华擎J3455主板安装Ubuntu server
- DuerOS业绩亮眼,如何成为了百度财报新增长点?
热门文章
- SQL Server 2008:示例数据库安装
- 武汉区块链软件技术公司区块链将如何应用于会员生态系统?
- Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码
- 111 《深入理解Java虚拟机》读书笔记
- [HeadFirst-HTMLCSS入门][第十章div,span]
- 听飞狐聊JavaScript设计模式系列11
- lLinux编程大全
- Windows 7有用的20条新功能及技巧
- udp丢包解决办法 (没打开接收发送缓存)及setsockopt()用法 -转
- mongodb java驱动_Java的MongoDB驱动及读写策略