它是一个好主意,使用IEEE754浮动指南,用于价值不是吗?
-
10-07-2019 - |
题
它是一个好主意,使用IEEE754浮动指南(不是一个数)为价值观是不确定的对非数学的原因吗?
在我们的情况下,他们尚未设定,因为价值没有收到其他一些设备。上下文中是一个嵌入式系统的使用IEC1131REAL32值。 编辑: 编程语言是C,因此,我们将最有可能使用南和isnanf(x),这是从C99。虽然我们可能需要一些额外的扭曲,获得这些进入我们的操作系统兼容性层。
默认在编程语言似乎是初始化浮点变量与正零,其内部表示的都是零。这不是可用于我们,因为0范围的有效值。
这似乎是一个干净的解决方案,使用南,但也许这是更多的麻烦比它值得我们应该选择一些其他的价值呢?
解决方案
刚刚注意到这个问题。
这是IEEE 754委员会考虑的NaN的用途之一(我是委员会成员)。算术中NaNs的传播规则使其非常有吸引力,因为如果您有一系列涉及某些初始化数据的计算结果,则不会将结果误认为是有效结果。它还可以通过计算回溯,以便更直接地找到使用初始化数据的位置。
也就是说,754委员会控制之外还有一些陷阱:正如其他人所指出的那样,并非所有硬件都支持NaN值的速度,这可能会导致性能危害。幸运的是,在性能关键设置中,人们通常不会对初始化数据进行大量操作。
其他提示
南斯是一个合理的选择了'没有价值'句子(D编程语言使用它们初始化的价值观,为实例),但是因为任何的比较,涉及他们的将是虚假的,你可以得到一个惊喜:
if (result == DEFAULT_VALUE)
, 不会工作如期望的如果DEFAULT_VALUE
是南,作为乔恩提及。他们也可能会导致问题的范围内检查,如果你不小心。考虑功能:
bool isOutsideRange(double x, double minValue, double maxValue) { return x < minValue || x > maxValue; }
如果x是南,这一功能将错误地报告,x之间minValue和maxValue.
如果你只想要一个魔术价值的用户试验反对,我建议你积极或消极无限的,而不是南,因为它不附带同样的陷阱。使用南当你想它对其财产的任何行动在南的结果在一个南:它方便的时候你不希望依赖的呼叫者检查的价值,例如。
[编辑:我最初的管理类型"任何比较涉及他们的将是真正的"以上,这不是我的意思,是错误的,他们都是虚假的,除了楠!= NaN,这是真的]
我在类似的情况下使用NaN只是因为:通常的默认初始化值0也是有效值。到目前为止,NaNs工作正常。
顺便说一句,这是一个很好的问题,为什么默认的初始化值通常是(例如,在Java原始类型中)0而不是NaN。难道不是42或其他什么?我想知道零的基本原理是什么。我认为一般来说这是一个坏主意。要记住的一件事是大多数CPU对Nan的处理要慢得多,然后<!>通常<!>浮动。并且很难保证在通常情况下你永远不会有Nan。我在数值计算方面的经验是,它经常带来比它更值得的麻烦。
正确的解决方案是避免编码<!>“;缺少值<!>”;在浮动中,但以另一种方式发出信号。但是,这并不总是实用的,具体取决于您的代码库。
小心NaN的......如果你不小心的话,它们会像野火一样蔓延。
它们是浮点数的完全有效值,但涉及它们的任何赋值也将等于NaN,因此它们会在代码中传播。如果你抓住它,它作为一个调试工具是相当不错的,但是如果你带来一些东西要发布并且某处有一个边缘情况,它也会是一个真正的麻烦。
D使用此作为默认情况下赋予浮动NaN的基本原理。 (我不确定我同意。)
我的感觉是它有点hacky,但至少你使用这个NaN值进行操作的其他所有数字都会给出NaN作为结果 - 当你在错误报告中看到一个NaN时,至少你知道你是什么样的错误狩猎。
如果您的基本需求是浮点值不代表可能从设备接收的任何数字,和如果设备保证它永远不会返回NaN,那么这对我来说似乎很合理。
请记住,根据您的环境,您可能需要一种特殊的方法来检测NaN(不要只使用if (x == float.NaN)
或等同物。)
这听起来对我来说非常好用。希望我已经想到了......
当然,它们应该像病毒一样传播,这就是重点。
我想我会使用nan而不是其中一个无穷大。使用信令nan并使它在第一次使用时引起事件可能会很好,但到那时为时已晚它应该在第一次使用时保持安静。
使用NaN作为默认值是合理的。
请注意,某些表达式(如(0.0 / 0.0))会返回NaN。