C++ 如何制作我的C++;符合IEEE 754标准的库

C++ 如何制作我的C++;符合IEEE 754标准的库,c++,c++11,floating-point,numeric,ieee-754,C++,C++11,Floating Point,Numeric,Ieee 754,我已经编写了一个小型库(C++11)来使用四元数进行计算,但我很快意识到,由于涉及到相当多的浮点运算,因此存在许多精度/精度问题。这让我开始研究std::complex和ieee754。综合体做了大量的工作,尤其是处理NAN。这是我成为“符合IEEE 754标准”唯一需要担心的事情吗?更一般地说,对于如何将一个原本幼稚的数字库变成一个“符合IEEE 754标准”的库,是否有一个“秘诀” 注意:问题不在于编译器是否为IEEE 754,而在于我是否应该在自己的算法中采取特殊步骤以满足IEEE 754

我已经编写了一个小型库(C++11)来使用四元数进行计算,但我很快意识到,由于涉及到相当多的浮点运算,因此存在许多精度/精度问题。这让我开始研究std::complex和ieee754。综合体做了大量的工作,尤其是处理NAN。这是我成为“符合IEEE 754标准”唯一需要担心的事情吗?更一般地说,对于如何将一个原本幼稚的数字库变成一个“符合IEEE 754标准”的库,是否有一个“秘诀”


注意:问题不在于编译器是否为IEEE 754,而在于我是否应该在自己的算法中采取特殊步骤以满足IEEE 754的要求。毕竟,我与编写std::complex的人处于相同的位置,他们确实采取了额外的步骤,例如,对于NaNs。

您只需检查库的标题
常量
数值限制::是iec559
(iec559与ieee754相同)看看你的C++编译器是否已经支持IEEE 754。

< P>使算术IEEE兼容不是你的任务而是编译器的任务。 您的编译器符合或不符合IEEE(@Paul),对此您无能为力。具体来说,您不能使用符合IEEE的编译器双算术编写不符合IEEE的程序(请不要相信我的话:)。这与您很难使用ISO/IEC 14882:2011-comliant编译器编写非ISO/IEC 14882:2011-comliant程序类似

然而,这并不能保证程序能够给出预期的输出,并且没有奇怪的操作,包括UB。这与IEEE 754中NAN和INF的作用类似。它们是为了给定义不明确的数学运算(如0/0)或超出范围的运算(如1/0)提供“合理答案”

该标准不关心您在库中如何处理这些答案(即如何将它们翻译给lib用户)。该标准仅规定了在另一个数学运算中使用这些“合理答案”如何给出另一个“合理答案”的方法

你可能会感兴趣(读起来很难,但至少值得努力抓住这个想法)


Ps我检查了我的lib实现(mingw4.9.1.32位),没有注意到任何NaNs的神奇之处。

[@Frank:comments下面是我8月3日7:38的最后一个答案]

当与复数相乘时,NaN可能是以下位置使用XCode iplementation表示法的结果:

然后,他们(XCode STL的作者)会处理这些问题,以允许出现以下情况:

(INF + INFi)*(c + di)
(INF + INFi)*(0 + 0i)
etc...
诀窍(最有可能)是将包含值的INFs和NAN设置为(+/-)1或(+/-)0,以便最终重新计算

if (__recalc)
{
    __x = _Tp(INFINITY) * (__a * __c - __b * __d);
    __y = _Tp(INFINITY) * (__a * __d + __b * __c);
}
导致

INF * (+/-)INF = (+/-)INF or
INF * (+/-)0   = NaN
视情况而定

这是

如何将它们翻译给lib用户


ps.>我没有时间深入探讨这个问题,以便判断它们的实施情况,但这很可能是合理的。(这很有帮助,但我无法将其转换为[a+bi]复数表示法)总之,MinGW 4.9.1。32位Win实现使此任务保持打开状态,用户应处理紧急情况。您可以首先采用MinGW策略,如果您知道如何正确处理四元数代数的角情况,也可以采用XCode策略。在任何情况下,这不再是关于如何使我的C++库符合IEEE 754……/P>侧注:如果你关心速度,请注意感谢!事实上,所以我计划让IEEE 754符合性成为可选的。但英特尔的一篇论文(当然!)警告我,如果我的lib不是IEEE-754,那么火箭会坠毁,甚至更多。四元数运算(如乘法)通常处理(有符号)乘积的运行和。您可以将其视为一种相对便宜的方法,以提高符合IEEE-754的准确性。您还可以查看一个相对成熟的实现,如Boost的四元数类。我想象复杂的概念,如分支切割等,如果你想保持一致,在理论意义上对四元数会有很大的陌生感。还要注意的是,如果你使用四元数进行旋转,你应该在应用操作后(重新)规范化它们,以保持它们作为“单位”旋转。保罗-是的,确实,但这似乎并不是故事的结局。例如,如果你看一下std::complex库,它有代码来处理NAN——所以我认为作为一个程序员,我不得不在我的算法能够产生NaN的地方添加类似的代码。如果每次有人提到Goldberg论文作为浮点问题的最后一个词时我都有一美元…@PavDub-检查std::complex的gcc实现。我在那里看到了南斯的一些特殊代码。我还看到一个德国人的演示,他抱怨说,这种额外的处理使他的计算速度太慢了,他可以证明他的计算永远不会产生NAN。@Frank我没有逐行检查复杂的实现,但一眼就没有注意到任何NAN的痕迹。你能把你的实施方案寄给我吗?不是我不相信你,而是我只是好奇。。。(我的在这里:)我正在Mac上使用的是:/Applications/Xcode.app/Contents/Developer/toolschains/XcodeDefault.xctoolschain/usr/include/c++/v1/complex。我稍后会在pastebin上发布一个代码片段-我无法从工作中访问pastebin。template complex operator*(const complex&\uuuz,const complex&\uuuw)使用了大量的isinf和isnan。这就是这个线程的起源:我查看了他们对std::complex所做的工作,这让我思考是否应该在自己的操作中处理他们处理的所有情况,以及是否需要符合“IEEE-754标准”当前位置我以为这个标准描述了这些角落案例中的预期情况——那是我的错误。
INF * (+/-)INF = (+/-)INF or
INF * (+/-)0   = NaN