Scilab 中浮点计算的精度是多少?

What is the precision of floating point calculations in Scilab?

注意:我使用了 Matlab 标签以防它们保持相同的精度。 (据我所知,这两个程序非常相似。)

作为我之前的一个问题 () 的后续行动,我正在尝试确定我需要设置的精度级别(在我目前正在转换的 C++ 程序中Scilab 代码)为了 mock Scilab 程序的准确性。本质上,这两个程序都产生相同(或非常相似)的结果。

在 Scilab 中计算浮点数时,保持的精度水平是多少?

我读过(here 和其他一些地方),在 C++ 中使用浮点运算时,double 只能准确地保持大约 16 位小数,例如:

     4   8  12  16
     v   v   v   v
0.947368421052631578 long double
0.947368421052631526 double

与 Scilab 相比,这个准确度有多相似?

每种通用语言(标准 C++、scilab、matlab 等)都使用相同的格式 来表示十进制数。它在 IEEE754 中广为人知,其精确文档在以下位置进行了解释:

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

这意味着几乎所有常用系统的精度都保持不变。这是一个接近 2^-52(或等价于 2.2204e-16)的 数字。它定义了 "distance from 1.0 to the next largest double-precision number"。

当你使用scilab时,你可以通过%eps命令https://help.scilab.org/docs/5.5.1/fr_FR/percenteps.html. For matlab, it's stored in the eps variable http://nl.mathworks.com/help/matlab/ref/eps.html. For C++, it's a bit harder (see: http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon确认。

因此,如果您不使用特定机器(非典型架构或非常非常老的计算机或高精度小数(64 位双精度)),请不要担心精度。默认的将始终遵循相同的标准 (IEEE 754)。

但是,不要忘记,即使它看起来是一个常数,这个误差在非常大的数字和非常小的数字之间是不一样的(系统被设计为在区间 [0 , 1[ 和区间 [1, MAXIMUM[]。

可以用下面的例子来表示:

>>> 1e100 == 1e100+1
True
>>> 1 == 2
False

为确保您的代码可移植到不同的语言,我建议您明确引用赋予机器精度的函数。例如,在 scipy 中:print(np.finfo(float).eps)。但是,一般来说,设计良好的算法在 epsilon 略有不同的机器上不会有太大差异。

例如,如果我在 matlab 中为趋于 0(渐近)的东西实现一个循环,我应该写:

while(val < eps) do
...
end

因此,主要建议应该是:不要构建会尝试使用来自机器的太多信息的算法。您可以使用 epsilon 的实际值,也可以硬编码 2e-15 之类的东西。它可以在很多不同的机器上工作。

重新发布评论作为回答:

IEEE 754 双精度浮点数是大多数常用语言(如 MATLAB、C++ 和 SciLab)的标准表示形式:

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwiajY7LzZbNAhWJix4KHcrEA1wQFgggMAA&url=http%3A%2F%2Fforge.scilab.org%2Findex.php%2Fp%2Fdocscifloat%2Fdownloads%2Fget%2Ffloatingpoint_v0.2.pdf&usg=AFQjCNFQiOVdgkjuxhFXhp1PwDFY-J-Qbg&sig2=vH0cpadZqi0bNqa9F0Gmig&cad=rja

所以我不希望你需要做任何特殊的事情来表示精度,除了使用 C++ 双精度数(除非你的 SciLab 代码使用高精度浮点数)。

请注意,两个不同的 IEEE 754 兼容实现的表示在 16 位有效数字后可能不同:

MATLAB:

>> fprintf('%1.30f\n',1/2342317.0)
0.000000426927695952341190000000

Python:

>> "%1.30f" % (1/2342317,)
'0.000000426927695952341193713560'