5

私は2つの非常に大きな数に対して簡単な減算演算をしようとしています。科学記法変換 - スキーム

(- 1.8305286640724363e+023 (floor 1.8305286640724363e+023)) 

これを実行すると、結果は0.0になります。私はその答えを与えるだろう

(- 1.8305286640724363e+023 (floor 1.8305286640724363e+023)) => .2439521 

拡大科学表記法:私はの出力を期待しています。

183052866407243622723319.24395251から183052866407243622723319.00 = 0.2439521

科学表記とは対照的に、私は、彼らがそうであるような場所での十進数で、これらの番号を表したいので、私は望ましい結果を達成することができます。スキーム内でこれを行う方法はありますか?どのようなヘルプ、ガイダンス、またはリファレンスも高く評価されます:)

私は、Windows 64bitとR5RS言語用のDrRacketを使用しています。

EDIT

は、私は私が行ってるthearithmeticの例について、できるだけ具体的にしたい考え出しました。

算術:

(* 271979577247970257395 0.6180339887) => 1.6809262297150285e+020 

計算は、この同じ乗算をやって、結果yeilds => 168092622971502827156.7975214365

正確または不正確な使用しようとしたとき、私はこの取得:

(exact (* 271979577247970257395 0.6180339887)) => exact: undefined; 
(inexact (* 271979577247970257395 0.6180339887)) => inexact: undefined; 

を私はR5RSが正確/不正確をサポートしていないと思いますか?私はそれを見て、例がinexact-使用することを示して>正確な手順私は、これだので:それでは、私は使用してみました

(exact->inexact (* 271979577247970257395 0.6180339887)) => 1.6809262297150285e+020 

(inexact->exact (* 271979577247970257395 0.6180339887)) => 168092622971502854144 

そして、ちょうど特異性のために、私は反対をしました誰かが言ったように大きなフロート:

(bf-precision 128) 
(bf (* 271979577247970257395 0.6180339887)) => (bf 168092622971502854144) 

正確な出力と同じ出力を与えます。私が望むのは、計算機から得られる数値を保存することだけです。非常に難しい作業のようです。私はこれを取得していないために馬鹿に聞こえるかもしれない、申し訳ありませんが、ちょうど私がSCHEMEの極端なアマチュアであることを覚えておいてください。あなたの助けをもう一度ありがとう! :)

答えて

4

問題は、ラケットがその内部表現で使用する よりも入力に有効数字があることです。

は、私たちは裸の数字を入力してみましょう:

> 183052866407243622723319.24395251 
1.8305286640724363e+23 

> 183052866407243622723319.00 
1.8305286640724363e+23 

どちらの数字は、このように内部的に同じ(全体)の数として表現されています。 結果が0であった理由を説明します。

この動作はラケットに限定されません。実際に、Racketは64ビット浮動小数点数での計算のIEEE標準に準拠しています。他のプログラミング言語でも同じ結果が得られます。

なぜより精度が高いのかを計算する必要がある場合は、代わりにbigfloatsを使用できます。

(require math/bigfloat) 
(bf-precision 128) ; use 128 bits 
(bf- (bf #e183052866407243622723319.24395251) 
    (bfround (bf #e183052866407243622723319.00))) 

結果は次のとおりです。 (BF番号のe0.2439525099999997337363311089575290679932)

注:ビッグフロートを使用するには、あなたがラケットの最新バージョンを持っていることを確認してください。

更新:なぜ結果が.2439521でなかったのか疑問が生じた場合、 の答えは、結果と.2439521が同じ内部ビットパターンで表されるということです。

更新:

あなたが戻って標準の浮動小数点に結果を有効にする場合は、bigfloat->flonumを使用しています。

(bf-precision 256) ; to get more decimal digits correct 
(bigfloat->flonum 
    (bf- (bf #e183052866407243622723319.24395251) 
     (bfround (bf #e183052866407243622723319.00)))) 

これは結果を与える:0.24395251

補遺:

ラケット(およびスキーム)を浮動小数点数として小数点と番号を読み出します。番号の前に#eを付けると、それは正確な数値として読み取られます(結果の値は正確な小数です)。正確な小数点を維持するためにこれを使うことができます。計算全体の正確な数値を入力し、最後にexact->inexactを使用して結果を浮動小数点数に変換します。ここではあなたの例である:もちろん

> (exact->inexact 
    (- #e183052866407243622723319.24395251 
     #e183052866407243622723319.00)) 
0.24395251 
+0

こんにちは、ご連絡いただきありがとうございます。ビッグフロートは私に小数点を与えてくれません。私はあなたが強制的に小数点以下を話しているのを見てから、引き算をしています。浮動小数点数を取得するために算術演算を実行しています。私はあなたにあなたを見せることができるように質問を更新します。 – Sixers17

+0

こんにちは。私は、結果を標準浮動小数点数に戻す方法を示すアップデートを追加しました。 – soegaard

+0

私はbigfloatsを使用する代わりの方法を追加しました。 – soegaard

4

、スキームであなたが正確な数字を持っている:

(define x (+ (exact 183052866407243622723319) (exact .24395251))) 
(define y (+ (exact 183052866407243622723319) (exact .0))) 

私はSchemeの読者が値を切り捨てることを避けるためにxを分割します。次に:

> x 
3297587283763054256749149618043779713285/18014398509481984 
> (- x y) 
4394657732528389/18014398509481984 
> (inexact (- x y)) 
0.24395251 

[編集]計算の間、正確な数値を使用する必要があります。つまり、入力を正確に変換し、最後に不正確な形で出力を変換することを意味します(必要な場合)。

#e(* 27... 0.6...)であなたの試行は#eが式ではなく数値に適用されるため、これは機能しません。 (* #e27... #e0.6...)を使用してください。

> (* #e271979577247970257395 #e0.6180339887) 
336185245943005654313595042873/2000000000 
+0

大きな数値に明示的に小数点以下の桁を追加しています。この例は、不正確で不正確でないことを知らなかったいくつかのことを私に教えてくれましたが、算術演算によって10進数を生成しようとしています。私の更新を参照してください。お返事ありがとうございます! – Sixers17

+0

私は明示的に小数点を追加しました。なぜなら、浮動小数点数として入力した場合、 'exact'を適用した時点ではそれが遅すぎるからです。これを解決するには、数値自体の接頭辞として '#e'を使用します。注:上記の編集を参照してください。 – GoZoner

+0

更新ありがとうございます!私はあなたの助けを借りてこれを回避する方法を見つけました!おかげで多くのGoZoner! – Sixers17