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

发布于 2024-11-25 23:51:07 字数 454 浏览 5 评论 0原文

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

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 在计算最后一行时崩溃。有什么想法可能会发生吗?

太感谢了。

I am trying to run this code but it keeps crashing:

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 crashes when it evaluates the last line. Any ideas why it may happen?

Thank you so much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

高速公鹿 2024-12-02 23:51:08

问题是差值变为负值,并且您的舍入函数因负参数而严重死亡。为了找到这一点,我将循环更改为:

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 直到绝对必要时才会对此进行评估,并且在评估代码中的某个地方,有些东西正在可怕地消失。

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

The problem is that the difference becomes negative and your rounding function dies horribly with a negative argument. To find this out, I changed your loop to:

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));

The last difference printed before everything fails miserably is -316539/6125000. So now try

rnd(-1,3)

and see the same problem. This all stems from the fact that you're taking the log of a negative number, which Maxima interprets as a complex number by analytic continuation. Maxima doesn't evaluate this until it absolutely has to and, somewhere in the evaluation code, something's dying horribly.

I don't know the "fix" for your specific example, since I'm not exactly sure what you're trying to do, but hopefully this gives you enough info to find it yourself.

且行且努力 2024-12-02 23:51:08

如果你想解构一个浮点数,我们首先要确保它是一个bigfloat。
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);

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

for n from 30 thru 1 step -1 do :

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

注意小数点。但即便如此还不够,因为整合
插入精确的结构,如 atan(10)。尝试舍入这些东西,或计算日志
其中可能不是您想要做的。我怀疑 Maxima 不高兴,因为 log 被赋予了一些混乱的表达式,结果却是负面的,尽管它最初是这么认为的。它将数字交给 lisp 日志程序,该程序非常乐意返回适当的 common-lisp 复数对象。不幸的是,Maxima 的大部分内容是在 LISP 拥有复数之前编写的。

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

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

错误(堆栈溢出!!!)来自于显示程序试图显示一个 Common Lisp 复数。

如何解决这一切?好吧,您可以尝试更改程序,以便它计算您真正想要的内容,在这种情况下,它可能不会触发此错误。 Maxima 的显示程序也应该得到修复。另外,我怀疑负数对数的简化有一些不幸的地方,但并不明显如此。

对于原始海报来说,这可能是太多的信息,但也许上面的段落会有所帮助,并且还可能在一个或多个地方改进 Maxima。

If you want to deconstruct a floating point number, let's first make sure that it is a bigfloat.
say z: 34.1

You can access the parts of a bigfloat by using lisp, and you can also access the mantissa length in bits by ?fpprec.

Thus ?second(z)*2^(?third(z)-?fpprec) gives you :

4799148352916685/140737488355328

and bfloat(%) gives you :

3.41b1.

If you want the mantissa of z as an integer, look at ?second(z)
Now I am not sure what it is that you are trying to accomplish in base 10, but Maxima
does not do internal arithmetic in base 10.
If you want more bits or fewer, you can set fpprec,
which is linked to ?fpprec. fpprec is the "approximate base 10" precision.
Thus fpprec is initially 16
?fpprec is correspondingly 56.

You can easily change them both, e.g. fpprec:100
corresponds to ?fpprec of 335.

If you are diddling around with float representations, you might benefit from knowing
that you can look at any of the lisp by typing, for example,
?print(z)

which prints the internal form using the Lisp print function.

You can also trace any function, your own or system function, by trace.
For example you could consider doing this:

trace(append,rnd,integrate);

If you want to use machine floats, I suggest you use, for the last line,

for n from 30 thru 1 step -1 do :

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

Note the decimal points. But even that is not quite enough, because integration
inserts exact structures like atan(10). Trying to round these things, or compute log
of them is probably not what you want to do. I suspect that Maxima is unhappy because log is given some messy expression that turns out to be negative, even though it initially thought otherwise. It hands the number to the lisp log program which is perfectly happy to return an appropriate common-lisp complex number object. Unfortunately, most of Maxima was written BEFORE LISP HAD COMPLEX NUMBERS.

Thus the result (log -0.5)= #C(-0.6931472 3.1415927) is entirely unexpected to the rest of Maxima. Maxima has its own form for complex numbers, e.g. 3+4*%i.

In particular, the Maxima display program predates the common lisp complex number format and does not know what to do with it.

The error (stack overflow !!!) is from the display program trying to display a common lisp complex number.

How to fix all this? Well, you could try changing your program so it computes what you really want, in which case it probably won't trigger this error. Maxima's display program should be fixed, too. Also, I suspect there is something unfortunate in simplification of logs of numbers that are negative but not obviously so.

This is probably waaay too much information for the original poster, but maybe the paragraph above will help out and also possibly improve Maxima in one or more places.

乖不如嘢 2024-12-02 23:51:08

您的程序似乎在 Maxima 的简化(代数恒等式)代码中触发了错误。我们正在调查,希望尽快修复错误。

与此同时,这里有一个想法。看起来当 x < 时,该错误是由 rnd(x, d) 触发的。 0.我猜 rnd 应该将 x 舍入为 d 位。处理 x < 0,试试这个:

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

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

当我这样做时,循环将运行至完成,并且 Ibwd 是一个值列表,但我不知道需要什么值。

It appears that your program triggers an error in Maxima's simplification (algebraic identities) code. We are investigating and I hope we have a bug fix soon.

In the meantime, here is an idea. Looks like the bug is triggered by rnd(x, d) when x < 0. I guess rnd is supposed to round x to d digits. To handle x < 0, try this:

rnd(x, d) := if x < 0 then -rnd1(-x, d) else rnd1(x, d);

rnd1(x, d) := (... put the present definition of rnd here ...);

When I do that, the loop runs to completion and Ibwd is a list of values, but I don't know what values to expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文