我正在设计一个新的微处理器指令集 (www.forwardcom.info),想要使用NAN传播技术来跟踪错误。然而,IEEE 754浮点数标准中存在一些奇怪的问题阻止了这一进展。
首先,我想使用NAN传播而不是错误捕获的原因是我有可变长度的向量寄存器。例如,如果我有一个包含8个元素的float向量,并且第一个元素为1/0,第六个元素为0/0,则只会获取一个陷阱,但如果在半向量长度的计算机上运行相同的程序,则会获取两个陷阱:无穷大和NAN各一个。我希望结果与向量长度无关,因此需要依赖于NAN和INF的传播而不是捕获。 NAN和INF值将通过计算进行传播,以便在最终结果中可以进行检查。 NAN表示包含一些称为有效载荷的位,可用于关于错误来源的信息。
但是,IEEE 754浮点数标准存在两个问题,防止了NAN值的可靠传播。
第一个问题是不同有效载荷的两个NAN的组合仅得到其中一个值。例如,NAN1 + NAN2给出NAN1。这违反了基本原则a+b = b+a。编译器可以交换操作数,以便在不同的编译器或不同的优化选项下获得不同的结果。我更喜欢获取两个有效载荷的按位OR组合。如果每个错误条件都有一个位,则这将起作用,但如果有效载荷包含更复杂的信息(例如具有动态类型的语言中的NAN boxing),那么它就行不通了。标准委员会实际上讨论过OR解决方案(请参见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*∞、∞/∞、modulo(1,0)、modulo(∞,1)、∞-∞以及涉及无穷大和除以零的其他错误。 sqrt(-1)、log(-1)、pow(-1,0.1)以及由对数和幂导出的其他错误。 asin(2)和其他数学函数。 显式赋值。当一个变量被初始化为NAN时,这可能是有用的。
用户定义的错误代码有大量空位可用。
这样做过吗,还是我必须从头开始发明一切?我是否需要考虑其他问题(除了某些语言中的NAN盒装)
min
可以由x<y?x:y
或x>y?y:x
组成。这些代码对于x = 1,y = NaN将产生不同结果,选择其中一个结果将是任意的。如果该操作是可交换的,则更好,使它不会因计算顺序的变化而发生改变。 - Eric Postpischilminimum
和maximum
,也有偏向数值的minimumNumber
和maximumNumber
。这意味着一个应用程序可以选择适合自己的选项,但如果您希望其提供符合性,则指令集必须支持两种选项。 - Eric Postpischil