フロートが過去に目的を果たした理由を理解しています。そして、今日のシミュレーションの例でそれらがなぜ役立つのかを理解できると思います。しかし、私はそれらの例は一般的なものよりも例外的だと思います。したがって、単純なシミュレーションでは、浮動小数点数が非常に高精度の整数よりも普及している理由がわかりません。
古典的な議論は、浮動小数点数はより広い範囲を提供しますが、高精度整数はこの課題に今すぐ対応できるというものです。たとえば、最新の64ビットプロセッサでは、最大2 ^ 64の高速整数計算を実行できます。太陽系の幅は100億km弱です。 100億kmを2 ^ 64で割ると、約5ミクロンになります。太陽系内の位置を人間の髪の毛の半分の精度で十分に表現することはできませんか?
反対に、浮動計算からの丸め誤差は問題を引き起こす可能性があります。計算に誤ってエラーを導入していないことを確認するために、計算の規模を考慮する必要があります。
では、なぜパーソナルコンピュータにFPUが必要になるのでしょうか。フロートをスパコンに任せてみませんか?
浮動小数点数に対するあなたの主張は非常に脆弱です。 (ここで問題はありません。あなたの質問は実際には非常に興味深いと思います。私の答えもそうなることを願っています。)
古典的な議論は、浮動小数点数はより広い範囲を提供しますが、高精度整数はこの課題に今すぐ対応できるというものです。たとえば、最新の64ビットプロセッサでは、最大2 ^ 64の高速整数計算を実行できます。太陽系の幅は100億km弱です。 100億kmを2 ^ 64で割ると、約5ミクロンになります。太陽系内の位置を人間の髪の毛の半分の精度で十分に表現することはできませんか?
あなたは暗黙のステートメントを作っているようです。それによれば、問題のスケールがわかったら、このスケールに関してfixed point算術を使用してその問題を解決できます。
時々、これは有効なアプローチであり、これはTeXで距離計算を実装するためにKnuthによって選ばれたものです。この場合、固定小数点演算を適切に使用するのは、計算内に現れるすべての量が整数または植字問題で発生する距離のいずれかであることです。アプリケーションの分野は非常に狭いため、人間の目で認識できるよりもはるかに小さい非常に小さい単位長を選択し、すべての量をこの単位の倍数に変換することは理にかなっています。これは非常に重要な結果につながります。この数値の表現に依存する印刷上の問題では、2つの長さを乗算する必要がないため、固定小数点演算での乗算による精度の損失が発生しません。
ほとんどの場合、しかしそれはひどいアプローチです、ここにいくつかの理由があります:
物理定数が存在し、常にそれらの単位を賢明な方法で調整できるとは限りません。
太陽系の設定を検討してください。重力定数は6.67×10−11 N・(m/kg)2、光速は3.00x10 + 5 m/s、太陽の質量は1.9891×10 + 30 kg、地球の質量は5.97219×10 + 24。固定小数点設定では、重力定数を満足のいく精度で表すことができません。したがって、単位を変更します。しかし、そうすることで、各数値を置き換え、よく知られている一般的な量を不可解な値に置き換える必要があります。さらに、必要なすべての定数を適切に表すシステムを見つけることさえ不可能である可能性が非常に高いです。速度が光速に近い無限小粒子を扱う量子物理学を考えてみてください。
数学的な単位のない定数が存在します。
単位を付けないPi 3.1415の値(小数点第4位まで)。実際には、任意の固定小数点システムでは正確に表すことができない同様の便利な定数がたくさんあります。あなたが説明した太陽系の設定では、私たちはPiを小数点以下6桁で表すことができます。これは、たとえば惑星軌道の円周を計算するときにひどい精度を与えます。
固定小数点システムでは、計算する量のサイズを事前に知る必要があります。
重力定数の値がまだわからないとします。多くの測定を行い、その定数の近似値を見つけるコンピュータープログラムを作成します。残念ながら、あなたが説明した太陽系の設定では、重力定数は0で表されます。これは、
計算。
一部の数学関数は、その成長率が原因で、固定精度演算ではうまく機能しません。
最も重要なものは、指数関数とガンマ関数です。これは、事実上、多項式以外のものを扱うすべてのプログラムに欠陥があることを意味します。
固定小数点演算では、数値を正しく乗算および除算することは非常に困難です。
これは、数値のサイズアプリオリがわからない場合、その積が表現に収まるかどうかを判断できないためです。つまり、各乗算の前に手動で精度のアンダーフローをチェックする必要があります。
あなたの質問の結論は、固定小数点演算は万能な計算には十分であり、浮動小数点演算はスーパー計算機に予約する必要があることを意味しますが、それはまさにその逆です。浮動小数点演算は非常に優れた非常に賢明なツールです万能の計算では、固定小数点は非常に特定の、よく分析されたケースでのみうまく機能します。
整数に切り替えても何も解決されないからです。フロートの問題は、フロートが不正確であることではなく、フロートを使用している人の半数が、何が起こっているのか注意を払っていないということです。それらの同じ人々は、彼らが整数を使用するとき、彼らが使用しているユニットに適切な注意を払うつもりはありません、そして、異なるセットアップが起こります。
私の後に繰り返してください:特効薬はありません。
宇宙の物理的特性(その中の原子の数など)は、数値サイズの境界を決定するのに役立ちません。これは、より広い範囲の数値を使用して有用な計算が行われるためです。
浮動小数点数は、精度と範囲の間のトレードオフです。それらは、より大きな範囲を達成するために、意図的にある程度の精度をあきらめます。
日常生活で使用するほとんどのプロセッサはnotであり、非常に高速な整数計算や大量のスペースを備えた現代の64ビットプロセッサです。ほとんどのプロセッサは8-16ビットデバイスで、車、電子レンジ、時計などを実行します。
さらに、ガロンの半分や人間の髪の毛など、ユニットの半分について話す必要がある場合はどうなりますか?整数は素晴らしいですが、6.4216×10のような表記法で話すことになります30 これは正確ですが、人間が自然に考える方法ではありません。
高精度整数の代わりに浮動小数点数を使用すると(変換あり!)単純に簡単で高速です。入力できます
float myVar = 0.15; //my value...
シミュレーションの残りのロジックに移ります。 int
への変換について考えたり、すべてのスケールが正しいことを確認したりするために余分な時間を費やす必要はありません。
そして、結果は最終的に十分に良いです。私は、私の仕事の中で、開発の速度をとんでもないレベルの推定された比較的正確さを超えて喜んでトレードします。
これを入力しながらレポートを作成しています。フィールドの1つは、どこかから取得したlong
ミリ秒の期間です。これはMicrosoft Excelに送信され、使用する期間の単位は10進数日(1.25
= 1日、6時間)です。
確かに、可能な最小値から最大値までの範囲を細分化し、それらの間を整数単位でステップすることはできますが、ほとんどの場合、これは本当に扱いにくい単位です。
コンピュータで作業する場合、3つの場合があります。
浮動小数点ではなく整数を使用する場合、時間1と3を時間2と交換して、より高速に実行します。しかし、これが問題です...高速で実行する必要はありません。
小数点以下の時間の計算で小数点以下10桁に丸め誤差がある場合、それは私が気にしない1秒の端数です(レポートはHH:MM:SS
-HH:MM:SS.000
ではありません)。彼らは私が扱っているものや提示しているものに丸められません。浮動小数点で十分です。
グラフの円の面積、またはpiが整数のみで確率を計算する場所の計算は、not funです。 Piはではない3。
また、多くの場所で浮動小数点を処理するために高速です。 1.5
は1.5
ではありません(1のスケールで15)。そのため、コードをより速く記述でき、コードを保守する人はそれをより速く読み取って作業できます。
特定のアプリケーション(銀河の衝突や核爆弾のシミュレーション)の速度を上げるために固定小数点精度(お金)または純粋な整数演算を使用する必要がある場合は、必ずそれらを使用してください。しかし、ほとんどの場合、これらの特殊な状況に本当に対処していなければ、浮動小数点は問題ありません。
それはスケールの一端で機能しているだけです。 0と2の間で細分できる数値64 (または使用しているビット数)。 264 約10です19。しかし、10で作業する必要がある場合はどうでしょうか。20 または10200?このドメインで動作する問題がありスーパーコンピューターに限定されていない。通常のシミュレーションやゲームではフロートを使用する場合があります。多くの場合、ライブラリの制限が原因ですが、そこでも使用されています。時にはそれだけで簡単です。
Gamedev.SEに関連: 浮動小数点の精度について、なぜそれを使用するのか
64ビット整数でも十分な範囲が得られない場合があるためです。
たとえば、私が現在取り組んでいる物理コードでは、分子質量を1モルあたりのグラム数(入力/出力形式で使用)と1分子あたりのキログラム数(内部計算で単位整合性に必要)の間で変換する必要があります。
約2つあります79 モル内の分子、 したがって、この特定の変換には、数量を1,000倍して乗算または除算することが含まれます[〜#〜] n [〜#〜]あ ≈6.022×1026日 ≈289。
確かに、この特定の問題couldは、モルごとおよび分子ごとの量に異なる固定小数点数値型を使用するだけで、固定小数点で処理されますが、これにより、コードに多くの複雑さが追加されます。本当に必要です。そして、これは孤立したケースからはほど遠いです-物理計算自体はしばしば ボルツマン定数 ≈2のようなものとの乗算を含みます-76。理論的には、さまざまな固定小数点型を使用し、どの型を使用してどの数値を格納する必要があるかを追跡することで、これらすべてを処理できますが、なぜ煩わしいのでしょうか。浮動小数点を使用すると、単一の数値型を使用してそれらすべてを格納できます。
さらに、ここで重要なのは、これらの分子量は最終的に実験データに基づいているということです。それらのどれも10桁以上の有効数字で知られていません。それでも、計算に入る他のいくつかのパラメーターの精度よりはるかに優れています。単精度の浮動小数点数でさえ、それらを格納するには十分すぎるほどです。実際には、実際には倍精度浮動小数点数を使用していますが、実際にはそうしない理由はありません。
なぜプログラマはまだフロートを使用するのですか?すでにここにある(一般的に良い)答えに、私は追加します:
ほとんどのプログラミング言語は「10進数」タイプを提供しないか、少なくともフロートとして扱うのに便利にはなりません。これらが言語に組み込まれていて扱いやすい場合、任意精度の10進数は2進浮動小数点数よりもはるかに直感的で扱いやすく、0.3 - 0.2
などを計算しようとすると面白い答えが得られます。
はい、あなたはcan整数を固定小数点10進数として使用します。足し算と引き算は問題なく機能しますが、乗算/除算を行う場合は追加の手順が必要です(結果は上下にシフトする必要があります)。それは15年または20年前にある程度のパフォーマンスを達成した可能性がありますが、今日のCPUでは、どうでしょうか?フロートを使用する方が高速です。実際、浮動小数点演算はinteger演算よりも高速な場合があります!
一般的なオーディオ処理はフロートを使用します。フロートは計算に十分で高速であるため、32ビットフロートが提供する精度よりも高い精度を使用してもまったく役に立たないためです。実装は、数値的に「正確」にはるかに多くの処理能力を必要とし、リアルタイムの仕様に適合しない可能性があると述べました。一部の特定の実装では、一部の(古い)組み込みプラットフォームのように、固定小数点を使用しますが、それは質問の範囲ではありません。 http://broadcastengineering.com/audio/fixedpoint_vs_floatingpoint を参照してください。
他のほとんどの信号処理と画像処理アルゴリズムの実装では、まったく同じ理由で浮動小数点を使用しています。固定小数点または整数の実装は、特定の目的で浮動小数点アルゴリズムからのみ派生します。
係数が必要な場合は、floatの方が適しています。
たとえば、12442の54.2%の場合、0.542 * 12442を実行します。
FloatはCPU上の専用ユニットであるFPUによって計算されることを忘れないでください。電力消費量が多いため、組み込みハードウェアには明らかに適していませんが、ゲームプログラミングやグラフィックプログラミングでは非常に重要です。
科学と金融では、データが失われる可能性があるため、フロートはあまり好きではありません。
科学的シミュレーションでは、それらは使用されていないと私は信じています。GMPライブラリを使用すると、128ビット以上の浮動小数点数を作成できます。理論的には、速度を犠牲にして、可能な限りの精度を実現できます。
ただし、リアルタイムシミュレーションではフロートが推奨されます。データの損失やエラーの蓄積を回避したい場合は、浮動小数点数を使用するときにいくつかの注意事項があります。たとえば、ブリザードは決定論的な方法を使用して、スタークラフト2のマルチプレイヤーゲームがプレイされるときに、ユニットの位置ではなくプレイヤーの注文のみが送信されるため、ゲームの状態を変更します。
フロートには用途があるだけで、長所と短所があります。