当使用按位运算符时,意味着什么是真实的条件

在js代码的端口上,我在使用按位操作时面临困难。

有一个如果条件,我不知道我完全理解。

我不明白的条件是

if (byteUnderConsideration & Math.pow(2, (7 - bitIndexWithinByte))) return node.right 

我不知道在那种情况下什么时候会是真的。

完整的原始代码是,

 KBucket.prototype._determineNode = function (node, id, bitIndex) { // **NOTE** remember that id is a Buffer and has granularity of // bytes (8 bits), whereas the bitIndex is the _bit_ index (not byte) // id's that are too short are put in low bucket (1 byte = 8 bits) // parseInt(bitIndex / 8) finds how many bytes the bitIndex describes // bitIndex % 8 checks if we have extra bits beyond byte multiples // if number of bytes is <= no. of bytes described by bitIndex and there // are extra bits to consider, this means id has less bits than what // bitIndex describes, id therefore is too short, and will be put in low // bucket var bytesDescribedByBitIndex = ~~(bitIndex / 8) var bitIndexWithinByte = bitIndex % 8 if ((id.length <= bytesDescribedByBitIndex) && (bitIndexWithinByte !== 0)) return node.left var byteUnderConsideration = id[bytesDescribedByBitIndex] // byteUnderConsideration is an integer from 0 to 255 represented by 8 bits // where 255 is 11111111 and 0 is 00000000 // in order to find out whether the bit at bitIndexWithinByte is set // we construct Math.pow(2, (7 - bitIndexWithinByte)) which will consist // of all bits being 0, with only one bit set to 1 // for example, if bitIndexWithinByte is 3, we will construct 00010000 by // Math.pow(2, (7 - 3)) -> Math.pow(2, 4) -> 16 if (byteUnderConsideration & Math.pow(2, (7 - bitIndexWithinByte))) return node.right return node.left } 

移植的代码是,

 func (K *KBucket) determineNode(node *KBucketNode, id []byte, bitIndex int) *KBucketNode { if len(id) < 20 { panic(fmt.Errorf("id length must be 20, got %v", id)) } // **NOTE** remember that id is a Buffer and has granularity of // bytes (8 bits), whereas the bitIndex is the _bit_ index (not byte) // id's that are too short are put in low bucket (1 byte = 8 bits) // parseInt(bitIndex / 8) finds how many bytes the bitIndex describes // bitIndex % 8 checks if we have extra bits beyond byte multiples // if number of bytes is <= no. of bytes described by bitIndex and there // are extra bits to consider, this means id has less bits than what // bitIndex describes, id therefore is too short, and will be put in low // bucket bytesDescribedByBitIndex := int(math.Floor(float64(bitIndex) / 8)) bitIndexWithinByte := float64(bitIndex % 8) if len(id) <= bytesDescribedByBitIndex && bitIndexWithinByte != 0 { return node.left } byteUnderConsideration := id[bytesDescribedByBitIndex] // byteUnderConsideration is an integer from 0 to 255 represented by 8 bits // where 255 is 11111111 and 0 is 00000000 // in order to find out whether the bit at bitIndexWithinByte is set // we construct Math.pow(2, (7 - bitIndexWithinByte)) which will consist // of all bits being 0, with only one bit set to 1 // for example, if bitIndexWithinByte is 3, we will construct 00010000 by // Math.pow(2, (7 - 3)) -> Math.pow(2, 4) -> 16 y := int(byteUnderConsideration) & int(math.Pow(2, (7-bitIndexWithinByte))) if y > 0 { return node.right } return node.left } 

我通常不会进行这种计算,这一切都是不清楚的,我也没有正确地确定正确的打印方式,开始理解逻辑。

谢谢!

首先,如果你正在努力而不是:

 x * 8 x / 8 

也许这样做:

 x << 3 x >> 3 

这将使意图更清楚。

另外,使用它也没什么意义:

 byteUnderConsideration & Math.pow(2, (7 - bitIndexWithinByte)) 

当你能做到的时候:

 byteUnderConsideration & (1 << (7 - bitIndexWithinByte)) 

这将更加清晰(甚至不会提到它会更有效率)。

<<运算符向左移位, >>向右移位。

&运算符AND位于同一位置和| 操作符ORs位。

你应该花一些时间,阅读JavaScript中的按位运算符(与C中的工作方式几乎相同),因为你制作了许多奇怪的构造:

 ~~(x / 8) 

这可以是:

 x >> 3 

和(否定做两次)将不需要,因为你已经有一个整数。 除此之外,即使在你需要强制转换为一个整数的情况下,而不是做~~x你可能会更好的做x|0看看这个组合运算符~~|0之间的区别: