だから私は浮動小数点の精度 (そして 1.1 のようなものを 2 進数で正確に表現できないこと) については知っていますが、疑問に思っているのは、数学関連のライブラリはどのようにして無限精度を実装しているのでしょうか? つまり、たとえば 1.1 をバイナリで正確に表すにはどうすればよいでしょうか。簡単な説明だけでも結構です。正確な詳細は自分で把握できます。ありがとう。:)
6 に答える
無限精度のライブラリはありませんが、任意精度のライブラリはあります。これらの実装方法の詳細については、いくつかのドキュメントをお読みください:-)
正確に 1.1 をバイナリで表現するために、正しく指摘しているように浮動小数点を使用することはできません。整数部分 (1) を整数として格納し、小数部分 (.1) を別の整数として格納すると表現でき、これらの構造を処理するロジックを作成する必要があります。あるいは、分母と分子の両方が整数として格納された分数 (11/10) として格納することもできます。
正確な算術演算に依存する特定の幾何学的アルゴリズムがあるため、CGAL ライブラリを見ると、さまざまな操作で「閉じられた」さまざまな正確な数値型が見つかります。つまり、サポートされている操作を使用して、正確に表現できない結果を生成する方法はありません。
いくつかの例:
整数は加算と乗算で閉じられます。
ゼロの特別な場合を除いて、有理数も割り算で閉じています。整数のペアとして表すことができます。GMP の有理数関数も参照してください。たとえば、1.1 = 11/10 は (11, 10) と表すことができます。
平方根も閉じている数値型。
数値を 10 進数で表し、10 進数の演算を行うこともできます。基になる表現は、各桁がバイナリ コードで表されるという意味でバイナリです。各桁は、小数点の左側か右側かに関係なく、整数として扱われます。その後、算術は「手動で」桁ごとに行われます。
10 進数ベースのライブラリの一例は、PHP の BCMath です。
無限精度の数学ライブラリは実装されていません。それはできません。数値 1/3 は、分数以外の有限数のビットで表すことはできません。pi や e のような超越数は、どのような方法でも完全に表すことはできません。
一方、非常に正確な数学ライブラリを作成することは可能です。それはすべて、浮動小数点値の仮数に十分なビットを割り当てることの問題です。
浮動小数点数と浮動小数点数について話しているとき、Pax は完全にここにありますが、解決策はあると思いますが、それは非常に非効率的です。
文字列を使用して数値を表すことができます。文字列は精度を失いません。
「0.0001」+「0.1」のような数値がある場合は常に、両方の文字列を繰り返し、現在の位置のみを int に変換します。
ステップ 1:
0 + 0 = 0 -> 文字列に変換し、data[0] に割り当てます。
ステップ 2:
0 + 1 = 1 -> 文字列に変換し、data[1] に割り当てます。
ステップ 3:
iter > "0.1".length() -> 停止。