Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Floating point 如何在D中执行高精度计算?_Floating Point_D_Arbitrary Precision - Fatal编程技术网

Floating point 如何在D中执行高精度计算?

Floating point 如何在D中执行高精度计算?,floating-point,d,arbitrary-precision,Floating Point,D,Arbitrary Precision,对于一些大学的工作,我必须近似一些数字,比如带有级数的欧拉数。所以我必须加上非常小的数字,但我在精度上有问题。如果数值很小,则不会影响结果 real s; //sum of all previous terms ulong k; //factorial s += 1.0/ k; 在每一步之后,k变得更小,但在第10轮之后,结果不再改变,并停留在2.71828固定精度浮点类型,即CPU浮点单元本机支持的类型(float,double,real)对于任何需要多位数精度的计算,例如您给出的示例,

对于一些大学的工作,我必须近似一些数字,比如带有级数的欧拉数。所以我必须加上非常小的数字,但我在精度上有问题。如果数值很小,则不会影响结果

real s;  //sum of all previous terms
ulong k; //factorial

s += 1.0/ k;

在每一步之后,k变得更小,但在第10轮之后,结果不再改变,并停留在2.71828固定精度浮点类型,即CPU浮点单元本机支持的类型(
float
double
real
)对于任何需要多位数精度的计算,例如您给出的示例,都不是最优的

问题是这些浮点类型具有有限的精度数字(实际上是二进制数字),这限制了此类数据类型可以表示的数字长度。
float
类型的小数位数限制约为7位(例如3.141593);
double
类型限制为14(例如3.1415926535898);而
real
类型也有类似的限制(略高于
double

因此,向浮点值中添加非常小的数字将导致这些数字丢失。观察将以下两个浮点值相加时会发生什么情况:

float a = 1.234567f, b = 0.0000000001234567
float c = a + b;

writefln("a = %f b = %f c = %f", a, b, c);
a
b
都是有效的浮点值,各自保留大约7位精度。但当添加时,只保留最前面的7位数字,因为它被推回浮点:

1.2345670001234567 => 1.234567|0001234567 => 1.234567
                              ^^^^^^^^^^^
                         sent to the bit bucket
因此
c
最终等于
a
,因为
a
b
相加的精度更高的数字会被去掉

,可能比我的好得多



这个问题的答案是任意精度的算法。不幸的是,CPU硬件不支持任意精度的算法;因此,它(通常)不在您的编程语言中。但是,有许多库支持任意精度浮点类型以及要对其执行的数学运算。请参阅以获取一些建议。今天,您可能找不到任何用于此目的的特定于D的库,但是有很多C库(GMP、MPFR等)应该很容易单独使用,如果您可以为其中一个找到D绑定,则更是如此。

如果您需要一个使用本机类型运行的解决方案,您应该能够通过尝试始终添加类似数量级的数字来获得合理的结果。一种方法是计算数列的前X项,然后重复将两个最小的数替换为三个和:

auto data = real[N];
foreach(i, ref v; data) {
  v = Fn(i);
}

while(data.length > 1) {
  data.sort(); // IIRC .sort is deprecated but I forget what replaced it.
  data[1] += data[0];
  data = data[1..$];
}

return data[0];

(一个最小的堆会使这个过程快一点。)

如前所述,您需要使用一些第三方多精度浮点算术库(我认为Tango或Phobos只有一个用于任意长度整数算术的模块)


是一个使用MPFR的D项目。您应该可以在那里找到绑定。

太好了。。我要这样试试!