63

32ビット単精度浮動小数点演算のみをサポートする組み込みハードウェア用のプログラムを作成しています。ただし、私が実装しているアルゴリズムには、64ビットの倍精度の加算と比較が必要です。double2つのタプルを使用してデータ型をエミュレートしようとしていfloatます。したがって、aはタプルを含むものdouble dとしてエミュレートされます。struct(float d.hi, float d.low)

比較は、辞書式順序を使用して簡単に行う必要があります。ただし、どのベースを使用すればよいかわからないため、追加には少し注意が必要です。それはすべきFLT_MAXですか?そして、どうすればキャリーを検出できますか?

これはどのように行うことができますか?


編集(明確さ):余分な範囲ではなく、余分な有効数字が必要です。

4

8 に答える 8

92

double-floatは、単精度の数値のペアを使用して、単精度の指数範囲のわずかな縮小を伴う単精度演算のほぼ2倍の精度を達成する手法です(範囲の遠端での中間のアンダーフローとオーバーフローによる)。 。基本的なアルゴリズムは、1970年代にTJデッカーとウィリアムカハンによって開発されました。以下に、これらの手法をGPUに適応させる方法を示す、かなり最近の2つの論文を示します。ただし、これらの論文で取り上げられている資料の多くは、プラットフォームに関係なく適用できるため、当面のタスクに役立つはずです。

https://hal.archives-ouvertes.fr/hal-00021443 GuillaumeDaGraça、David Defourグラフィックハードウェアでのfloat-float演算子の実装、実数とコンピューターに関する第7回会議、RNC7。

http://andrewthall.org/papers/df64_qf128.pdf AndrewThallGPU計算用の拡張精度浮動小数点数。

于 2011-07-21T01:17:20.897 に答える
11

これは簡単なことではありません。

浮動小数点(IEEE 754単精度)には、1つの符号ビット、8つの指数ビット、および23ビットの仮数(実質的には24)があります。

double(IEEE 754倍精度)には、1つの符号ビット、11の指数ビット、および52ビットの仮数(実質的に53)があります。

フロートの1つから符号ビットと8つの指数ビットを使用できますが、他のフロートからさらに3つの指数ビットと29ビットの仮数を取得するにはどうすればよいでしょうか。

誰か他の人が何か賢いことを思いつくかもしれませんが、私の答えは「これは不可能です」です。(または、少なくとも、「64ビット構造体を使用して独自の操作を実装するよりも簡単ではありません」)

于 2011-07-21T00:02:14.307 に答える
9

実行する操作の種類によって少し異なります。足し算と引き算だけを気にするなら、カハンの加算は素晴らしい解決策になり得ます。

于 2011-07-21T00:51:56.193 に答える
7

精度と広い範囲の両方が必要な場合は、 SoftFloatなどの倍精度浮動小数点のソフトウェア実装が必要になります。

(さらに、基本的な原則は、各値の表現(64ビットなど)を3つの構成要素(符号、指数、仮数)に分割し、指数の差に基づいて1つの部分の仮数をシフトし、またはに追加することです。符号ビットに基づいて他の部分の仮数から減算し、仮数をシフトしてそれに応じて指数を調整することにより、結果を再正規化する可能性があります。途中で、不必要な損失を避けるために、説明すべき厄介な詳細がたくさんあります。精度を高め、無限大、NaN、非正規化された数値などの特別な値を処理します。)

于 2011-07-21T00:47:03.523 に答える
5

23マグニチュードを超える高精度に対するすべての制約を考えると、最も有益な方法は、カスタム演算パッケージを実装することだと思います。

簡単な調査によると、Briggsのdoubledouble C ++ライブラリは、ニーズに対応し、次にいくつかのニーズに対応する必要があります。これを参照してください。[*]デフォルトの実装は、30の有効数字の計算を達成することに基づいていますが、13または14の有効数字を達成するためdoubleに使用するように簡単に書き直されます。float同様の大きさの値で加算演算を分離し、最後の演算で極値を加算するだけである場合は、これで十分な場合があります。

ただし、コメントにはx87制御レジスタをいじることが記載されていることに注意してください。詳細は確認していませんが、コードが移植性に欠けて使用できない可能性があります。


[*] C ++ソースはその記事によってリンクされていますが、gzip圧縮されたtarのみがデッドリンクではありませんでした。

于 2011-07-21T01:43:15.230 に答える
3

役立つ可能性のある別のソフトウェアベースのソリューション:GNU MPFR
これは、他の多くの特殊なケースを処理し、他の方法では自分で処理しなければならない任意精度(64ビット倍精度よりも優れている)を可能にします。

于 2011-07-21T11:43:28.473 に答える
2

それは実用的ではありません。もしそうなら、すべての組み込み32ビットプロセッサ(またはコンパイラ)は、それを行うことで倍精度をエミュレートします。現状では、私が知っていることは誰もしていません。それらのほとんどは、の代わりfloatになりdoubleます。

ダイナミックレンジではなく精度が必要な場合は、固定小数点を使用するのが最善の策です。コンパイラが64ビットをサポートしている場合、これも簡単になります。

于 2011-07-21T00:10:51.070 に答える
1

これは、ハードウェア計算のみをサポートする一部のマシンで多くのコンパイラが使用するdouble-double演算に似ています。また、サポートされていない古いNVIDIAGPUのフロートフロートとしても使用されます。GPUで2つのFP32を使用してFP64をエミュレートするを参照してください。このように、計算はソフトウェア浮動小数点ライブラリよりもはるかに高速になります。long doubledoubledouble

ただし、ほとんどのマイクロコントローラーでは、のハードウェアサポートがないfloatため、純粋にソフトウェアで実装されます。そのため、を使用してfloat-floatもパフォーマンスが向上せず、指数の余分なバイトを節約するためにメモリオーバーヘッドが発生する可能性があります。

より長い仮数が本当に必要な場合は、カスタム浮動小数点ライブラリを使用してみてください。たとえば、40ビットの仮数と7ビットの指数のみが必要な場合は、ライブラリを変更して、独自の新しい48ビット浮動小数点型を適合させるなど、十分なものを選択できます。不要な16ビットの計算/保存に時間を費やす必要はもうありません。ただし、コンパイラのライブラリには、独自のタイプのfloatに対してアセンブリレベルの最適化が行われていることが多いため、このライブラリは非常に効率的です。

于 2013-08-02T07:28:31.147 に答える