A F*_*Fog 8 c++ floating-point nan ieee-754
我正在设计一个新的微处理器指令集(www.forwardcom.info),我想使用NAN传播来跟踪错误.但是,IEEE 754浮点标准中有许多奇怪的事情可以防止这种情况发生.
首先,我想使用NAN传播而不是错误捕获的原因是我有可变长度的向量寄存器.例如,如果我有一个带有8个元素的浮点向量,并且我在第一个元素中有1/0而在第六个元素中有0/0,那么我只得到一个陷阱,但如果我在计算机上运行相同的程序矢量长度的一半然后我得到两个陷阱:一个用于无穷大,一个用于NAN.我希望结果与向量长度无关,所以我需要依赖于NAN和INF的传播而不是陷阱.NAN和INF值将通过计算传播,以便在最终结果中检查它们.NAN表示包含一些称为有效负载的位,可用于有关错误源的信息.
但是,IEEE 754浮点标准中存在两个阻止NAN值可靠传播的问题.
第一个问题是具有不同有效载荷的两个NAN的组合只是两个值中的一个.例如,NAN1 + NAN2给出NAN1.这违反了a + b = b + a的基本原则.编译器可以交换操作数,以便在不同的编译器或不同的优化选项上获得不同的结果.我更喜欢得到两个有效载荷的按位OR组合.如果每个错误条件都有一位,那么这将起作用,但当然,如果有效负载包含更复杂的信息(例如具有动态类型的语言中的NAN装箱),则无效.标准委员会实际讨论了OR'ing解决方案(参见http://grouper.ieee.org/groups/754/email/msg01094.html).我不知道他们为什么拒绝这个提议.
第二个问题是如果只有一个输入是NAN,则min和max函数不传播NAN.换句话说,min(1,NAN)= 1.可靠的NAN传播当然需要min(1,NAN)= NAN.我不知道为什么标准会说这个.
在名为ForwardCom的新微处理器系统中,我想避免这些不幸的怪癖并指定NAN1 + NAN2 = NAN1 | NAN2和min(1,NAN)= NAN.
现在我的问题是:首先,我是否需要一个选项切换来在严格的IEEE一致性和可靠的NAN传播之间进行切换?引用标准:
安静的NaN应该由实施者自行决定提供从无效或不可用的数据和结果中继承的回顾性诊断信息.为了便于传播NaN中包含的诊断信息,应尽可能多地保留NaN操作结果中的信息.
注意标准在这里说"应该",在其他地方有"应该".这是否意味着我允许偏离建议?
第二个问题:我找不到任何实际使用NAN传播来跟踪错误的例子.也许这是因为标准的弱点.我想为不同的错误条件定义不同的有效负载位,例如:
0/0,0*∞,∞/∞,模(1,0),模(∞,1),∞-∞,以及涉及无穷大和除零的其他误差.
sqrt(-1),log(-1),pow(-1,0.1)以及从对数和幂导出的其他错误.
asin(2)和其他数学函数.
明确的分配.当变量初始化为NAN时,这可能很有用.
用户定义的错误代码有很多空位.
这是否已经完成,或者我是否必须从零开始创造一切?我有什么问题需要考虑(除了某些语言的NAN拳击)
是的,您可以偏离“应该”。从规范(§1.6):
? may表示在标准范围内允许的行动过程,没有暗示的偏好(“may”意味着“被允许”)
? 应表示为符合标准而必须严格遵守的强制性要求,不得偏离(“应”表示“必须”)
? 应该表示在几种可能性中,推荐一种特别合适,不提及或排除其他可能性;或者某种行动方案是首选但不一定是必需的;或者(以否定形式)不赞成但不禁止某项行动(“应该”的意思是“建议”)。
关于 的行为min,Intel 实现也不同于 IEEE 规范。来自英特尔指令集参考MINSD:
如果第二个源操作数中的值是 SNaN,则将 SNaN 原样返回到目标(即,不返回 SNaN 的 QNaN 版本)。
如果该指令只有一个值是 NaN(SNaN 或 QNaN),则将第二个源操作数(NaN 或有效浮点值)写入结果。如果不是这种行为,而是要求返回 NaN 源操作数(来自第一个或第二个源),则可以使用一系列指令来模拟 MINSD 的操作,例如比较后跟 AND、ANDN 和或者。
换句话说,它对应于x < y ? x : y。(有关更多详细信息,请参阅std::min 的参数顺序更改浮点的编译器输出:这是 C++ std::min,而不是fmin包装 IEEE-754 NaN 传播minimum操作的 C 数学库。)
我实际上不确定他们脑子里有什么特定的顺序,但是这里建议了另一种方法https://github.com/JuliaLang/julia/issues/7866#issuecomment-51845730。