【每天学习一点算法 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)

相关推荐
Je1lyfish9 分钟前
CMU15-445 (2025 Fall/2026 Spring) Project#3 - QueryExecution
linux·c语言·开发语言·数据结构·数据库·c++·算法
许彰午11 分钟前
03-二叉树——从递归遍历到非递归实现
java·算法
Brilliantwxx24 分钟前
【C++】 vector(代码实现+坑点讲解)
开发语言·c++·笔记·算法
百锦再1 小时前
Auto.js变成基础知识学习
开发语言·javascript·学习·sqlite·kotlin·android studio·数据库开发
KuaCpp1 小时前
C++新特性学习
c++·学习
NorburyL2 小时前
DPO笔记
深度学习·算法
老纪的技术唠嗑局2 小时前
深度解析 LLM Wiki / Obsidian-Wiki / GBrain:Agent 时代知识的“自组织”与“自进化”
大数据·数据库·人工智能·算法
Komorebi_99994 小时前
大模型学习day5
学习·大模型
逍遥德4 小时前
AI时代,计算机专业大学生学习指南
java·javascript·人工智能·学习·ai编程
网络与设备以及操作系统学习使用者5 小时前
直连路由优先级最高
运维·网络·学习·华为·智能路由器