Javascript 什么是a^b和(a&b)<&书信电报;1.
我在leetcode做这个 请求: 计算两个整数a和b的和,但不允许使用运算符+和- 我无法理解它给出的解决方案 有人能解释一下这个函数是如何工作的吗 以下是JS中的答案:Javascript 什么是a^b和(a&b)<&书信电报;1.,javascript,bitwise-operators,Javascript,Bitwise Operators,我在leetcode做这个 请求: 计算两个整数a和b的和,但不允许使用运算符+和- 我无法理解它给出的解决方案 有人能解释一下这个函数是如何工作的吗 以下是JS中的答案: var getSum=函数(a,b){ const Sum=a^b;//我不明白这两行代码是如何工作的 const carry=(a&b)让我们通过示例学习。想象一下a=3和b=5 在二进制表示法中,它们是a=0011和b=0101 异或: a^b是异或运算符。当比较两个位时,如果它们相同,则返回0;如果它们不同,则返回1
var getSum=函数(a,b){
const Sum=a^b;//我不明白这两行代码是如何工作的
const carry=(a&b)让我们通过示例学习。想象一下a=3
和b=5
在二进制表示法中,它们是a=0011
和b=0101
异或:
a^b
是异或运算符。当比较两个位时,如果它们相同,则返回0
;如果它们不同,则返回1
。01^10=>11
所以当我们做a^b
时,结果将是0110
和+SHIFT
a&b
执行逻辑与运算。仅当a=b=1
时,它才会返回1
在我们的例子中,结果是0001
所以,XORing的结果是(0011),它实际上是十进制的3。然后我们得到p和q的和
0101
0110
-------
0100
我们通过与5和6求和得到4(二进制中为100),现在如果我们将这个值左移1,我们得到
0100<<1=1000
所以,做我们得到的第一个XORing
0011
1000
-------
1011
这次的XORing生成了11(1011二进制),所以我们现在执行
0011
1000
-------
0000
对于和3和8,我们得到了所有的零,所以这次左移位运算符也得到了零,因为这里没有1,它可能通过左移位零给我们一个值。
由于进位变量现在为零,我们到了递归的末尾,XORed值将是和,即11(二进制中的1011)
希望你能理解这个过程。通过学习按位运算,你可以学到更多,因为这是机器进行算术运算的方式。它基本上是在复制
添加2位A和B产生2个输出:一个和和和一个进位,如下所示
╔═══════╤═════════════╗
║ Input │ Output ║
╠═══╤═══╪═══════╤═════╣
║ A │ B │ carry │ sum ║
╟───┼───┼───────┼─────╢
║ 0 │ 0 │ 0 │ 0 ║
╟───┼───┼───────┼─────╢
║ 1 │ 0 │ 0 │ 1 ║
╟───┼───┼───────┼─────╢
║ 0 │ 1 │ 0 │ 1 ║
╟───┼───┼───────┼─────╢
║ 1 │ 1 │ 1 │ 0 ║
╚═══╧═══╧═══════╧═════╝
从表中我们得到了输出的逻辑:进位=A和B,和=A或B
也称为无进位加法运算符,由⊕ 带有+
符号
所以上面的代码片段是这样工作的
const Sum=a^b; // sum = a xor b = a ⊕ b
const carry=(a&b)<<1; // carry = 2*(a and b), since we carry to the next bit
if(!carry){
return Sum; // no carry, so sum + carry = sum
}
return getSum(Sum,carry); // a + b = sum + carry
const Sum=a^b;//Sum=a异或b=a⊕ B
const carry=(a&b)^
是异或,一种按位操作。在单个位上,规则是0^0=0
,0^1=1
,1^0=0
,处理多位值时,只需在相应位上扩展执行它。名称是“异或”的缩写,这是因为A^B
是1
当且仅当A或B都是1
,而不是两者都是。但是,谈论它的另一个名字更有趣,⊕. ⊕ 是+但略有不同。您会注意到⊕ 与添加规则类似:0+0=0
、0+1=1
、1+0=1
和1+1=10
。⊕ 为+,但1除外⊕ 1=0
;即,⊕ 是+,除了没有携带。这适用于多个位:011+001=100
,因为您将1
从1位携带到2位,然后将1
再次携带到4位。然后,011⊕ 001=010
,因为你就是不带
现在,当进行实加法时,什么时候进行?在二进制中,答案很简单:当给定位置有两个1
时,将1
带到下一个位置。这很容易理解为按位AND,&
1&1=1
,否则为0
。对于011+001
,加法而不使用携带011⊕ 001=010
,我们可以知道我们需要把1
带出这个位置,因为011&001=001
。在中的移位(a&b)如果我没有弄错的话,更准确的说法是它复制了全加器,因为函数对自身的递归调用——一个xor加号和一个阶段通向另一个阶段。@Sergiykoldyazhnyy这里的输入只有a和b,这是半加器。全加器的功能是通过递归调用实现的,它给你a+b+2*carry
。一个真正的全加器需要3个输入A+b+carryIn=sum+2*carryOut
可能值得指出的是,它是一个每一位同时进行的半加器,不像真值表只显示一个位的位置。请编辑您的问题以澄清您对这些行不了解的原因。您不熟悉w吗关于@Ilmari Karonen的^
、&
和可能的重复项,好吧……我将编辑这个问题。这似乎只是讨论特定情况,而不是算法的一般工作原理。我们如何从中知道它适用于所有可能的输入?@ilkkachu您可以尝试不同的输入值,它可能适用于不同的输入我的目标是通过例子来解释算法。
0011
1000
-------
0000
╔═══════╤═════════════╗
║ Input │ Output ║
╠═══╤═══╪═══════╤═════╣
║ A │ B │ carry │ sum ║
╟───┼───┼───────┼─────╢
║ 0 │ 0 │ 0 │ 0 ║
╟───┼───┼───────┼─────╢
║ 1 │ 0 │ 0 │ 1 ║
╟───┼───┼───────┼─────╢
║ 0 │ 1 │ 0 │ 1 ║
╟───┼───┼───────┼─────╢
║ 1 │ 1 │ 1 │ 0 ║
╚═══╧═══╧═══════╧═════╝
const Sum=a^b; // sum = a xor b = a ⊕ b
const carry=(a&b)<<1; // carry = 2*(a and b), since we carry to the next bit
if(!carry){
return Sum; // no carry, so sum + carry = sum
}
return getSum(Sum,carry); // a + b = sum + carry