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

将long类型转换为byte数组用于高效传输时的代码问题

4字节存储long值的序列化代码错误分析

我正在创建一种序列化格式,头部使用4个固定字节存储消息体长度,希望用这4个字节存储尽可能大的数值,需要将long类型存入byte[](采用base256编码方式)。以下是我的代码:

long val = 25484394;
var encoded = new byte[4];

var max = 0L;

for (var i = 0; i < encoded.Length; ++i)
{
    max += (long)Math.Pow((int)byte.MaxValue, i);
}

if (val >= max)
    throw new ArgumentOutOfRangeException("value", $"{val} is too large to be encoded (max value is {max})");
    
for (var i = encoded.Length - 1; i > 0; i--)
{
    //This line is wrong
    encoded[i] = (byte)(int)Math.Floor(val / Math.Pow(byte.MaxValue, i));
}

这段代码存在以下关键错误:

  • 最大值计算错误:
    byte.MaxValue是255,4字节无符号整数能存储的最大值应为2^32 - 1(即4294967295),因为每个字节可表示0-255的数值,4字节组合范围是0到0xFFFFFFFF。但当前代码通过累加255^i计算max,得到的结果仅为1 + 255 + 255² + 255³ = 16581375,远小于实际可存储的最大值,会导致大量合法数值被误判为超出范围。

  • 循环遗漏关键字节:
    编码循环的条件是i > 0,仅处理了索引3、2、1的字节,完全漏掉了索引0的字节,最终encoded[0]会保持默认值0,导致原始数值的部分信息丢失,解码时无法还原正确值。

  • 编码逻辑的精度与逻辑错误:

    1. 使用Math.Pow进行浮点数运算会引入精度误差,当数值较大时,浮点数精度损失会导致计算结果不准确,进而造成编码后的字节值错误。
    2. 每次计算都使用原始的val值,没有在提取当前字节后更新val,导致所有字节都基于原始值计算,完全不符合base256编码的逻辑——正确逻辑应该是提取当前字节后,将val更新为剩余的数值。

修正示例(大端模式)

推荐用整数位运算替代浮点数运算,避免精度问题,同时覆盖所有字节:

long val = 25484394;
var encoded = new byte[4];
const long maxValue = 0xFFFFFFFFL;

if (val < 0 || val > maxValue)
    throw new ArgumentOutOfRangeException("value", $"{val} is out of range (max is {maxValue})");

encoded[0] = (byte)(val >> 24);
encoded[1] = (byte)(val >> 16);
encoded[2] = (byte)(val >> 8);
encoded[3] = (byte)val;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:47:25