当在C ++中处理令人难以置信的精确浮点计算时,保持精度的标准方法是什么? [英] What is the standard way to maintain accuracy when dealing with incredibly precise floating point calculations in C++?

查看:229
本文介绍了当在C ++中处理令人难以置信的精确浮点计算时,保持精度的标准方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从 Scilab 将程序转换为C ++(类似于Matlab )和我需要保持与以前的代码保持相同的精度水平。

I'm in the process of converting a program to C++ from Scilab (similar to Matlab) and I'm required to maintain the same level of precision that is kept by the previous code.

注意:虽然保持相同的精度水平理想。如果结果有一些错误,则可以接受。我面临的问题(我将在下面显示)是由于循环,所以计算错误化合很快。但是,如果最终结果只有千分之一左右(例如1/1000对比1/1001),则不会有问题。

Note: Although maintaining the same level of precision would be ideal. It's acceptable if there is some error with the finished result. The problem I'm facing (as I'll show below) is due to looping, so the calculation error compounds rather quickly. But if the final result is only a thousandth or so off (e.g. 1/1000 vs 1/1001) it won't be a problem.

我们简要地探讨了许多不同的方法,包括:

I've briefly looked into a number of different ways to do this including:

Int vs Float示例:而不是使用float 12.45,将其存储为124,500的整数。然后简单地转换回适当的一切都这样做。注意:我不确定这将如何与我正在使用的代码(下面的更多细节)。

Int vs Float Example: Instead of using the float 12.45, store it as an integer being 124,500. Then simply convert everything back when appropriate to do so. Note: I'm not exactly sure how this will work with the code I'm working with (more detail below).

我的程序产生不正确的结果:

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);
    }
}

我的问题是:

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

推荐答案

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

Maintaining precision when porting code like this is very difficult to do. Not because the languages have implicitly different perspectives on what a float is, but because of what the different algorithms or assumptions of accuracy limits are. For example, when performing numerical integration in Scilab, it may use a Gaussian quadrature method. Whereas you might try using a trapezoidal method. The two may both be working on identical IEEE754 single-precision floating point numbers, but you will get different answers due to the convergence characteristics of the two algorithms. So how do you get around this?

好吧,你可以浏览Scilab源代码,看看你所需要的所有算法。然后,您可以复制这些算法,照顾Scilab隐式执行的任何预处理或后处理(如果有的话)。这是很多工作。坦白地说,可能不是最好的方式来度过你的时间。相反,我将使用开发人员文档中的与其他语言的交互部分>查看如何直接从C,C ++,Java或Fortran代码调用Scilab函数。

Well, you can go through the Scilab source code and look at all of the algorithms it uses for each thing you need. You can then replicate these algorithms taking care of any pre- or post-conditioning of the data that Scilab implicitly does (if any at all). That's a lot of work. And, frankly, probably not the best way to spend your time. Rather, I would look into using the Interfacing with Other Languages section from the developer's documentation to see how you can call the Scilab functions directly from your C, C++, Java, or Fortran code.

当然,使用第二个选项,你必须考虑如何分发代码(如果你需要).Scilab有一个GPL兼容的许可证,所以你可以只是捆绑代码。但是,它是相当大(约180MB),你可能想要只是捆绑你需要的部分(例如,你不需要整个解释器系统)。这是更多的工作在不同的方式,但保证与您当前的Scilab解决方案的数字兼容。

Of course, with the second option, you have to consider how you are going to distribute your code (if you need to).Scilab has a GPL-compatible license, so you can just bundle it with your code. However, it is quite big (~180MB) and you may want to just bundle the pieces you need (e.g., you don't need the whole interpreter system). This is more work in a different way, but guarantees numerical-compatibility with your current Scilab solutions.

这篇关于当在C ++中处理令人难以置信的精确浮点计算时,保持精度的标准方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆