You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中Long与字节数组互转异常:Double还原值偏差排查

问题:Double转字节数组后还原值不一致

近期尝试将包含若干基本类型变量的类对象转换为字节数组时,遇到一个问题:将Double保存为8字节格式后,还原得到的值与原数值接近但不完全一致。

测试过表达式 val value = Double.fromBits(1.2.toBits()),结果完全正确,因此推测问题出在自己实现的Long与字节数组互转逻辑中,但无法定位具体bug。

以下是相关实现代码:

写入字节数组(Long转ByteArray)

fun from(value : Long) : ByteArray{
    val byteArray = ByteArray(Long.SIZE_BYTES)
    var index = 0
    var shift = 8 * Long.SIZE_BYTES

     while(index < Long.SIZE_BYTES){
        shift -= 8
        byteArray[index] = value.shr(shift).and(0xFFL).toByte()
        index++
     }

     return byteArray
}

从字节数组读取(ByteArray转Long)

fun read(byteArray: ByteArray) : Long{
    var value = 0L
    var index = 0

    while(index < Long.SIZE_BYTES){
        value = value.shl(8) + byteArray[index].toLong()
        index++
    }

    return value
}

问题定位与修复

问题出在read方法中的byteArray[index].toLong():Kotlin的Byte是有符号类型(取值范围-128~127),当字节的原始值大于127时,toLong()会进行符号扩展,将其转换为负数的Long值,导致最终计算出的Long数值错误,进而还原Double时出现精度偏差。

修复后的read方法只需对字节转Long的结果做无符号掩码处理:

fun read(byteArray: ByteArray) : Long{
    var value = 0L
    var index = 0

    while(index < Long.SIZE_BYTES){
        value = value.shl(8) + byteArray[index].toLong().and(0xFFL)
        index++
    }

    return value
}

修复后,Long与字节数组的互转可以完全准确对应,Double还原后的值也会和原数值完全一致。

内容的提问来源于stack exchange,提问作者Giebut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 22:57:25