Lua 5.1.5版本中如何将字节转换为有符号整数
Lua 5.1.5 字节转有符号整数兼容方案
问题背景
目前公开的字节转有符号整数实现大多依赖Lua 5.2及以上版本新增特性(如内置位运算、string.unpack接口等),无向下兼容能力,无法在Lua 5.1.5环境运行。已知无符号整数转换参考代码如下:
payload_t.temperature=tonumber(utility.hex2str(string.sub(payload,32,33)),16)
实现原理
有符号整数在字节流中以补码形式存储,转换核心逻辑为:
- 先按已有逻辑完成字节到无符号整数的转换
- 判断无符号值是否超过对应位宽有符号整数的正数上限(即最高符号位是否为1)
- 若符号位为1,将无符号值减去2的位宽次幂,即可得到对应的负向有符号值;若符号位为0,直接返回无符号值即可
该逻辑全程使用Lua 5.1原生支持的数值运算语法,无版本兼容问题,不需要引入第三方依赖。
可直接复用的代码
通用转换函数
-- @param unsigned_val: 转换得到的无符号整数值 -- @param bit_width: 目标有符号整数的位宽,常用值为8/16/32 -- @return 补码转换后的有符号整数 function to_signed(unsigned_val, bit_width) local sign_threshold = 2 ^ (bit_width - 1) if unsigned_val >= sign_threshold then return unsigned_val - 2 ^ bit_width end return unsigned_val end
适配现有业务的调用示例
以当前读取2字节(16位)温度值的场景为例,直接在原有无符号转换逻辑后追加调用即可:
-- 原有逻辑取16位无符号值 local temp_unsigned = tonumber(utility.hex2str(string.sub(payload,32,33)),16) -- 转换为16位有符号整数 payload_t.temperature = to_signed(temp_unsigned, 16)
常用位宽参数参考
- 单字节8位有符号整数:位宽参数传
8,取值范围-128~127 - 双字节16位有符号整数:位宽参数传
16,取值范围-32768~32767,为多数传感器温度、电流等模拟量的通用存储格式 - 四字节32位有符号整数:位宽参数传
32,取值范围-2147483648~2147483647
注意:如果待转换字节为小端序,需要先调整字节顺序再计算无符号值,上述补码转换逻辑不受字节序影响。
内容的提问来源于stack exchange,提问作者cMod
相关产品推荐
相关产品推荐

