使用MATLAB进行二项式的精度误差?

时间:2016-01-23 08:41:12

标签: matlab precision

该值是绝对整数,不是要被怀疑的浮点数,而且,它不是溢出,因为double值可以保持到2 ^ 1024。

fprintf('%f',realmax)
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

我在nchoosek函数中遇到的问题是它没有产生确切的值

fprintf('%f\n',nchoosek(55,24));
2488589544741302.000000

虽然关于binomian(n,m)=binomial(n-1,m)+binomial(n-1,m-1)的百分比误差为2,如下所示

fprintf('%f',nchoosek(55-1,24)+nchoosek(55-1,24-1))
2488589544741301.000000

Ps:确切的值为2488589544741300

this demo shows

MATLAB有什么问题?

3 个答案:

答案 0 :(得分:2)

您对realmax功能的理解是错误的。它是可以存储的最大值,但是如此大的数字,你的浮点精度误差远高于1.第一个不能存储在double值中的整数是2^53+1,try { {1}}这是一个简单的例子。

如果符号工具箱可用,最容易实现的解决方案是使用它:

2^53==2^53+1

答案 1 :(得分:1)

看起来像整数(55)的东西和实际上是整数的东西(就变量类型而言)之间存在差异。

你计算它的方式,你的值存储为浮点(这是realmax指向你的 - 最大正浮点数 - 检查intmax('int64')是否有最大可能的整数值),这样你就可以得到浮点错误。大值中的绝对差值2并非意料之外 - 实际百分比误差很小。

另外,您在格式字符串中使用%f - 例如要求它显示为浮点。

对于nchoosek具体而言,从文档中,输出作为非负标量值返回,与输入n和k的类型相同,或者,如果它们是不同类型,则返回非双重类型(如果只有一个输入类型,你只能有不同的输入类型。

在Matlab中,当您直接在函数输入中键入数字时,它通常默认为浮点数。你必须强迫它是一个整数。

尝试改为:

fprintf('%d\n',nchoosek(int64(55),int64(24)));

注意:%d不是%f,将两个输入转换为特定整数。此处nchoosek的输出应为int64类型。

答案 2 :(得分:1)

我无法访问MATLAB,但由于您显然可以使用Octave,我会发布基于此的观察结果。

如果您使用edit nchoosekhere查看Octave源代码,您会发现计算二项式系数的公式非常简单:

A = round (prod ((v-k+1:v)./(1:k)));

如您所见,有k个分区,每个分区都有可能引入一些小错误。下一行试图提供帮助,并警告您可能会失去精确度:

if (A*2*k*eps >= 0.5)
  warning ("nchoosek", "nchoosek: possible loss of precision");

所以,如果我稍微修改你的最后一个问题,那么Octave有什么问题?我会说没有错。作者显然知道不精确的可能性,并包括检查以警告用户何时出现这种可能性。所以功能按预期工作。如果您的应用程序需要比内置函数更高的精度,那么您似乎需要编写(或查找)能够更精确地计算中间结果的内容。