浮動小数点はどのように格納されるのでしょうか?それはいつ重要ですか?
-
09-06-2019 - |
質問
フォローアップで この質問, 、一部の数値は浮動小数点でまったく表現できず、代わりに近似されているようです。
浮動小数点数はどのように格納されるのでしょうか?
さまざまなサイズに共通の規格はありますか?
浮動小数点を使用する場合、どのような注意が必要ですか?
言語間の互換性はありますか (つまり、浮動小数点数を Python プログラムから C プログラムに TCP/IP 経由で送信するにはどのような変換に対処する必要がありますか)?
-アダム
解決
前述したように、 IEEE 754 に関するウィキペディアの記事 ほとんどのシステムで浮動小数点数がどのように格納されるかをうまく示しています。
ここで、一般的な注意点をいくつか示します。
- 最も大きな点は、2 つの浮動小数点数が等しい (または不等である) かどうかを比較する必要がほとんどないことです。代わりに、「より大きい」/「より小さい」比較を使用することをお勧めします。
- 浮動小数点数に対して実行する演算が増えるほど、丸め誤差が大きくなる可能性があります。
- 精度は分数のサイズによって制限されるため、数桁離れた数値を正しく加算できない場合があります。(たとえば、1E-30 を 1E30 に追加することはできません。)
他のヒント
浮動小数点数に関する問題については、記事で詳しく説明されています。 すべてのコンピュータ科学者が浮動小数点演算について知っておくべきこと.
基準は IEEE 754.
もちろん、IEE754 が十分ではない場合に数値を保存する他の手段もあります。Javaのようなライブラリ BigDecimal
ほとんどのプラットフォームで使用でき、SQL の数値型に適切にマップされます。シンボルは無理数に使用でき、2 進数または 10 進数の浮動小数点で正確に表現できない比率を比率として保存できます。
質問の 2 番目の部分に関しては、プロジェクトにとってパフォーマンスと効率が重要でない限り、浮動小数点データを文字列として TCP/IP 経由で転送することをお勧めします。これにより、バイト アライメントなどの問題を回避でき、デバッグが容易になります。
基本的に、浮動小数点数で心配する必要があるのは、精度の桁数が限られているということです。これにより、等価性をテストするときや、プログラムが実際にそのデータ型で得られる精度よりも多くの桁数の精度を必要とする場合に問題が発生する可能性があります。
C++ では、経験則として、float では 7 桁の精度が得られ、double では 15 桁の精度が得られると考えてください。また、同等性をテストする方法に興味がある場合は、次を参照してください。 これ 質問スレッド。
この質問のフォローアップでは、いくつかの数値は浮動点によって表すことができず、代わりに近似されているようです。
正しい。
浮動小数点数はどのように格納されるのでしょうか?さまざまなサイズに共通の規格はありますか?
他のポスターがすでに述べたように、ほぼ独占的にIEEE754とその後継IEE754R。グーグルで検索すると、ビットパターンとその説明とともに何千もの説明が得られます。それでも入手に問題がある場合は、依然として一般的な FP 形式が 2 つあります。IBMとDEC-VAX。一部の難解な機械とコンパイラ(Blitzbasic、Turbopascal)には、奇妙な形式がいくつかあります。
浮動小数点を使用する場合、どのような注意が必要ですか?それらは横断的な互換性がありますか(つまり、PythonプログラムからTCP/IPを介してCプログラムに浮動小数点数を送信するためにどのような変換を扱う必要がありますか)?
実質的には何もなく、言語間の互換性があります。
非常にまれに発生する癖:
IEEE754 では、sNaN (シグナリング NaN) と qNaN (クワイエット NaN) が定義されています。前者は、ロードされた場合にプロセッサにハンドラー ルーチンの呼び出しを強制するトラップを引き起こします。後者はこれを行いません。言語設計者は、sNaN がワークフローを中断する可能性を嫌い、sNaN をサポートするとハンドラー ルーチンのサポートが強制されるため、sNaN はほとんどの場合、黙って qNaN に変換されます。したがって、1:1 の生の変換に依存しないでください。しかし、また次のようになります。これは非常にまれであり、ナンが存在する場合にのみ発生します。
異なるコンピュータ間でファイルを共有すると、エンディアンの問題 (バイトの順序が間違っている) が発生する可能性があります。数値に対して NaN が得られるため、これは簡単に検出できます。
はい、あります 2 進浮動小数点演算の IEEE 標準 (IEEE 754)
数値は、バイナリで格納される場合、符号、指数、分数の 3 つの部分に分割されます。
これ 記事 「IEEE 標準 754 浮動小数点数」が役に立つかもしれません。正直に言うと、あなたの質問を理解できているかどうか完全に自信がありませんので、これが役立つかどうかはわかりませんが、役立つことを願っています。
浮動小数点の丸め誤差が本当に心配な場合は、ほとんどの言語で浮動小数点誤差のないデータ型が提供されています。SQL Server には、Decimal データ型と Money データ型があります。.Net には Decimal データ型があります。Java の BigDecimal のような無限の精度ではありませんが、定義されている小数点以下の桁数まで正確です。したがって、$4.58 として入力したドル値が浮動小数点値 4.579999999999997 として保存されることを心配する必要はありません。
私が覚えているのは、32 ビット浮動小数点は実際の数値に 24 ビットを使用して格納され、残りの 8 ビットは 10 の累乗として使用され、小数点の位置が決定されるということです。
この件に関しては少し話が逸れてしまいましたが...