7

正のフロートAが別の正のフロートB(C99)の逆二乗よりも小さいことを確認したい場合、Bが非常に小さいと、何か問題が発生する可能性がありますか?

私はそれを次のようにチェックすることを想像することができました

if(A<1/(B*B))

しかし、Bが十分に小さい場合、これはおそらく無限大になりますか?それが起こったとしても、コードはすべての状況で正しく機能しますか?

同様の流れで、私はするかもしれません

if(1/A>B*B)

...Bが小さい場合はB*Bがゼロになる可能性があるため、これは少し良いかもしれません(これは本当ですか?)

最後に、私が間違っているとは想像できない解決策は

if(sqrt(1/A)>B)

これがゼロ除算になるとは思わないが、Aがゼロに近い場合は問題が発生する可能性がある。

つまり、基本的に、私の質問は次のとおりです。

  • Xがゼロより大きい(ただし小さい)場合、1 / Xは無限大になる可能性がありますか?
  • Xがゼロより大きい場合、X * Xをゼロにすることはできますか?
  • 無限大との比較は、私が期待するように機能しますか?

編集:疑問に思っている人のために、私はやることになりました

if(B*A*B<1) 

どの乗算が最初に発生するかが視覚的に明確であるため、この順序で実行しました。

4

4 に答える 4

7

Aとの可能な値の全範囲を処理する場合はB、少し注意する必要がありますが、これはそれほど複雑ではありません。

使用の提案はa*b*b < 1.良いものです。bが非常に小さいためにa*b*bアンダーフローがゼロになる場合は、a必然的に。よりも小さくなり1./(b*b)ます。逆に、bが大きすぎa*b*bて無限大にオーバーフローする場合、条件は(正しく)満たされません。(Potatoswatterは、別の投稿のコメントで、これを書くと正しく機能しないことを正しく指摘しています。これは、条件が真である必要がある場合でも、非正規化数の場合、無限大にオーバーフローする可能性がb*b*aあるためです。ただし、Cでは、乗算は左に関連付けられます-右に、それを書いて、プラットフォームが妥当な数値モデルに準拠している場合、それは問題ではありません。)b*baa*b*b

とは両方とも正の数であることをアプリオリに知っているので、NaNを生成する方法はありません。したがって、その状態について心配する必要はありません。オーバーフローとアンダーフローが唯一の考えられる不正行為であり、私たちはすでにそれらを説明しました。またはがゼロまたは無限大である可能性がある場合をサポートする必要がある場合は、もう少し注意する必要があります。aba*b*bab

直接の質問に答えるには:(答えはIEEE-754演算を想定しています)

Xがゼロより大きい(ただし小さい)場合、1 / Xは無限大になる可能性がありますか?

はい!xが小さな正の非正規化数の場合、1/xオーバーフローして無限大を生成する可能性があります。たとえば、デフォルトの丸めモードの倍精度では、1 / 0x1.0p-1024オーバーフローします。

Xがゼロより大きい場合、X * Xをゼロにすることはできますか?

はい!デフォルトの丸めモードの倍精度では、xのすべての値が0x1.0p-5382**-578C99の16進形式のもの)よりも小さいため、このプロパティがあります。

無限大との比較は、私が期待するように機能しますか?

はい!これは、IEEE-754の最も優れた機能の1つです。

于 2010-06-02T03:10:33.303 に答える
5

OK、回答として再投稿します。

のような算術的に同等の比較を使用してみてくださいif ( A*B*B < 1. )。ただし、非常に大きな数で問題が発生する可能性があります。

コーナーケースについては、IEEE754を注意深く見てください。

于 2010-06-02T02:39:59.970 に答える
3

除算を避けたいので、方程式を修正するのがコツです。最初の方程式の両辺に(b * b)を掛けると、次のようになります。

b*b*a < 1.0

これには分割がないので、大丈夫です。

于 2010-06-02T02:33:44.673 に答える
1

分割自体はそれほど悪くはありません。ただし、標準のIEEE 754 FPタイプでは、非正規化数のため、正の数よりも負の負の指数範囲を大きくすることができます。たとえば、float範囲は1.4× 10-45から3.4× 10-38であるため、2× 10-44の逆数を取ることはできません。

したがって、ジェレミーが示唆しているように、オーバーフローを避けるために、AにBを掛けることから始めます。ここで、一方は正の指数を持ち、もう一方は負の指数を持ちます。

A*B*B<1これが正しい答えである理由です。

于 2010-06-02T03:13:59.930 に答える