1

我在理解如何检索使用 Intel 的 x86 协处理器完成的计算结果时遇到了一些麻烦。

请考虑以下数据段。

.data

res real4 ?
x real4 5.0
k real4 3.4

以及以下代码段,版本 1

.code

main:

fld x      ; 5.0
fadd k1    ; 5.0 + 3.4
fistp res  ; store as integer (it will round, in this case down)

mov eax, res ; eax = 00000008

end main

版本 2

.code

main:

fld x     ; 5.0
fadd k    ; 5.0 + 3.4
fstp res  ; store as real

mov eax, res ; eax = 41066666

end main

我理解版本 1,没有问题。

2版​​没看懂 我可以在调试器中看到它与版本 1 一样进行了一些精确的计算,但是当存储时间是“41066666”!?

这是什么原因?
使用什么“编码”将 8.4 变成“41066666”?
有没有办法将它转换回 8.4,以便我可以在控制台中打印它(例如,使用 StdOut masm32 库函数)?

谢谢。

4

3 回答 3

4

浮点计算器和转换器

输入8.4可以看到数字的十六进制表示为:41066666

于 2010-01-20T04:50:21.583 回答
3

编码为IEEE-754浮点格式。看来您正在使用 32 位浮点数,也称为单精度。这种格式包含一个符号位、一个偏置 127 的 8 位指数(可能是 128——我不记得了)和 24 位尾数,其中存储了 23,丢失的位是最重要的,通常具有值一,除了非规范值。有几种具有特殊含义的模式:零、NaN、无穷大和非规范化。

除了 CookieOfFortune 建议的外部工具外,您还可以通过执行各种算术运算来确定值,将浮点转换为 ASCII。有许多算法可以在空间上权衡速度。查看 的任何运行时库源ftoa,或查看 的 %f 或 %g 转换printf()

于 2010-01-20T06:03:43.193 回答
3

0x41066666 是以IEEE-754 单精度格式编码的 8.4(准确地说是 8.3999996185302734375)。您可以通过从编码中提取组件字段轻松地将其值显示为十六进制数,这会给您0x8.66666,但将其转换为十进制更难正确执行。如果您想要十进制输出,最简单的方法是链接到系统上的 C 库并使用该printf函数。

或者,正如wallyk建议的那样,获取其中一个开源转换例程的源代码(或者编写自己的实现,尽管要做好这是一项令人惊讶的具有挑战性的任务)。可能最好的易于访问的资源位于 Netlib 上的gdtoa.tgz文件。该实现的复杂性应该让您对所涉及的问题有所了解,并且可能会让您回到使用库 =)

于 2010-01-20T14:57:17.357 回答