【发布时间】:2016-09-28 23:47:06
【问题描述】:
我正在构建由两个 Longs 组成的 BigInt 数字,每个数字如下:
val msb = -1L // some arbitrary long value, can be anything between Long.Min/MaxValue
val lsb = 25L // a second arbitrary long value
val bb = ByteBuffer
.allocate(17)
.put(0.toByte) // 1 byte
.putLong(msb) // 8 bytes
.putLong(lsb) // 8 bytes
val number = BigInt(bb.array) // in this case: 340282366920938463444927863358058659865
我在前面添加另一个 0-Byte 的原因是为了保证结果是一个正数。否则,由于二进制补码,生成的 BigInt 可能为负数。之后调用的算法期望数字大于或等于零。
到目前为止,一切都很好。
我在反转整个过程时遇到了麻烦 - 将 BigInt 转换回两个 Longs(正是用作输入的两个值)。我不能只做以下事情:
val arr = number.toByteArray
val bb = ByteBuffer.wrap(arr)
val ignore = bb.getByte
val msb = bb.getLong
val lsb = bb.getLong
想象BigInt 数字是例如3. 那么.toByteArray 将产生一个大小为 1,而不是 16(或 17)的数组,因此对 getLong 的调用将导致 BufferUnderflowException。
解决这个问题最简单的方法是什么?我尝试了几种手动填充缓冲区的方法,直到有 16 个字节可用,但由于这个“填充”必须正确考虑两个数字的二进制补码,所以我没有成功。
【问题讨论】:
-
您是否要编写类似 BigDecimal 的代码?
-
请原谅我的无知,不知道 scala,但我怀疑
bb.getByte.getLong是否有效。bb.getByte不返回0,导致0.getLong? -
@Andreas 你完全正确,我写这篇文章的时候已经很晚了
标签: java arrays scala bytebuffer