80位浮点数和次正规数

80-bit floating point and subnormal numbers

本文关键字:浮点数 80位      更新时间:2023-10-16

我正在尝试将80位扩展精度浮点数(在缓冲区中)转换为双精度。这个缓冲区基本上包含了一个x87寄存器的内容。

这个问题帮助我开始,因为我不太熟悉IEEE标准。无论如何,我正在努力寻找80位格式的次常态(或非规范化)数字的有用信息。我所知道的是,与float32或float64不同,它在尾数中没有隐藏位(没有隐含的1.0添加),因此了解数字是否规范化的一种方法是检查尾数中的最高位是否设置。这给我留下了以下问题:

维基百科告诉我,float32和float64表示一个次正规数,指数为0,尾数非零。

  • 这在80位浮点数中告诉我什么?
  • 可以使用尾号<1.0有非零指数吗?
  • 或者,指数为0的80位浮点数甚至有尾数>= 1.0吗?
编辑:我想这个问题归结为:

我可以期望FPU消毒x87寄存器中的指数和最高尾数位吗?

如果不是,转换结果应该是什么样的数?在这种情况下,我应该完全忽略指数吗?还是qNaN?

编辑:

我阅读了英特尔手册(英特尔®64和IA-32架构软件开发人员手册,卷1:基本架构)中的FPU部分,这比我担心的要少得多。结果是以下值没有定义:

  • 指数== 0 +尾数与最高位集
  • 指数!= 0 +尾数,没有最高位集

它没有提到这些值是否可以在野外出现,也没有提到它们是否可以在内部转换。因此,我实际上重新使用Ollydbg并手动设置x87寄存器中的位。我精心设计了ST(0),以包含指数中设置的所有位和尾数0。然后我让它执行

FSTP QWORD [ESP]
FLD QWORD [ESP]

存储在[ESP]的值转换为信令NaN。在FLD之后,ST(0)包含一个安静的NaN。

我想这回答了我的问题。我接受了J-16 SDiZ的解决方案,因为它是最直接的解决方案(尽管它没有明确解释一些更精细的细节)。

不管怎样,案子解决了。谢谢,每一个人。

尝试SoftFloat库,它有floatx80_to_float32, floatx80_to_float64floatx80_to_float128。检测本地格式,并相应地执行

查找亚正常80位数字信息的问题可能是因为8087没有对它们使用任何特殊的非规范化。在msdn的float (C)类型页面上发现:

本表所列值仅适用于规范化浮点数;非规范化浮点数有较小的最小值。注意在80x87寄存器中保留的数字总是以80位规范化形式表示;数字只能是在32位或64位存储时以非规范化形式表示浮点变量(float和long类型的变量)。

编辑

对于微软如何使用fpu寄存器,上述可能是正确的。

FPU数据类型:

80x87 FPU通常以规范化格式存储值。当一个浮点数归一化后,H.O.位总是1。在32位和64位浮点格式,80x87实际上没有存储这个位,80x87总是假定它是1。因此,3264位浮点数总是标准化的。扩展精度80位浮点格式,80x87没有假设尾数的h。o。位是1,h。o

规格化值提供给定数量的最大精度位。然而,存在大量的非规范化值我们可以用80位的格式表示。这两个值非常接近到零,并表示尾数h。o。位不是的值的集合零。80x87 fpu支持一种特殊的80位形式,称为非规范化值。