我在理解如何检索使用英特尔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库函数)?
感谢。
答案 0 :(得分:4)
Floating Pointt Calculator and Converter
输入8.4,您可以看到该数字的十六进制版本表示为:41066666
答案 1 :(得分:3)
编码为IEEE-754浮点格式。看来你使用的是32位浮点数,也称为单精度浮点数。这种格式包含一个符号位,一个八位指数偏置127(可能是128-我不记得随意),24位尾数,其中23个存储,丢失位是最重要的,通常有值一,除了非正规值。有几种具有特殊含义的模式:零,NaN,无穷大和非正规。
除了CookieOfFortune建议的外部工具外,您还可以通过执行各种算术运算来确定值,从而将浮点转换写入ASCII。有许多算法可以权衡空间速度。请参阅ftoa
的任何运行时库源代码,或printf()
的%f或%g转换。
答案 2 :(得分:3)
0x41066666
8.4(确切地说,8.3999996185302734375)以IEEE-754单精度格式编码。您可以通过从编码中提取组件字段轻松地将其值显示为十六进制数字,这将为您提供0x8.66666
,但将其转换为十进制则更难以正确执行。如果您想要十进制输出,最简单的方法是链接系统上的C库并使用printf
函数。
或者,正如 wallyk 建议的那样,抓住其中一个开源转换例程的源代码(或者编写自己的实现,尽管这是一个非常具有挑战性的任务,但要做得好)。可能最容易访问的资源位于Netlib上的gdtoa.tgz
文件中。该实现的复杂性应该让您对所涉及的问题有所了解,并且可能会指向您使用库=)