【发布时间】:2016-12-03 02:13:34
【问题描述】:
我正在编写一个程序,该程序需要将小(最多 16 位)有符号整数序列化为二进制文件。作为其中的一部分,我需要编写一个可以将整数拆分为两个字节的函数,以及另一个可以将这对字节转换回原始整数的函数。
我想到的第一个想法是解决这个问题,就像我如何解决它 C:
function dump_i16(n)
assert (-0x8000 <= n and n < 0x8000) -- 16 bit
local b1 = (n >> 8) & 0xff
local b2 = (n >> 0) & 0xff
return b1, b2
end
function read_i16(b1, b2)
assert (0 <= b1 and b1 <= 0xff) -- 8 bit
assert (0 <= b2 and b2 <= 0xff) -- 8 bit
return (b1 << 8) | (b2 << 0)
end
但是,这些函数会在负数上中断,因为 Lua 整数实际上有 64 位,而我只保留低 16 位:
-- Positive numbers are OK
print( read_i16(dump_i16(17)) ) -- 17
print( read_i16(dump_i16(42)) ) -- 42
-- Negative numbers don't round trip.
print( read_i16(dump_i16(-1)) ) -- 65535 = 2^16 - 1
print( read_i16(dump_i16(-20)) ) -- 65516 = 2^16 - 20
修改我的 read_i16 函数使其对负数正常工作的最简洁方法是什么?
如果可能的话,我宁愿使用纯 Lua 5.3 来完成这项工作,而无需编写 C 代码。
【问题讨论】:
-
您的 dump_i16 正在生成无符号值 [0,256),因此您的断言总是会失败
-
你说过
read_i16(dump_i16(-20) == 65516和65516 == 2^16 -20。为什么不直接从结果中减去2^16...? -
@Moop:你是对的。我应该在半夜编辑之前测试一下……
标签: lua bit-manipulation