80 位浮点数和次正规数
我正在尝试将 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试 SoftFloat 库,它有
floatx80_to_float32
、floatx80_to_float64
和floatx80_to_float128
。检测本机格式,并采取相应措施。Try SoftFloat library, it have
floatx80_to_float32
,floatx80_to_float64
andfloatx80_to_float128
. Detect the native format, act accordingly.查找非正常 80 位数字信息的问题可能是因为 8087 没有对它们使用任何特殊的非规范化。在 MSDN 页面上找到了这个 类型 float (C):
编辑
上述内容可能适用于 Microsoft 如何使用 FPU 寄存器。找到另一个表明这一点的来源:
FPU 数据类型:
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):
Edit
The above might be true for how Microsoft make use of the FPUs registers. Found another source that indicate this:
FPU Data types: