Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用LUA解码UDP消息_Lua_Floating Point_Coronasdk_Floating Point Conversion_Lua 5.1 - Fatal编程技术网

用LUA解码UDP消息

用LUA解码UDP消息,lua,floating-point,coronasdk,floating-point-conversion,lua-5.1,Lua,Floating Point,Coronasdk,Floating Point Conversion,Lua 5.1,我对lua和编程都是比较新的(自学),所以请温柔一点 无论如何,我写了一个lua脚本来读取游戏中的UDP消息。该信息的结构如下: DATAxXXXXaaaaBBBBccccDDDDeeeeFFFFggggHHHH DATAx = 4 letter ID and x = control character XXXX = integer shows the group of the data (groups are known) aaaa...HHHHH = 8 single-precision f

我对lua和编程都是比较新的(自学),所以请温柔一点

无论如何,我写了一个lua脚本来读取游戏中的UDP消息。该信息的结构如下:

DATAxXXXXaaaaBBBBccccDDDDeeeeFFFFggggHHHH
DATAx = 4 letter ID and x = control character
XXXX = integer shows the group of the data (groups are known)
aaaa...HHHHH = 8 single-precision floating point numbers
最后一个是我需要解码的数字

如果我将收到的消息打印出来,它类似于:

DATA*{V???A?A?...etc.
使用string.byte(),我得到了如下字节流(我已经“格式化”了字节以反映上述结构)

68 65 84 65/42/20 0 0 0/237 222 28 66/189 59 182 65/107 42 41 65/33 173 79 63/0 0 128 63/146 41 41 65/0 0 30 66/0 0 184 65
前5个字节当然是数据*。下4个字节是第20组数据。下一个字节,我需要解码的字节,等于这些值:

237 222 28 66 = 39.218
189 59 182 65 = 22.779
107 42 41 65 = 10.573
33 173 79 63 = 0.8114
0 0 128 63 = 1.0000
146 41 41 65 = 10.573
0 0 30 66 = 39.500
0 0 184 65 = 23.000
我找到了用BitConverter.ToSingle()进行解码的C#代码,但我还没有找到类似于Lua的代码。
有什么想法吗?

这是IEEE-754单精度二进制文件的小端字节顺序:

例如,
0 0 128 63
是:

00111111 10000000 00000000 00000000 (63)(128)(0)(0)

为什么等于
1
要求您了解IEEE-754表示法的基本原理,即指数和尾数的使用。请参阅开始


有关如何在Lua 5.3中使用
string.unpack()
,以及可以在早期版本中使用的一个可能实现,请参见上面@Egor的答案。

您有什么Lua版本?
此代码适用于Lua 5.3

local str = "DATA*\20\0\0\0\237\222\28\66\189\59\182\65..."
-- Read two float values starting from position 10 in the string
print(string.unpack("<ff", str, 10))  -->  39.217700958252  22.779169082642 18
-- 18 (third returned value) is the next position in the string

在使用
string.byte()
之前,您能否给出一个您收到的完整消息的示例?下面是一个使用print()的示例。DATA*{V???a?a???:?y?g(???%a???):不是上面的内容,而是类似的内容。您是如何确定上面字节数组的值的(例如,
0 0 128 63=1.0000
?游戏是X-Plane飞行模拟器,这些值可以在游戏中显示。下面是一个示例。它们是飞机的位置(坐标、高度等)非常感谢@Brian。这正是我需要的,一个方向。我知道我需要为此编写一些代码,但这很好。非常感谢@Egor!直接解压收到的消息,与Lua 5.3配合使用很好。但是,我计划将其用于使用Corona SDK的移动应用程序,该应用程序使用Lua 5.1.3。我会看看我能做些什么。非常感谢@Egor!我欠你一杯啤酒!谢谢@Egor-我很高兴我在下面错了!这迫使我深入研究
字符串。打开
文档。我会在你的回答中添加对第一个参数的解释,字符串格式,其中

local function binary_to_float(str, pos)
   local b1, b2, b3, b4 = str:byte(pos, pos+3)
   local sign = b4 > 0x7F and -1 or 1
   local expo = (b4 % 0x80) * 2 + math.floor(b3 / 0x80)
   local mant = ((b3 % 0x80) * 0x100 + b2) * 0x100 + b1
   local n
   if mant + expo == 0 then
      n = sign * 0.0
   elseif expo == 0xFF then
      n = (mant == 0 and sign or 0) / 0
   else
      n = sign * (1 + mant / 0x800000) * 2.0^(expo - 0x7F)
   end
   return n
end


local str = "DATA*\20\0\0\0\237\222\28\66\189\59\182\65..."
print(binary_to_float(str, 10))  --> 39.217700958252
print(binary_to_float(str, 14))  --> 22.779169082642