不使用+或-运算符,计算两数之和

简介: 不使用+或-运算符,计算两数之和

引言

标在我们为了提升自身编程能力刷题时,总会总会遇到一些奇怪的要求,如:不使用+-运算符计算两数之和。

今天我们就可以通过位运算来解决这个问题。


问题描述

给你两个整数 a b ,不使用运算符 + - ,计算并返回两整数之和。

示例一:

输入:a = 1, b = 2

输出:3

示例二:

输入:a = 2, b = 3

输出:5


算法描述

因为题目要求不可以使用+-运算符。所以我们就可以使用位运算,首先了解位运算基础:

1&(与)如果两个相应的二进制位都为1,则该位的结果值为1,否则为0

2|(或)两个相应的二进制位中只要有一个为1,该位的结果值为1

3^(异或)若参加运算的两个二进制位值相同则为0,否则为1

4~(取反)~是一元运算符,用来对一个二进制数按位取反,即将01,将1

5<<(左移)用来将一个数的各二进制位全部左移N位,右补0>>(右移)将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数, 高位补0

通过了解到位运算的基础知识,我们可以:

1)用^(异或运算)得到同位不同值的相加;

2)然后再循环使用&(与运算)<<(左移)得到同位加相加的值,用与运算得到需要进位的值,然后通过左移运算进位(当a&b不为0时,对应位异或结果变为0,但是相当于两个1加在一起要进位,所以(a&b)<<1求得所有进位的1,再进行异或,直到不存在进位为止。)

注:在 Python 的实现中,因为 Python 的整数类型为是无限长的,所以无论怎样左移位都不会溢出。因此,我们需要对Python 中的整数进行额外处理,以模拟用补码表示的 32 位有符号整数类型。具体地,我们将整数对 2^32取模,从而使第 33 位及更高位均为 00


结语

通过灵活使用异或运算和与运算以及循环完成,不使用+-运算符,计算两数相加。


代码清单

不使用+-运算符,计算两数之和

Courier New字体,23磅行间距

a, b = 3, 4

max1 = 1023

 

 

def int_overflow(val):

    if not -max1 - 1 <= val <= max1:

        val = (val + (max1 + 1)) % (2 * (max1 + 1)) - max1 - 1

    return val

 

 

while b:

    a, b = int_overflow(a ^ b), int_overflow((a & b) << 1)

    print(a)




目录
相关文章
|
C# 数据库
C# DataGridView用法(—)代码绑定数据源
C# DataGridView用法(—)代码绑定数据源
695 1
|
8月前
|
安全 Linux 开发工具
零基础构建开源项目OpenIM桌面应用和pc web- Electron篇
OpenIM 为开发者提供开源即时通讯 SDK,作为 Twilio、Sendbird 等云服务的替代方案。借助 OpenIM,开发者可以构建安全可靠的即时通讯应用,如 WeChat、Zoom、Slack 等。 本仓库基于开源版 OpenIM SDK 开发,提供了一款基于 Electron 的即时通讯应用。您可以使用此应用程序作为 OpenIM SDK 的参考实现。本项目同时引用了 @openim/electron-client-sdk 和 @openim/wasm-client-sdk,分别为 Electron 版本和 Web 版本的 SDK,可以同时构建 PC Web 程序和桌面应用(Wi
497 2
R语言错误处理与调试:如何高效调试R代码
【8月更文挑战第28天】调试R代码是一项需要不断练习和提高的技能。通过理解常见的错误类型、使用`traceback()`查看错误路径、逐步执行代码、利用`tryCatch()`捕获和处理错误、设置更严格的警告级别、利用RStudio的调试工具以及编写可复现的示例,你可以更加高效地调试R代码,并快速解决遇到的问题。
计算机组成原理(6)-----指令执行过程
计算机组成原理(6)-----指令执行过程
882 0
|
XML 设计模式 安全
【Spring框架四】——Spring AOP 注解实现和xml方式实现1
【Spring框架四】——Spring AOP 注解实现和xml方式实现
237 0
|
C# Windows
C# 串口关闭时主界面卡死原因分析
串口程序关闭导致界面卡死的原因是主线程与辅助线程间的死锁。问题出在`SerialPort.Close()`方法与`DataReceived`事件处理程序。`DataReceived`事件在`lock (stream)`块中执行,而`Close()`方法会关闭`SerialStream`并锁定自身。当辅助线程处理数据并尝试更新UI时,UI线程因调用`Close()`被阻塞,造成死锁。解决办法是让`DataReceived`事件处理程序使用`this.BeginInvoke()`异步更新界面,避免等待UI线程,从而防止死锁。
|
存储 数据可视化 NoSQL
Qt Creator的CDB调试器--使用技巧与解决调试很慢的心得,重点是Symbols Path设置
Qt Creator的CDB调试器--使用技巧与解决调试很慢的心得,重点是Symbols Path设置
3429 0
Qt Creator的CDB调试器--使用技巧与解决调试很慢的心得,重点是Symbols Path设置
|
存储 数据采集 运维
带你读《基于数据资产全生命周期估值与实践报告》——2. 数据资产价值评估的核心因子说明(1)
带你读《基于数据资产全生命周期估值与实践报告》——2. 数据资产价值评估的核心因子说明
385 0
|
存储 编译器 C++
内存对齐计算方法(偏移量)
内存对齐简单来讲就是把一个数据存放到内存中,其内存的地址要与数据自己大小为整数倍。 处理器在执行指令去操作内存中的数据,这些数据通过地址来获取。 当一个数据所在的地址和它的大小对齐的时候,就说这个数据对齐了,否则就是没对齐。
378 1