如何在不使用外部库的任何Lua版本中将double转换为小字符串表示而不丢失数据?

我想使用任何Lua版本将数字转换为字符串,因此

  • ##没有数据损失(必需!)

  • 字符串表示尽可能小(8字节将很好)(可选,非必需)

  • ##不使用外部库(必需!)

  • 转换尽可能快(可选,非必需)

我不在乎

  • 人类可读性
  • 避免特殊字符

我尝试了内置的 tonumber 功能,但它并不总是给出正确的结果:

> print((2+256^6)==(1+256^6))
false
> print(tostring(2+256^6)==tostring(1+256^6))
true
点赞
用户7185318
用户7185318

这包括一个number_to_str和一个number_from_str函数:

https://github.com/bakpakin/binser/blob/master/binser.lua

显然,它们比Lua内置的tonumber函数更加强大...

2018-07-07 11:13:00
用户107090
用户107090

如果你可以使用标准 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+ 中可用。

2018-07-07 11:24:34
用户6834680
用户6834680

不丢失数据的编码/解码

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)'
}

-- 编码:
str_value = string.format('%.17g', num_value):gsub('^.*', NaN_serialized):gsub(',', '.')

-- 解码:
num_value = loadstring("return "..str_value)()

该代码块展示了如何进行不丢失数据的编码和解码。NaN_serialized 表是一个在编码时用于处理 NaN 和正负无穷大的映射表,编码时会先将数字转换成字符串,然后使用映射表将字符串替换为合适的文本表示。在解码时,使用 loadstring 将字符串转换成对应的数字。

2018-07-10 11:01:05