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];
问题根源
- 数组越界:原转回代码里用了
buf[4],但buf数组只有4个元素(下标范围0-3),越界访问会读取到随机值或0,直接导致结果错误。 - 拆分时运算顺序错误:拆分long到字节数组时,
(byte) n >> 8是先把n转成byte(仅保留低8位),再右移8位,结果必然是0。正确顺序应该是先对long类型的n执行移位操作,再转成byte,这样才能拿到对应高位的字节。 - 转回时符号扩展陷阱:在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
相关产品推荐
相关产品推荐

