Я пишу программу, которая должна сериализовать небольшие (до 16 бит) целые числа со знаком в двоичный файл. Как часть этого, мне нужно написать функцию, которая может разделить целое на два байта и другую функцию, которая может преобразовать эту пару байтов обратно в исходное целое число.Как преобразовать пару байтов в 16-битное целое число с использованием Lua?
Первая мысль, которая пришла мне на ум, чтобы решить эту проблему так же, как я бы решить это 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 бита и I я только сохранение нижних 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], поэтому он всегда будет терпеть неудачу в ваших утверждениях. – Moop
Вы сказали, что 'read_i16 (dump_i16 (-20) == 65516' и' 65516 == 2^16 -20'. Почему бы вам просто не вычесть «2^16» из результата ...? – siffiejoe
@Moop: Вы правы. Я должен был протестировать, прежде чем редактировать тех, кто находится посреди ночи ... – hugomg