0

2 進 (または binaryoid) 浮動小数点を使用し、結果を 10 進数で表すときの複雑さを理解しています。

1 (do ((numerator 1 (* 10 numerator)))
 2     ((>= numerator 1000000000000))
 3   (let ((fred (list 'coerce (/ numerator 3) (quote 'double-float))))
 4     (prin1 fred)
 5     (princ " ")
 6     (prin1 (eval fred))
 7     (terpri)))
(COERCE 1/3 'DOUBLE-FLOAT) 0.3333333333333333d0
(COERCE 10/3 'DOUBLE-FLOAT) 3.3333333333333335d0
(COERCE 100/3 'DOUBLE-FLOAT) 33.333333333333336d0
(COERCE 1000/3 'DOUBLE-FLOAT) 333.3333333333333d0
(COERCE 10000/3 'DOUBLE-FLOAT) 3333.3333333333335d0
(COERCE 100000/3 'DOUBLE-FLOAT) 33333.333333333336d0
(COERCE 1000000/3 'DOUBLE-FLOAT) 333333.3333333333d0
(COERCE 10000000/3 'DOUBLE-FLOAT) 3333333.3333333335d0
(COERCE 100000000/3 'DOUBLE-FLOAT) 3.3333333333333332d7
(COERCE 1000000000/3 'DOUBLE-FLOAT) 3.333333333333333d8
(COERCE 10000000000/3 'DOUBLE-FLOAT) 3.3333333333333335d9
(COERCE 100000000000/3 'DOUBLE-FLOAT) 3.3333333333333332d10

しかし、私はその最後の可変桁の不運を避けたいと思っています. この状況では、計算速度は私にとって重要ではありません。

真の 10 進浮動小数点 LISP パッケージは存在しますか?

編集 1 : 理想的には、bignum が整数に対して行うように、このパッケージは任意の精度を許可します。

編集 2、Dennis Jaheruddin の質問に応えて:

[I]最後の桁には関心がなく、数値を同じにしたい場合は、最初の 15 桁程度を観察するだけでよいでしょうか?

私はそれについて考えました。うまくいきません。たとえば、2/3 の場合、666667 のような値が必要です。

 1 (do ((numerator 2 (* 10 numerator)))
 2     ((>= numerator 1000000000000))
 3   (let ((fred (list 'coerce (/ numerator 3) (quote 'double-float))))
 4     (prin1 fred)
 5     (princ " ")
 6     (prin1 (eval fred))
 7     (terpri)))
(COERCE 2/3 'DOUBLE-FLOAT) 0.6666666666666666d0
(COERCE 20/3 'DOUBLE-FLOAT) 6.666666666666667d0
(COERCE 200/3 'DOUBLE-FLOAT) 66.66666666666667d0
(COERCE 2000/3 'DOUBLE-FLOAT) 666.6666666666666d0
(COERCE 20000/3 'DOUBLE-FLOAT) 6666.666666666667d0
(COERCE 200000/3 'DOUBLE-FLOAT) 66666.66666666667d0
(COERCE 2000000/3 'DOUBLE-FLOAT) 666666.6666666666d0
(COERCE 20000000/3 'DOUBLE-FLOAT) 6666666.666666667d0
(COERCE 200000000/3 'DOUBLE-FLOAT) 6.6666666666666664d7
(COERCE 2000000000/3 'DOUBLE-FLOAT) 6.666666666666666d8
(COERCE 20000000000/3 'DOUBLE-FLOAT) 6.666666666666667d9
(COERCE 200000000000/3 'DOUBLE-FLOAT) 6.6666666666666664d10

ご覧のとおり、最後の桁を使用して切り上げるかどうかを判断することさえできません。64 は 70 ではなく 60 に丸められます。ただし、最後の桁を破棄し、前の桁を使用して残りの数値を丸めることができます。ただし、(a) この時点で多くの精度を破棄し始めており、(b) これにより間違った方法で丸められるケースがないかどうかわからないため、これには不快です。 . できれば任意の精度を持つ 10 進浮動小数点パッケージが理想的です。

編集 3 : Rainer Joswig が以下の回答で指摘しているように、移植性のない潜在的な解決策は、浮動小数点の精度を設定することです。自宅でフォローしている人のために、彼はここで、これが次のように行われていることを指摘しています。(SETF (EXT:LONG-FLOAT-DIGITS) n)

編集 4 : 彼の回答の後のコメントで、Rainer Joswig は代数システム Maxima と Axiom を調べることを推奨しています。そうすることで、次の優れたウィキペディアのリソースにつながります。

編集 5:その後、10 進浮動小数点パッケージは必要ないと判断しましたが、パッケージがあるかどうかについてはまだ興味があります。たぶんないです。

なぜ私はそれを必要としないのですか?答えは、(a) Rainer Joswig の wu-decimal パッケージへのポインターと (b) wvxvw の長い除算への言及の組み合わせです。

wu-decimal には、基数 10 を使用する従来の特性と仮数部はありませんが、数値を比率として格納するという興味深いアイデアが導入されています。したがって、1/3 は 1/3 として格納され、(有限長の) 2 進小数の繰り返しではありません。比率として格納された数値を乗算すると、すぐに非常に長い比率が得られますが、元の精度は最後まで維持されます。そのアイデアを使ってみます。私が必要としないのは、wu-decimal の非常に気の利いた解析と、必要に応じて比率を 10 進数として書き込むことです。そのため、パッケージをインストールしません。このような値の解析と書き込みを簡単にすることに興味がある場合は、パッケージをチェックしてください。(私はそれを使用していません。)

残っているのは、比率を 10 進数として出力することです。このために、wvxvw と同じように長除算を使用します。私のコードは多少異なりますが、長い除算のアイデアについては、彼に感謝します。

4

1 に答える 1

1

使用したことはありません:

http://wukix.com/lisp-decimals

GNU CLISP では、float の精度を設定できます。

于 2012-10-10T18:48:54.947 に答える