能否使用双精度浮点数表示64位数字而不失精度?

7

我希望使用Lua(它内部仅使用双精度浮点数)来表示一个整数,该整数在0到2^64-1之间不能发生舍入误差,否则会发生可怕的事情。

这种做法是否可行?


2
IEEE 64位双精度提供了确切的53位尾数,其余的位用于符号和指数。 - David R Tribble
8个回答

14

不行

至少要使用一些64位双精度浮点数的位来表示指数(二进制小数点的位置),因此可用于实际数字的位数不到64位。因此,不,64位双精度浮点数不能表示所有64位整数可以表示的值(反之亦然)。


1
只要在浮点数和64位整数之间没有映射函数,那么这就是正确的。你可以将该数字表示为不同的浮点数。但这并不实用 :) - viraptor
2
即使是不切实际的解决方案也可能行不通 - 例如,如果在Lua中处理信号NaN(SNaN)值,则可能会触发异常(不知道是否正确 - 但可能会)。 - stusmith
1
一些双精度浮点数的值是非规格化的 - 如果您的编程语言可能在不经过警告的情况下重新规格化它们,则无法安全地将64位信息储存在其中。 - bdonlan

5
尽管您已经得到了关于64位类型的问题的一些好答案,但您可能仍希望针对自己的具体问题找到实用的解决方案。我所知道的最可靠的解决方案是使用LNUM补丁(也称为Lua整数补丁)构建Lua 5.1版本,该补丁可以从LuaForge下载。如果您不打算从C源代码构建Lua,则至少有一个纯Lua库可以处理64位有符号整数-请参阅Lua用户wiki。

4

双精度浮点数本身是一个64位类型。然而,你会失去1个比特用于符号和11个比特用于指数。

所以答案是否定的:无法完成。


3
因为最高位始终不为零,所以你会获得一个比特,即精度为总比特数 - 符号比特数 - 指数比特数 + 隐式比特数 = 64 - 1 - 11 + 1 = 53 - Christoph
我不理解你的解释。我明白可以通过“滥用”符号位来增加数字范围。(基本上是使用负数来增加正数范围) - Toad
1
例如,二进制小数0.01...(51个1)...1在IEEE双精度浮点数中可以被准确表示,即使它有53个有效数字。它由指数-2(占用11位)、符号0(占用1位)和尾数1...(50个1)...1(占用52位)表示。第一个1没有存储在任何地方,它是默认的。您总是会选择一个指数,使得尾数的“第一个”位是1,因此第一个位被省略了。例外是非规格化数,它们处理方式略有不同(或根本不处理)。 - Steve Jessop
@reinier:IEEE 754双精度浮点数的指数为23,不是吗?11位指数适用于浮点数。虽然这并不改变你观点的本质 :-) - Arthur Reutenauer
嗯...你可能是对的。我知道微软使用这个:double类型包含64位:1位用于符号,11位用于指数,52位用于尾数。它的范围是+/-1.7E308,至少具有15位精度。来源:http://msdn.microsoft.com/en-us/library/e02ya398%28VS.80%29.aspx - Toad
2
@Arthur:IEEE 754双精度浮点数具有11位指数字段。单精度浮点数具有8位指数字段。任何754固定宽度类型中唯一的23位字段是单精度数字的有效数字字段。 - Stephen Canon

3

记忆中,double 可以完全表示一个53位有符号整数。


2
不,你不能使用 Double 存储 64 位整数而不失精度。
但是,你可以使用一个 Lua 补丁来为 Lua 解释器添加真正的 64 位整数支持。将 LNUM 补丁应用到你的 Lua 源码中,并重新编译。

1

在64位系统中,您只能存储2^64个不同的代码。这意味着,一个可以表示2^64个整数的64位类型没有任何地方来表示其他东西,比如浮点数。

显然,双精度浮点数可以表示很多非整数,因此它无法满足您的要求。


0

IEEE 754双精度浮点数无法准确表示64位整数。但是,它可以准确地表示每个32位整数值。


-1

我对Lua一无所知
但如果你能够找出如何在这种语言中执行浮点数的位运算,理论上你可以创建一个包装类,将你以字符串形式给出的数字设置为浮点数的位,以表示你给出的数字
更实际的解决方案是使用一些大数库


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接