0

我想了解使用按位和/或在BigInt时发生的以下行为。目标是结合两个Long值来获得“128位BigInt”。scala.math.BigInt使用按位运算时的局限性?

首先,让我们创建两个Long值:

val uuid = java.util.UUID.fromString("6fcb514b-b878-4c9d-95b7-8dc3a7ce6fd8") 
val msb = BigInt(uuid.getMostSignificantBits) 
// => 8055621744141552797 
val lsb = BigInt(uuid.getLeastSignificantBits) 
// => -7658496769846775848 

(该UUID不用于任何其他目的不是提供可再生的两个Long值,因此可以忽略它)。

这个想法是在将它与lsb合并成64位之后使用按位或。

val result = (msb << 64) | lsb 

然而,结果等于lsb本身。换句话说,((msb << 64) | lsb) == lsbtrue。除此之外,((msb << 64) & lsb) == (msb << 64)也是true

这是为什么?

编辑:

的位移位似乎工作的msb << 64中介结果有127个二进制数字(可能是一个前导零)。

+0

负值的符号位正在结转。所有这些前导位在“或”在一起时消除移位的值。它应该使用2个正面的“长”值。 – jwvh

+0

当然,谢谢。由于某些原因,我虽然负数的前导1不会超过64位。 – fxlae

回答

1

这里有一种方法可能会让你知道你在做什么。

import java.nio.ByteBuffer 

val uuid = java.util.UUID.fromString("6fcb514b-b878-4c9d-95b7-8dc3a7ce6fd8") 

val bb = ByteBuffer.allocate(16) 
bb.putLong(uuid.getMostSignificantBits) 
bb.putLong(uuid.getLeastSignificantBits) 

val result: BigInt = bb.array.foldLeft(BigInt(0))((bi,b) => (bi << 8)|(0xFF & b)) 
// result = 148599992668788990968304946804723445720 

// proof it works 
println(f"$result%x") // 6fcb514bb8784c9d95b78dc3a7ce6fd8 
+0

谢谢,这是有效的。但是由于无论如何我们都需要'ByteBuffer'和'Array [Byte]',所以也可以只执行'BigInt(bb.array)'' – fxlae