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 は最終行を評価するときにクラッシュします。なぜそれが起こるのでしょうか?

どうもありがとう。

4

3 に答える 3

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は、絶対に必要になるまでこれを評価せず、評価コードのどこかで、何かがひどく死にかけています。

あなたが何をしようとしているのか正確にはわからないので、あなたの特定の例の「修正」はわかりませんが、うまくいけば、これはあなた自身でそれを見つけるのに十分な情報をあなたに与えるでしょう。

于 2011-07-27T21:45:55.517 に答える
2

浮動小数点数を分解したい場合は、まずそれが 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 は?fpprecof 335 に対応します。

フロート表現をいじっている場合は、次のように入力して任意の Lisp を表示できることを知っておくと役立つ場合があります。 ?print(z)

これは、Lisp print 関数を使用して内部フォームを出力します。

トレースによって、独自の関数またはシステム関数の任意の関数をトレースすることもできます。たとえば、これを行うことを検討できます。

trace(append,rnd,integrate);

マシン フロートを使用する場合は、最後の行に次を使用することをお勧めします。

n が 30 から 1 ステップ -1 の場合:

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

小数点に注意してください。しかし、統合は atan(10) のような正確な構造を挿入するため、それでも十分ではありません。これらを丸めたり、それらのログを計算したりすることは、おそらくやりたいことではありません。log は、最初はそうではないと考えていたにもかかわらず、負であることが判明した厄介な表現を与えられているため、Maxima が不満を持っているのではないかと思います。これは、適切な common-lisp 複素数オブジェクトを返すことを完全に喜んでいる Lisp ログ プログラムに数値を渡します。残念なことに、Maxima のほとんどは、LISP が COMPLEX NUMBERS を持つ前に書かれました。

したがって、(log -0.5)= #C(-0.6931472 3.1415927)Maxima の残りの部分にとって、結果はまったく予想外です。Maxima には、複素数に対して独自の形式があります3+4*%i

特に Maxima 表示プログラムは、一般的な Lisp 複素数形式よりも前のものであり、それをどう処理すればよいかわかりません。

エラー (スタック オーバーフロー !!!) は、一般的な Lisp 複素数を表示しようとしている表示プログラムによるものです。

これをすべて修正する方法は?実際に必要なものを計算するようにプログラムを変更してみてください。その場合、おそらくこのエラーは発生しません。Maxima の表示プログラムも修正する必要があります。また、負であるが明らかにそうではない数の対数の単純化には、何か不幸があるのではないかと思います。

これは元の投稿者にとっては情報量が多すぎるかもしれませんが、上記の段落が役立つかもしれませんし、1 つまたは複数の場所で Maxima を改善する可能性もあります。

于 2011-07-27T23:19:19.360 に答える
1

あなたのプログラムは Maxima の単純化 (代数恒等式) コードでエラーを引き起こしているようです。現在調査中であり、バグ修正がすぐに行われることを願っています。

そんな中、こんなアイデアが。x < 0 の場合に rnd(x, d) によってバグが引き起こされるようです。rnd は x を d 桁に丸める必要があると思います。x < 0 を処理するには、次のようにします。

rnd(x, d) := x < 0 の場合 -rnd1(-x, d) それ以外の場合 rnd1(x, d);

rnd1(x, d) := (... rnd の現在の定義をここに置く ...);

これを行うと、ループは最後まで実行され、Ibwd は値のリストになりますが、期待する値がわかりません。

于 2011-07-30T22:30:36.687 に答える