mathematica中一个非常奇怪的问题

时间:2011-03-30 23:03:48

标签: wolfram-mathematica

我在mma v7.0中这样做:

r[x_] := Rationalize[x, 0]; N[Nest[Sqrt, 10., 53] // r, 500]

它给了我 1.000000000000000222044604925031308084726333618164062500000000000000000

然而,如果我更进一步 N[Nest[Sqrt, 10., 54] // r, 500]

我全部为零。有人知道解释,还是错误?

此外,从解决方案Nest[Sqrt, 10., 53]生成更多数字的方式看起来效果不佳。如何获得更有效的数字用于此计算?

非常感谢。

修改

如果我Nest[Sqrt, 10., 50],我仍然有很多有效数字。

2 个答案:

答案 0 :(得分:4)

如果您执行此操作54次,则除零之外没有有效数字。因此,你所做的合理化(简单地保留位模式)就可以得到你所看到的。

InputForm[n53 = Nest[Sqrt, 10., 53]]

缺货[180] // InputForm = 1.0000000000000002

InputForm[n54 = Nest[Sqrt, 10., 54]]

缺货[181] // InputForm = 1。

Rationalize[n53, 0]

4503599627370496分之4503599627370497

Rationalize[n54, 0]

出[183]​​ = 1

对于好奇:问题不是在迭代计算的退化意义上的精度损失。实际上,迭代这些平方根实际上提高了精度。我们可以通过bignum输入看到这一点。

InputForm[n54 = Nest[Sqrt, 10.`20, 54]]

缺货[188] // InputForm = 1.0000000000000001278191493200323453724568038240908339267044`36.25561976585499

这是实际问题。当我们使用机器编号然后在54次迭代之后,在结果机器double中没有除零之外的有效数字。也就是说,我们对数字的大小限制是原因。

原因不是太神秘。调用结果值1 + eps。然后我们将(1 + eps)^(2 ^ 54)等于(近似逼近)到10.然后二阶扩展显示eps必须小于机器epsilon。

InputForm[epsval = 

首先[选择[     eps /。 N [求解[Sum [eps ^ j *二项式[2 ^ 54,j],{j,2}] == 9,eps]],     头[#] === Real&& #> 0&]]] 出[237] // InputForm = 1.864563472253985 * ^ - 16

$MachineEpsilon

出[235] = 2.22045 * 10 ^ -16

Daniel Lichtblau Wolfram Research

答案 1 :(得分:3)

InputForm /@ NestList[Sqrt, 10., 54]

10.
3.1622776601683795
1.7782794100389228
1.333521432163324
1.1547819846894583
1.0746078283213176
1.036632928437698
1.018151721718182
1.0090350448414476
1.0045073642544626
1.002251148292913
1.00112494139988
1.0005623126022087
1.00028111678778
1.0001405485169472
1.0000702717894114
1.000035135277462
1.0000175674844227
1.0000087837036347
1.0000043918421733
1.0000021959186756
1.000001097958735
1.0000005489792168
1.0000002744895706
1.000000137244776
1.0000000686223856
1.000000034311192
1.0000000171555958
1.0000000085777978
1.0000000042888988
1.0000000021444493
1.0000000010722245
1.0000000005361123
1.0000000002680562
1.0000000001340281
1.000000000067014
1.000000000033507
1.0000000000167535
1.0000000000083769
1.0000000000041884
1.0000000000020943
1.0000000000010472
1.0000000000005236
1.0000000000002618
1.000000000000131
1.0000000000000655
1.0000000000000329
1.0000000000000164
1.0000000000000082
1.000000000000004
1.000000000000002
1.0000000000000009
1.0000000000000004
1.0000000000000002
1.

投掷N[x, 500]就像试图从岩石中挤水一样。


上述计算以机器精度完成,速度非常快。如果您愿意放弃速度,可以通过在输入值上指定非机器精度来利用Mathematica's arbitrary precision arithmetic。 “反引号”可用于执行此操作(如下例所示),也可以使用SetPrecisionSetAccuracy。在这里,我将指定输入是10到20位精度的数字。

NestList[Sqrt, 10`20, 54]

10.000000000000000000
3.1622776601683793320
1.77827941003892280123
.
.
.
1.00000000000000051127659728012947952
1.00000000000000025563829864006470708
1.000000000000000127819149320032345372

正如您所看到的,您不需要使用InputForm,因为Mathematica会自动将任意精度数字打印到尽可能多的地方。

如果你使用InputFormFullForm,你会看到一个反引号,然后是一个数字,这是该数字的当前精确度。