位操作-使用逐位操作时的scala.math.BigInt限制



我正在尝试理解在使用位和/或BigInt时发生的以下行为。目标是将两个Long值组合起来,得到一个"128位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值外,没有任何其他用途,因此您可以忽略它)。

其思想是在使用逐位或将msblsb合并之前左移64位。

val result = (msb << 64) | lsb

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

为什么?

编辑:

比特移位似乎起作用,msb << 64的中间结果有127个二进制数字(可能是前导零)。

这里有一种方法可以让您获得想要的东西。

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

最新更新