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

Arduino中long类型与4字节数组的互转异常问题

long与4字节数组互转的错误排查与修复

问题场景

我尝试实现long类型和4字节数组的互转,从论坛找的示例代码有问题:测试n=15000时,原代码返回0,修改转回逻辑后返回152,都得不到原数值,还得支持负数场景。

原代码:

long n;
byte buf[4];
buf[0] = (byte) n;
buf[1] = (byte) n >> 8;
buf[2] = (byte) n >> 16;
buf[3] = (byte) n >> 24;
long value = (unsigned long)(buf[4] << 24) | (buf[3] << 16) | (buf[2] << 8) | buf[1];

我修改后的转回代码:

long value = (unsigned long)(buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];

问题根源

  1. 数组越界:原转回代码里用了buf[4],但buf数组只有4个元素(下标范围0-3),越界访问会读取到随机值或0,直接导致结果错误。
  2. 拆分时运算顺序错误:拆分long到字节数组时,(byte) n >> 8是先把n转成byte(仅保留低8位),再右移8位,结果必然是0。正确顺序应该是先对long类型的n执行移位操作,再转成byte,这样才能拿到对应高位的字节。
  3. 转回时符号扩展陷阱:在Arduino环境中byte是有符号类型,如果直接对buf元素左移,当元素最高位为1(比如负数的高位字节),会触发符号扩展,高位补1导致最终结果出错。必须先把byte转成无符号类型再移位。

正确实现代码

1. long转4字节数组(小端序,与原代码意图一致)

long n = 15000; // 支持任意long值,包括负数
byte buf[4];

// 先移位再转byte,确保获取正确的字节段
buf[0] = (byte)(n);               // 低8位
buf[1] = (byte)(n >> 8);          // 次低8位
buf[2] = (byte)(n >> 16);         // 次高8位
buf[3] = (byte)(n >> 24);         // 高8位

2. 4字节数组转回long(支持正负场景)

// 每个buf元素先转为unsigned long再移位,避免符号扩展
long value = (long)(
    ((unsigned long)buf[3] << 24) |
    ((unsigned long)buf[2] << 16) |
    ((unsigned long)buf[1] << 8) |
    (unsigned long)buf[0]
);

验证效果

  • 测试n=15000:15000的十六进制为0x3A98,拆分后buf[0]=0x98、buf[1]=0x3A、buf[2]=0x00、buf[3]=0x00,转回后计算结果为0x3A98,即15000,与原数值一致。
  • 测试负数n=-1:十六进制为0xFFFFFFFF,拆分后每个buf元素均为0xFF,转回后得到0xFFFFFFFF,对应long类型的-1,结果正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:25:35