16

既存のシステムで使用されている式を再構築しようとしているときに問題がありました。これは、1 つの入力と 1 つの出力のかなり単純な式です。

y = f(x)

多くの困惑の後、観測されたデータポイントに適合する式を見つけることができました。

ここに画像の説明を入力

ご覧のとおり、私たちの理論モデルは観測データに非常によく適合しています。

ここに画像の説明を入力

残差エラー (つまり ) をプロットする場合を除いy = f(x) - actualYて、残差にいくつかの線が表示されます。

ここに画像の説明を入力

これらの線が、式に中間の丸めを適用した結果であることは明らかでしたが、どこにあるのかは明らかはありませんでした。最終的に、元のシステム (リバース エンジニアリングしようとしているシステム) が中間Decimalデータ型に値を格納していることが判明しました。

  • 小数部の8ビット精度で
  • 0.5 の切り上げ丸めモデルを使用します。

この 8 ビット精度を小数部でシミュレートするには、次のようにします

multiply by 128 (i.e. 2^8)
apply the round
divide by 128 (i.e. 2^8)

上記の式を次のように変更します。

ここに画像の説明を入力

これにより、残差が大幅に減少します。

ここに画像の説明を入力

さて、上記のすべては私の質問とは関係ありませんが、次の点を除きます。

  1. コンピューターで数値表現をシミュレートすることがモデルに役立つことを示す
  2. きれいな絵や色で人の目を引く
  3. 私が質問をする理由を説明するまで、投稿 拒否する批評家を黙らせてください。

Single Precision今、浮動小数点数を使用するプログラミング言語 (および Excel) 内で浮動小数点数をシミュレートしたいと考えていDouble Precisionます。それが必要だと思うので、私はこれをやりたいです。

上記の例で、元のシステムはDecimal data type with fixed 8-bit fractional precision using 0.5 round-up rules. 次に、その計算モデルをDouble数学でシミュレートする方法を見つけなければなりませんでした。元のシステムは精密演算を使用していると思いますSingleが、それを使用してシミュレートしたいと考えていますDouble

double を使用して単精度丸めをシミュレートするにはどうすればよいですか?

私の現在のモデルでは、通常の線形パターンに分類される残差が再びあります。これは、丸めの明らかな兆候です。

ここに画像の説明を入力

問題は、入力変数が大きくなるにつれて、エラーが大きくなり、目に見えるだけになることです。これは、すべての浮動小数点数がIEEE 754の「科学表記法」に正規化されていることが原因である可能性が高いことに気付きました。

たとえ間違っていたとしても、私はまだそれを試してみたいと思っています。

試したくない場合でも、まだ質問しています

Singleを使用して精度の丸めをシミュレートするにはどうすればよいDoublesですか?


最初に値を「正規化」できる限り、「8小数ビット後の丸め」の概念を適用できるようです(ただし、精度浮動小数点の場合は24ビットです) 。例えばSingle

1234567898.76543

に変換する必要があります (に似たもの):

1.23456789876543 E-09

次に、「24 番目のビットに丸め」を適用できます (つまり、2^24 = 16,777,216)。

floor(1.23456789876543E-09 * 16777216 + 0.5) / 16777216;

sign問題は、 、abslnexp(または他の関数)のどの組み合わせを適用して、値を「正規化」し、それを n 番目のバイナリ桁に丸めてから「非正規化」できるかということです。

:IEEE表現がバイナリ1を最上位ビットとして保持していることを認識しています。正しい結果を得るために、その動作を繰り返す必要はないかもしれません。したがって、これは取り決めを破るものではなく、アプローチ全体が失敗であると示唆する原因にもなりません。

こちらもご覧ください

4

4 に答える 4

9

標準のC99関数であり、Luaで使用可能なライブラリ関数frexpおよびldexpを使用する必要があります。

frexpは浮動小数点数を取り、仮数を指数から分離します。結果の仮数は、0または[0.5、1.0)または(-1.0、0.5]の範囲のいずれかになります。その後、明らかな方法で余分なビットを削除できますfloor(mantissa * 2^k)/2^k(たとえば、負でない値の場合)。追加:)Luaは2^kが正確であることを保証しないと確信しているので、示されているように除算を行うよりも、ldexpの呼び出しで指数からkを引く方がよいでしょう。

ldexpはfrexpの逆です。これを使用して、切り捨てられた数値を元に戻すことができます。

Excelでこれを行う方法がわかりません。マニュアルを確認してください:)(編集して追加:)数値を2で除算し、数値の対数2の上限の累乗にした後、上記のように2進ラウンドを実行すると、ほぼ同じ効果が得られると思います。次に、プロセスを逆にして元の指数を再作成します。しかし、結果は、Excelの算術に関する独特のアイデアとの特異性に遭遇することがあると思います。

于 2012-09-23T16:31:17.430 に答える
6

以下を使用して、単精度への丸めのほとんどの効果を得ることができます。

y = x + x * 0x1p29 - x * 0x1p29;

ほとんどの場合、x が float (32 ビット バイナリー IEEE 754) に丸められてから double (64 ビット) に変換された場合と同じ結果が y に生成されます。これは、仮数から x の一部のビットを「押し出す」値 (x * 0x1p29) を追加し、ビット 23 で丸めを行ってから、追加された値を減算することによって機能します。(は 2 29、5368709120x1p29の 16 進浮動小数点です。)

まれに、わずかに異なる結果が生成されます。モデルのノイズを減らしたいだけの場合、これらのまれなケースは無視できる場合があります。それらを排除したい場合は、2 29 x を足したり引いたりする代わりに、x以下の最大の 2 のべき乗を見つけ、 2 29 x の代わりにその 2 29倍を足したり引いたりすることができます。(2 の累乗を求めるには、2 を底とする対数を取り、その底を取ることができます。ただし、補正が必要になる可能性がある丸めの問題はまだあります。さらに、入力がゼロまたは負の可能性がある場合は、その対数を取るときに発生するエラー。)

さらに、これは、単精度で非正規である数値または単精度でオーバーフローする数値の動作を再現しません。

最後に、倍精度の結果を計算してから単精度に丸めると、元の単精度の結果の計算とはわずかに異なる結果が生成されることがまれにあり、倍精度の結果を丸める方法でこれを修正することはできません。

于 2012-09-24T17:01:39.507 に答える
1

次のようなコードを使用します (C):

double x, y;
/ ... y gets a double value somewhere ... /
x = (double)(float)y;

その後、x (double) は y を単精度浮動小数点として丸めた結果の値になります。

于 2015-02-13T14:36:16.407 に答える