【问题标题】:What is the standard way to maintain accuracy when dealing with incredibly precise floating point calculations in C++?在 C++ 中处理极其精确的浮点计算时,保持准确性的标准方法是什么?
【发布时间】:2016-10-06 15:34:36
【问题描述】:

我正在将程序从Scilab(类似于 Matlab)转换为 C++,并且我需要保持与之前代码保持的相同级别的精度。

注意:尽管保持相同水平的精度是理想的。如果完成的结果有一些错误,这是可以接受的。我面临的问题(如下所示)是由于循环造成的,因此计算错误会很快复合。但如果最终结果仅相差千分之一左右(例如 1/1000 与 1/1001),那将不是问题。

我已经简要研究了许多不同的方法来做到这一点,包括:

Int vs Float 示例: 不要使用浮点数 12.45,而是将其存储为整数 124,500。然后在适当的时候简单地将所有内容转换回来。注意:我不确定这将如何与我正在使用的代码一起工作(下面有更多详细信息)。

我的程序如何产生错误结果的示例:

for (int i = 0; i <= 1000; i++)
{
    for (int j = 0; j <= 10000; j++)
    {
        // This calculation will be computed with less precision than in Scilab
        float1 = (1.0 / 100000.0);

        // The above error of float2 will become significant by the end of the loop
        float2 = (float1 + float2);
    }
}

我的问题是:

是否有一种普遍接受的方法来保持浮点运算的准确性,或者上述方法之一是否足够?

【问题讨论】:

标签: c++ math precision gmp


【解决方案1】:

如果您的编译器支持它,请使用 BCD(二进制编码的十进制)

山姆

【讨论】:

    【解决方案2】:

    好吧,如果您使用 GCC 编译器,另一种选择是使用 quadmath/__float128 类型。

    【讨论】:

      【解决方案3】:

      是否有一种普遍接受的方法来保持浮动精度 点算术

      “普遍接受”过于宽泛,所以没有。

      上述方法之一就足够了吗?

      是的。特别是 gmp 似乎是一个标准选择。我也想看看Boost Multiprecision library

      手动编码整数方法也可以,但肯定不是首选方法:它需要更多编码,并且需要更严格的方法来存储和处理任意精确的整数。

      【讨论】:

        【解决方案4】:

        在移植这样的代码时保持精度是非常困难的。不是因为这些语言对 float 是什么有隐含的不同观点,而是因为不同的算法或准确性限制的假设是什么。例如,在 Scilab 中进行数值积分时,可能会使用高斯求积法。而您可以尝试使用梯形方法。两者可能都在处理相同的 IEEE754 单精度浮点数,但由于两种算法的收敛特性,您会得到不同的答案。那么如何解决这个问题呢?

        好吧,您可以浏览 Scilab 源代码并查看它为您需要的每件事使用的所有算法。然后,您可以复制这些算法来处理 Scilab 隐式执行的数据的任何预处理或后处理(如果有的话)。这是很多工作。而且,坦率地说,这可能不是消磨时间的最佳方式。相反,我会考虑使用developer's documentation 中的与其他语言接口部分,看看如何直接从 C、C++、Java 或 Fortran 代码调用 Scilab 函数。

        当然,对于第二个选项,您必须考虑如何分发您的代码(如果需要)。Scilab 具有与 GPL 兼容的许可证,因此您可以将它与您的代码捆绑在一起。但是,它非常大(~180MB),您可能只想捆绑您需要的部分(例如,您不需要整个解释器系统)。这是以不同的方式进行的更多工作,但保证与您当前的 Scilab 解决方案的数值兼容性。

        【讨论】:

        • 感谢您的回答。幸运的是,我只处理标准算术(例如 + - * /),所以我不必担心转换任何算法(假设上述运算符在两种语言中的工作方式相同)。
        • @PaulWarnick 如果您只处理简单的算术,那么当 Scilab 不使用 GMP 之类的任意精度库时,为什么还要考虑使用它呢?我对你的总体目标感到困惑。
        • 我对问题的研究越多,我就越开始明白我实际上并不需要 GMP。从我的问题:stackoverflow.com/questions/37686796/…(特别是接受的答案和以下 cmets)我已经开始思考如何解决这个问题。我最初提出这个问题的原因是因为我的印象是 Scilab 保持了比标准 C++ 双精度更高的精度,而实际上它们遵循相同的 IEEE 标准。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        • 2019-11-22
        相关资源
        最近更新 更多