5

fdlibmから現在使用しているモデル チェッカー ツール ( cbmcsqrt ) への関数 (64 ビット double 用) の移植に取り組んでいます。 仕事の一環として、ieee-754 規格についてよく読みましたが、基本演算 (sqrt を含む) の精度の保証を理解していなかったと思います。

fdlibm の sqrt のポートをテストすると、64 ビット double で sqrt を使用して次の計算が得られました。

sqrt(1977061516825203605555216616167125005658976571589721139027150498657494589171970335387417823661417383745964289845929120708819092392090053015474001800648403714048.0) = 44464159913633855548904943164666890000299422761159637702558734139742800916250624.0

(このケースは、精度に関する私のテストで単純な事後条件を破りました。この事後条件が IEEE-754 で可能かどうかはわかりません)

比較のために、いくつかの多精度ツールは次のように計算しました。

sqrt(1977061516825203605555216616167125005658976571589721139027150498657494589171970335387417823661417383745964289845929120708819092392090053015474001800648403714048.0) =44464159913633852501611468455197640079591886932526256694498106717014555047373210.truncated

左から 17 番目の数字が異なることがわかります。これは、次のようなエラーを意味します。

3047293474709469249920707535828633381008060627422728245868877413.0

質問 1: この膨大な量のエラーは許容されますか?

標準では、すべての基本演算 (+、-、​​、/、sqrt) は 0.5 ulp 以内である必要があるとされています。これは、最も近い fp 表現に丸められた数学的に正確な結果に等しくなければならないことを意味します (wiki では、一部のライブラリは1 ulp しか保証されませんが、現時点ではそれほど重要ではありません)。

質問 2: すべての基本操作で、64 ビット double (マシン イプシロン) で 2.220446e-16 未満のエラーが発生するということですか?

x86-32 Linux システム (glibc / eglibc) で同じことを計算したところ、fdlibm で得られたのと同じ結果が得られました。

  • a: 私は何か間違ったことをしました (しかし、どのように:printf候補になるでしょうが、それが理由であるかどうかはわかりません)
  • b: エラー/精度はこれらのライブラリで一般的です
4

2 に答える 2

16

IEEE-754 規格では、いわゆる「基本演算」 (加算、乗算、除算、平方根を含む) が正しく丸められる必要があります。これは、一意の許可された答えがあり、それが演算のいわゆる「無限に正確な」結果に最も近い表現可能な浮動小数点数であることを意味します。

倍精度では、数値の精度は 2 進数で 53 桁であるため、正しい答えは 53 桁の有効数字に丸められた正確な答えになります。Rick Reganが回答で示したように、これはまさにあなたが得た結果です。

ご質問への回答は次のとおりです。

質問 1: この膨大な量のエラーは許容されますか?

はい。ただし、このエラーを「巨大」と呼ぶのは誤解を招きます。実際には、より小さな誤差を持つ、返される可能性のある倍精度値はありません。

質問 2: すべての基本操作で、64 ビット double (マシン イプシロン) で 2.220446e-16 未満のエラーが発生するということですか?

いいえ。これは、現在の丸めモードに従って、すべての基本操作を (一意の) 最も近い表現可能な浮動小数点数に丸める必要があることを意味します。これは、相対誤差がマシンのイプシロンによって制限されているということとまったく同じではありません。

質問 3: x86 ハードウェアと gcc + libc で得られる結果はどれですか?

sqrt合理的なプラットフォームで正しく丸められるため、あなたがしたのと同じ答えです。

于 2010-11-30T22:04:20.473 に答える
8

バイナリでは、任意精度の回答の最初の58ビットは1011111111111111111111110101010101111111111111111011010001です。

double値の53ビットの仮数は

10111111111111111111111101010101011111111111111110111

これは、double値が53の有効ビットに正しく丸められ、1/2ULP以内であることを意味します。(エラーが「大きい」というのは、数値自体が大きいからです)。

于 2010-11-30T21:44:36.403 に答える