为什么这段代码导致机器崩溃?

时间:2011-07-24 16:27:23

标签: maxima

我正在尝试运行此代码,但它一直崩溃:

log10(x):=log(x)/log(10);
char(x):=floor(log10(x))+1;
mantissa(x):=x/10**char(x);
chop(x,d):=(10**char(x))*(floor(mantissa(x)*(10**d))/(10**d));
rnd(x,d):=chop(x+5*10**(char(x)-d-1),d);
d:5;
a:10;
Ibwd:[[30,rnd(integrate((x**60)/(1+10*x^2),x,0,1),d)]];
for n from 30 thru 1 step -1 do Ibwd:append([[n-1,rnd(1/(2*n-1)-a*last(first(Ibwd)),d)]],Ibwd);

Maxima在评估最后一行时崩溃。任何想法为什么会发生?

非常感谢你。

3 个答案:

答案 0 :(得分:2)

问题在于差异变为负值,并且您的舍入函数会因负面参数而死亡。为了找到这个,我把你的循环改为:

for n from 30 thru 1 step -1 do
  block([],
    print (1/(2*n-1)-a*last(first(Ibwd))),
    print (a*last(first(Ibwd))),
    Ibwd: append([[n-1,rnd(1/(2*n-1)-a*last(first(Ibwd)),d)]],Ibwd),
    print (Ibwd));

在一切都失败之前打印的最后一个差异是-316539/6125000。所以现在尝试

rnd(-1,3)

并看到同样的问题。这一切都源于你正在记录负数的事实,Maxima通过分析延续将其解释为复数。 Maxima不会对此进行评估,直到它绝对必须,并且在评估代码的某处,某些东西可能会死得很厉害。

我不知道你的具体例子的“修复”,因为我不确定你要做什么,但希望这给你足够的信息来自己找到它。

答案 1 :(得分:1)

如果你想解构浮点数,我们首先要确保它是一个浮点数。   说z: 34.1

您可以使用lisp访问bigfloat的各个部分,也可以通过?fpprec访问尾数长度。

因此?second(z)*2^(?third(z)-?fpprec)为您提供:

4799148352916685/140737488355328

bfloat(%)为您提供:

3.41b1.

如果您想将z的尾数作为整数,请查看?second(z) 现在我不确定你想要在10号基础上完成什么,但是Maxima 不在基数10中进行内部算术。
如果你想要更多或更少的位,你可以设置fpprec, 与?fpprec相关联。 fpprec是“近似基数10”的精度。 因此fpprec最初是16 ?fpprec相应地为56。

您可以轻松更改它们,例如fpprec:100 对应于335的?fpprec

如果你正在使用浮动表示,你可能会从知道中受益 你可以通过键入来查看任何一个lisp,例如, ?print(z)

使用Lisp打印函数打印内部表单。

您还可以通过跟踪跟踪任何功能,您自己的或系统功能。 例如,您可以考虑这样做:

trace(append,rnd,integrate);

如果您想使用机器浮动,我建议您使用最后一行

对于从30到1步-1的n执行:

Ibwd:append([[n-1,rnd(1/(2.0*n- 1.0)-a*last(first(Ibwd)),d)]],Ibwd);

请注意小数点。但即使这还不够,因为整合 插入精确的结构,如atan(10)。试图绕过这些东西,或计算日志 他们可能不是你想做的。我怀疑千里马不高兴,因为日志被赋予一些混乱的表达,结果证明是负面的,即使它最初认为不是这样。它将数字传递给lisp日志程序,该程序非常乐意返回适当的common-lisp复数对象。不幸的是,Maxima的大部分是在LISP HAD COMPLEX NUMBERS之前编写的。

因此,结果(log -0.5)= #C(-0.6931472 3.1415927)对于Maxima的其余部分来说完全出乎意料。 Maxima有自己的复数形式,例如3+4*%i

特别是,Maxima显示程序早于常见的lisp复数格式,并且不知道如何处理它。

错误(堆栈溢出!!!)来自显示程序,试图显示一个常见的lisp复数。

如何解决所有这些问题?好吧,您可以尝试更改程序,以便计算您真正想要的内容,在这种情况下,它可能不会触发此错误。 Maxima的显示程序也应该修复。另外,我怀疑在简化数字日志方面存在一些不利因素,这些数据是否定的,但不是很明显。

这可能是原始海报的太多信息,但也许上面的段落可以帮助,也可能在一个或多个地方改善千里马。

答案 2 :(得分:1)

您的程序似乎在Maxima的简化(代数身份)代码中触发错误。我们正在调查,希望我们很快就能修复错误。

与此同时,这是一个想法。看起来这个bug是由rnd(x,d)在x<我猜rnd应该将x舍入到d位数。处理x< 0,试试这个:

rnd(x,d):= if x< 0然后-rnd1(-x,d)否则rnd1(x,d);

rnd1(x,d):=(...把rnd的当前定义放在这里......);

当我这样做时,循环运行完成,Ibwd是一个值列表,但我不知道期望什么值。