67 lines
2.2 KiB
JavaScript
67 lines
2.2 KiB
JavaScript
/* leetcode 371
|
||
给你两个整数 a 和 b ,不使用 运算符 + 和 - 计算并返回两整数之和。
|
||
|
||
示例 1:
|
||
|
||
输入:a = 1, b = 2
|
||
输出:3
|
||
示例 2:
|
||
|
||
输入:a = 2, b = 3
|
||
输出:5
|
||
|
||
提示:
|
||
|
||
-1000 <= a, b <= 1000
|
||
*/
|
||
|
||
/*
|
||
在计算机中,反码、补码和原码是用来表示整数的不同编码方式:
|
||
|
||
原码:即数字的真实表现形式,也就是它的符号位加上其二进制表示形式。正数的原码与其二进制表示形式相同,负数的原码最高位为1,其余位为其绝对值的二进制表示形式。
|
||
|
||
反码:负数的反码是其原码除符号位外各位取反(0变1,1变0)得到的结果。正数的反码与其原码相同。
|
||
|
||
补码:负数的补码是其反码加1得到的结果。正数的补码与其原码相同。
|
||
|
||
举个例子:
|
||
|
||
原码:+5 的原码是 00000101,-5 的原码是 10000101。
|
||
反码:+5 的反码与其原码相同,即 00000101,-5 的反码是 11111010。
|
||
补码:+5 的补码与其原码相同,即 00000101,-5 的补码是其反码加1得到的结果,即 11111011。
|
||
*/
|
||
|
||
const getSum = (a, b) => {
|
||
while (b !== 0) {
|
||
const carry = (a & b) << 1;
|
||
a ^= b;
|
||
b = carry;
|
||
}
|
||
return a;
|
||
};
|
||
|
||
const getSum2 = (a, b) => {
|
||
if (b === 0) return a; // 如果进位结果为0就结束递归
|
||
const carry = (a & b) << 1;
|
||
const c = a ^ b;
|
||
getSum2(c, carry);
|
||
return '';
|
||
};
|
||
|
||
/**
|
||
思考:
|
||
为什么这样就能实现加法运算,我们在小学的时候做加法运算的时候会列竖式,如果是没有进位的加法我们可以
|
||
很快的做出来,比如说123+123,想都不要想就知道是246,但是如果结果里面有进位那么就不能一眼看出来,比如
|
||
说 456+645 ,这个结果一眼是看不出来的,经过计算我们可以知道,他的结果是1101,首先我们从个位开始加6+5
|
||
等于1向前面进一位,之后再5+4+1得到结果10,向前进一位,之后4+6+1得到结果11🔎进一位,这里面我们总共进了
|
||
三次位,所以只要把把没进位的数和进位的数相加得到的结果不就是结果吗?
|
||
|
||
4 5 6 4 5 6
|
||
6 4 5 6 4 5
|
||
-------- ---------
|
||
0 9 1 1 1 1 1
|
||
*/
|
||
|
||
console.log(getSum(1, 0));
|
||
console.log(getSum2(2, 0));
|