80 位浮点数和次正规数

发布于 2024-11-28 15:08:17 字数 1297 浏览 1 评论 0原文

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

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

根据维基百科告诉我的内容,float32 和 float64 表示一个次正规数,其(有偏差的)指数为 0 且尾数非零。

  • 在 80 位浮点数中这告诉我什么?
  • 80位浮点数可以尾数<< 1.0 甚至有一个非零指数?
  • 或者,指数为 0 的 80 位浮点数是否可以有尾数 >= 1.0?

编辑:我想问题归结为:

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

如果不是,转换结果应该是哪种数字?在这种情况下我应该完全忽略指数吗?或者是qNaN?

编辑:

我阅读了英特尔手册中的 FPU 部分(英特尔® 64 和 IA-32 架构软件开发人员手册,第 1 卷:基本架构),这没有我想象的那么可怕曾经害怕过。事实证明,以下值未定义:

  • exponent == 0 + 具有最高位设置的尾数
  • exponent != 0 + 没有最高位设置的尾数

它没有提到这些值是否可以出现在野外,也没有提到它们是否可以出现进行内部转换。 所以我实际上清理了 Ollydbg 并手动设置了 x87 寄存器中的位。 我制作了 ST(0) 来包含指数中设置的所有位和尾数 0。然后我让它执行存储

FSTP QWORD [ESP]
FLD QWORD [ESP]

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

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

无论如何,案子解决了。谢谢大家。

I am trying to convert an 80-bit extended precision floating point number (in a buffer) to double.
The buffer basically contains the content of an x87 register.

This question helped me get started as I wasn't all that familiar with the IEEE standard.
Anyway, I am struggling to find useful info on subnormal (or denormalized) numbers in the 80-bit format.
What I know is that unlike float32 or float64 it doesn't have a hidden bit in the mantissa (no implied addition of 1.0), so one way to know if a number is normalized is to check if the highest bit in the mantissa is set. That leaves me with the following question:

From what wikipedia tells me, float32 and float64 indicate a subnormal number with a (biased) exponent of 0 and a non-zero mantissa.

  • What does that tell me in an 80-bit float?
  • Can 80-bit floats with a mantissa < 1.0 even have a non-zero exponent?
  • Alternatively, can 80-bit floats with an exponent of 0 even have a mantissa >= 1.0?

EDIT: I guess the question boils down to:

Can I expect the FPU to sanitize exponent and highest mantissa bit in x87 registers?

If not, what kind of number should the conversion result in? Should I ignore the exponent altogether in that case? Or is it qNaN?

EDIT:

I read the FPU section in the Intel manual (Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1: Basic Architecture) which was less scary than I had feared. As it turns out the following values are not defined:

  • exponent == 0 + mantissa with the highest bit set
  • exponent != 0 + mantissa without the highest bit set

It doesn't mention if these values can appear in the wild, nor if they are internally converted.
So I actually dusted off Ollydbg and manually set bits in the x87 registers.
I crafted ST(0) to contain all bits set in the exponent and a mantissa of 0. Then I made it execute

FSTP QWORD [ESP]
FLD QWORD [ESP]

The value stored at [ESP] was converted to a signaling NaN.
After the FLD, ST(0) contained a quiet NaN.

I guess that answers my question. I accepted J-16 SDiZ's solution because it's the most straight forward solution (although it doesn't explicitly explain some of the finer details).

Anyway, case solved. Thanks, everybody.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烧了回忆取暖 2024-12-05 15:08:17

尝试 SoftFloat 库,它有 floatx80_to_float32floatx80_to_float64floatx80_to_float128。检测本机格式,并采取相应措施。

Try SoftFloat library, it have floatx80_to_float32, floatx80_to_float64 and floatx80_to_float128. Detect the native format, act accordingly.

爱你不解释 2024-12-05 15:08:17

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

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

编辑

上述内容可能适用于 Microsoft 如何使用 FPU 寄存器。找到另一个表明这一点的来源:

FPU 数据类型

80x87 FPU 通常以标准化格式存储值。当一个
浮点数经过标准化后,HO 位始终为 1。在
32 位和 64 位浮点格式,80x87 实际上并不
存储该位时,80x87 始终假定它是 1。因此,32
64 位浮点数总是标准化的。
扩展精度 80 位浮点格式,80x87 没有
假设尾数的HO位为1,则尾数的HO位
数字作为位串的一部分出现。

归一化值可提供给定数量的最大精度
位。然而,存在大量非标准化值
我们可以用80位格式来表示。 这些值非常接近
为零并表示尾数 HO 位不为的值的集合
零。 80x87 FPU 支持一种特殊形式的 80 位,称为
非规范化值。

The problem with finding information on sub-normal 80 bit numbers might be because the 8087 does not make use of any special denormalization for them. Found this on MSDNs page on Type float (C):

The values listed in this table apply only to normalized
floating-point numbers; denormalized floating-point numbers have a
smaller minimum value. Note that numbers retained in 80x87 registers
are always represented in 80-bit normalized form;
numbers can only be
represented in denormalized form when stored in 32-bit or 64-bit
floating-point variables (variables of type float and type long).

Edit

The above might be true for how Microsoft make use of the FPUs registers. Found another source that indicate this:

FPU Data types:

The 80x87 FPU generally stores values in a normalized format. When a
floating point number is normalized, the H.O. bit is always one. In
the 32 and 64 bit floating point formats, the 80x87 does not actually
store this bit, the 80x87 always assumes that it is one. Therefore, 32
and 64 bit floating point numbers are always normalized. In the
extended precision 80 bit floating point format, the 80x87 does not
assume that the H.O. bit of the mantissa is one, the H.O. bit of the
number appears as part of the string of bits.

Normalized values provide the greatest precision for a given number of
bits. However, there are a large number of non-normalized values which
we can represent with the 80 bit format. These values are very close
to zero and represent the set of values whose mantissa H.O. bit is not
zero. The 80x87 FPUs support a special form of 80 bit known as
denormalized values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文