floating-point - 为什么 PowerPC 的 stfs 指令没有按预期运行?
问题描述
PowerPC 的浮点寄存器只支持双精度格式,因此加载和存储单精度值需要转换。在加载时从单到双的转换是有道理的,但是从双到单的转换用于存储会造成一些令人困惑的事情。它似乎正确地截断了单精度范围内的数字,以及 NaN、无穷大和零,但对其他所有内容做了一些奇怪的移位,而不是像我期望的那样四舍五入到零或无穷大。
来自 PPC750 CPU 的示例。首先列出了给出我预期结果的示例。
double-precision input decimal approximation single-precision output decimal approximation
0x 400f ffff ffff ffff 3.99999999 0x 407f ffff 3.99999976
0x 7ff8 0000 0000 0000 QNaN 0x 7fc0 0000 QNaN
0x 7ff0 0000 0000 0000 +inf 0x 7f80 0000 +inf
0x 8000 0000 0000 0000 -0.0 0x 8000 0000 -0.0
--------------------------------------------------------------------------------------------------
0x 8000 0000 0000 0001 -4.941e-324 0x 8080 0000 -1.175e-38
0x 00a0 0000 0000 0000 1.139e-305 0x 0500 0000 6.019e-36
0x 7fe0 1234 5678 9abc 9.028e+307 0x 7f00 91a2 1.709e+38
我查看了PowerPC Programming Environments Manual
以了解它是否可以对此有所了解。第 C.7 节描述了“不需要非规范化”和“需要非规范化”情况的转换步骤。(请注意,||
在此符号中表示串联。)
然后它继续说:
请注意,如果要由单精度存储浮点指令存储的值的大小大于单一格式可表示的最大数,则适用第一种情况,“不需要反规范化”。存储在 WORD 中的结果是一个定义明确的值,但在数值上不等于源寄存器中的值(也就是说,从 WORD 中加载单精度浮点的结果不等于原始源寄存器)。
这解释了为什么我得到了我所做的结果,但它并没有解释它有什么用处。在我看来,如果再次从内存中加载这些值会导致可怕的错误。
为什么 stfs 指令不执行正常舍入?预期结果如何不会引起问题?
解决方案
文档说“请注意,在执行stfs指令stfs
之前,要存储的值应该是单精度格式。” 这意味着要存储的寄存器的内容应该是一些产生单精度值的先前指令的结果,例如(单精度浮点乘法)或(舍入到单精度)。fmuls
frsp
我会冒险猜测部分原因是它可以快速且易于实现 - <code>stfs 不必进行舍入,也不必使用浮点单元来执行此操作。它可以直接进入加载存储单元,该单元仅具有处理更简单情况的逻辑,其中截断位就足够了。
推荐阅读
- asynchronous - 这是使用异步/等待的正确方法吗?
- python - 字符串索引必须是整数 json python
- git - 如何一次 git diff 所有未(尚未)暂存的修改文件?
- c# - LINQ 查询有条件地过滤 where 子句并从另一个表中选择值
- wordpress - 如何在 WooCommerce 上设置自定义产品排序?
- reactjs - 创建到不同主机的 socket.io 连接。适用于 CRA 开发版本,但不适用于生产版本
- php - SSH2 sftp 使用 PHP 返回 502 Bad gateway
- javascript - 我怎样才能得到这个js中每个类项的唯一ID
- haskell - 无法在 ReaderT 包装中推断出 MonadReader
- sql - 优化删除 SQLite3 中具有最高用户 ID 或 rowid 的重复行之一?