如何在没有外部库的任何lua中将双精度转换为小字符串表示而不会丢失数据?
Posted
技术标签:
【中文标题】如何在没有外部库的任何lua中将双精度转换为小字符串表示而不会丢失数据?【英文标题】:How to convert a double to a small string representation without data loss in any lua without external libs? 【发布时间】:2018-07-07 10:56:19 【问题描述】:我想仅使用任何 Lua 版本将数字转换为字符串,以便
没有数据丢失(必要!)
字符串表示尽可能小(8 字节就可以)(可选,不是必需的)没有使用外部库(必需!)
转换速度尽可能快(可选,非必需)我不在乎
人类可读性 避免特殊字符我尝试了内置的tonumber
函数,但它并不总是给出正确的结果:
> print((2+256^6)==(1+256^6))
false
> print(tostring(2+256^6)==tostring(1+256^6))
true
【问题讨论】:
根据定义,浮点数是有损的 - 如果您确实需要避免 任何 数据丢失,则不能一开始就使用浮点数。 lua 有一种数字数据类型 - 这些数字是双精度数 - 我希望能够序列化这些数据,以便能够序列化除用户数据和线程之外的任何内容... 有人可以发布完整的解决方案吗? SO 不是给出完整解决方案的地方 你从哪里得到的?我看到了许多像我这样的小问题的完整解决方案!我不认为序列化一个数字是一门大科学。此外,如果只有错误的答案,将它们嵌入程序的人会遇到严重的问题!他们尝试序列化一个 nan,想知道为什么在反序列化数据时会得到 nil! 【参考方案1】:如果您可以使用标准 Lua 库,请尝试以下方法:
x=math.pi
s=string.pack("d",x)
y=string.unpack("d",s)
print(x==y)
s=string.format("%a",x)
y=tonumber(s)
print(x==y)
string.format("%a",x)
在 Lua 5.2+ 中可用。 string.pack
在 Lua 5.3+ 中可用。
【讨论】:
似乎比 tostring 好!如何反序列化?任何lua版本都有string.format吗? 试过了:你不能使用 tonumber 反序列化 (-)nans 和 (-)infs,但其他任何一个都可以。 另外(lua-users.org/wiki/StringLibraryTutorial 关于 string.format)“选项 A, a 可能在 Lua 5.2 及更高版本中可用。” (它应该适用于任何 lua 版本),string.pack 根本不在我的 lua 中。 "string.format("%a",x) 在 Lua 5.2+ 中可用。string.pack 在 Lua 5.3+ 中可用。" - 没有解决问题。还支持 nans、infs 及其否定版本。【参考方案2】: -- Encoding/decoding without data loss
local NaN_serialized =
[string.format('%.17g', 1/0 )] = '1/0',
[string.format('%.17g', -1/0 )] = '-1/0',
[string.format('%.17g', 0/0 )] = '0/0',
[string.format('%.17g', -(0/0))] = '-(0/0)'
-- How to encode:
str_value = string.format('%.17g', num_value):gsub('^.*', NaN_serialized):gsub(',', '.')
-- How_to_decode:
num_value = loadstring("return "..str_value)()
【讨论】:
似乎可以工作(至少在我目前使用的 lua 上)。 pro:非常非常短的解决方案,kontra:字符串表示非常大。【参考方案3】:这包括一个 number_to_str 和一个 number_from_str 函数:
https://github.com/bakpakin/binser/blob/master/binser.lua
显然,它们的能力超过了 Lua 的内置 tonumber...
【讨论】:
print(number_from_str(number_to_str(-(0/0)),1) == -(0/0)) 给出错误。这并没有保存 nan 和 -nan 之间的区别,而且,这是相当多的代码。如果你将它分叉并制作一个可以工作的版本,那就没问题了。 如果不处理NaN,你可以自己轻松添加。 是的,但我不想检查代码页是否有进一步的错误,如果你这样做了,但你没有发现你的解决方案是好的。 我没有时间这样做 至于你的(-0/0)==(-0/0)
测试,没有“minus nan”***.com/a/37759548/4687565以上是关于如何在没有外部库的任何lua中将双精度转换为小字符串表示而不会丢失数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PySpark 1.6 中将 DataFrame 列从字符串转换为浮点/双精度?
如何使用 stringstream 在 C++ 中将字符串转换为双精度值 [关闭]