scala.math.BigInt 使用按位运算时的限制?
scala.math.BigInt limitations when using bitwise operations?
我试图理解在 BigInt
上使用按位 and/or 时发生的以下行为。目标是组合两个 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
值外没有任何其他用途,所以你可以忽略它)。
想法是左移 msb
64 位,然后使用按位或将其与 lsb
合并。
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
我试图理解在 BigInt
上使用按位 and/or 时发生的以下行为。目标是组合两个 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
值外没有任何其他用途,所以你可以忽略它)。
想法是左移 msb
64 位,然后使用按位或将其与 lsb
合并。
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