【每天学习一点算法 2026/04/15】两整数之和(附带位运算总结)

每天学习一点算法 2026/04/15

题目:两整数之和

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

不能使用 + - 运算符就只能使用位运算符了

顺便总结一下位运算符吧(不想看的可以直接跳到最后的解题处)

按位与(&)

按位与(&)运算符在两个操作数对应的二进位都为 1 时,该位的结果值才为 1(全为 1 才为 1,否则为 0)。

javascript 复制代码
const a = 5; // 00000000000000000000000000000101
const b = 3; // 00000000000000000000000000000011

console.log(a & b); // 00000000000000000000000000000001
// Expected output: 1
按位或(|)

按位或(|)运算符在其中一个或两个操作数对应的二进制位为 1 时,该位的结果值为 1(有一个为 1 就为 1,全为 0 才为 0)

javascript 复制代码
const a = 5; // 00000000000000000000000000000101
const b = 3; // 00000000000000000000000000000011

console.log(a | b); // 00000000000000000000000000000111
// Expected output: 7
按位异或(^)

按位异或(^)运算符在两个操作数有且仅有一个对应的二进制位为 1 时,该位的结果值为 1(相同为 0,不同为 1 )。

javascript 复制代码
const a = 5; // 00000000000000000000000000000101
const b = 3; // 00000000000000000000000000000011

console.log(a ^ b); // 00000000000000000000000000000110
// Expected output: 6

我们可以看出不考虑进位的话,这就跟二进制数加法是一样的操作。

按位非(~)

按位非运算符(~)将操作数的位反转。如同其他位运算符一样,它将操作数转化为 32 位的有符号整型。(0 变 1,1 变 0)

注意:负数在计算机内是补码存储的

typescript 复制代码
const a = 5; // 00000000000000000000000000000101
const b = -3; // 11111111111111111111111111111101

console.log(~a); // 11111111111111111111111111111010
// Expected output: -6

console.log(~b); // 00000000000000000000000000000010
// Expected output: 2
左移 (<<)

左移操作符 (<<) 将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零

typescript 复制代码
const a = 5; // 00000000000000000000000000000101
const b = 2; // 00000000000000000000000000000010

console.log(a << b); // 00000000000000000000000000010100
// Expected output: 20
右移(>>)

右移运算符(>>)将一个操作数的二进制表示形式向右移动指定位数,该操作数可以是数值或者 BigInt 类型。右边移出位被丢弃,左边移出的空位补符号位(最左边那位)。该操作也称为"符号位传播右移"(sign-propagating right shift)或"算术右移"(arithmetic right shift),因为返回值的符号位与第一个操作数的符号位相同。

javascript 复制代码
const a = 5; //  00000000000000000000000000000101
const b = 2; //  00000000000000000000000000000010
const c = -5; //  11111111111111111111111111111011

console.log(a >> b); //  00000000000000000000000000000001
// Expected output: 1

console.log(c >> b); //  11111111111111111111111111111110
// Expected output: -2
解题

然后我们回到这道题:

  1. 我们之前分析过,不考虑进位的话我们的 a ^ b 操作就跟加法操作的结果是一样的
  2. 我们又知道同为 1 的时候,会进一位,那我们用 a & b 操作得到结果就是每一位相加多出的需要进位 1 ,再执行左移操作就把 1 对应到了需要进位的位置上了
  3. 然后我们继续将第一步的结果和第二部的结果进行同样的操作,直到 a & b === 0 表示在屋进位,此时的 a ^ b 就是最终的结果
typescript 复制代码
function getSum(a: number, b: number): number {
  // 循环执行位操作
  while (b !== 0) {
    const sum = a ^ b // 得到不考虑进位的和结果
    const carry = (a & b) << 1 // 得到需要加上的进位
    // 重新赋值 a b , 循环操作
    a = sum
    b = carry
  }
  return a // 返回最终结果
};

题目来源:力扣(LeetCode)

相关推荐
Hello.Reader2 小时前
算法是什么
linux·运维·算法
风兮雨露2 小时前
2026年全国硕士研究生招生考试(附资源)
学习
Tisfy2 小时前
LeetCode 2515.到目标字符串的最短距离:从中间往两边遍历
算法·leetcode·字符串·题解·数组·遍历
Xpower 172 小时前
PHM算法学习 Day 3:深度卷积神经网络(CNN)故障诊断变体
学习·算法·cnn
im_AMBER2 小时前
学习 Redux Toolkit :从 Context 误区到 createSlice 实践
前端·javascript·学习·react.js·前端框架
有谁看见我的剑了?2 小时前
Linux 内存巨页与透明巨页学习
java·linux·学习
red_redemption2 小时前
自由学习记录(166)
学习
苯酸氨酰糖化物2 小时前
基于深度学习(U-Net架构下改良GAN与ViT算法)的高效肺部多模态疾病预测模型
人工智能·深度学习·算法·生成对抗网络·视觉检测
feng_you_ying_li2 小时前
异常,try catch ,throw的介绍与运用
算法