首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在D中进行高精度的计算?

如何在D中进行高精度的计算?
EN

Stack Overflow用户
提问于 2011-02-09 20:15:03
回答 3查看 606关注 0票数 4

对于一些大学作业,我必须近似一些数字-比如用级数表示的欧拉数。因此,我必须添加非常小的数字,但我在精度方面存在问题。如果数字非常小,则不会影响结果。

代码语言:javascript
复制
real s;  //sum of all previous terms
ulong k; //factorial

s += 1.0/ k;

在每一步之后,k变得更小,但在第10轮之后,结果不再变化,停留在2.71828

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-10 23:15:20

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

代码语言:javascript
复制
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];

(最小堆将使这一过程更快一些。)

票数 3
EN

Stack Overflow用户

发布于 2011-02-09 22:58:05

固定精度浮点类型,即CPU的浮点单元(floatdoublereal)本身所支持的浮点类型,对于任何需要很多精度的计算都不是最优的,比如您给出的例子。

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

因此,将极小的数字添加到浮点值将导致这些数字丢失。当我们将以下两个浮点值相加时,看看会发生什么:

代码语言:javascript
复制
float a = 1.234567f, b = 0.0000000001234567
float c = a + b;

writefln("a = %f b = %f c = %f", a, b, c);

ab都是有效的浮点值,并且各自单独保留大约7位精度。但当添加时,只有最前面的7位数字被保留,因为它被推回到浮点数中:

代码语言:javascript
复制
1.2345670001234567 => 1.234567|0001234567 => 1.234567
                              ^^^^^^^^^^^
                         sent to the bit bucket

所以c最终等同于a,因为ab相加后的精度更高的数字被去掉了。

Here's another explanation of the concept,可能比我的好多了。

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

票数 9
EN

Stack Overflow用户

发布于 2011-02-11 01:03:09

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4944694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档