我正在尝试运行此代码,但它一直崩溃:
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在评估最后一行时崩溃。任何想法为什么会发生?
非常感谢你。
答案 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是一个值列表,但我不知道期望什么值。