27

次のように double に変換する文字列があります。

double d = [string doubleValue];

のドキュメントにdoubleValueよると、オーバーフロー時に、このメソッドはHUGE_VALまたはを返します-HUGE_VAL。これは、以前にこれを確認した方法です。

if (d == HUGE_VAL || d == -HUGE_VAL)
   //overflow

現在、新しい「-Weverything」警告フラグを追加して以来、コンパイラは次のように不平を言うようになりました

Comparing floating point with == or != is unsafe

この問題を解決するにはどうすればよいですか? これらの比較はどのように行うべきですか?


2 つの「通常の」浮動小数点数 (つまり、「HUGE_VAL」ではない) の比較についても同じ質問があります。例えば、

double a, b;
//...
if (a != b) //this will now yield the same warning
  //...

これはどのように解決する必要がありますか?

4

5 に答える 5

44

この警告について心配する必要はありません。あなたを含め、多くの場合、それはナンセンスです。

のドキュメントには、オーバーフローdoubleValueに十分近い、HUGE_VALまたは-HUGE_VALオーバーフロー時に何かを返すとは書かれていません。オーバーフローが発生した場合、これらの値を正確に返すと書かれています。

つまり、オーバーフローが発生した場合にメソッドによって返される値は、またはと比較==されHUGE_VALます-HUGE_VAL

そもそもなぜ警告が存在するのですか?

例を考えてみましょう0.3 + 0.4 == 0.7。この例はfalseと評価されます。あなたが出会った警告の作者を含む人々は、浮動小数点==は不正確であり、予期しない結果はこの不正確さから来ると考えています。

それらはすべて間違っています。

浮動小数点の加算は、ある意味不正確であるため、「不正確」です。これは、要求した操作に最も近い表現可能な浮動小数点数を返します。上記の例では、変換(10進数から浮動小数点へ)と浮動小数点の加算が奇妙な動作の原因です。

一方、浮動小数点の等式は、他の離散型の場合とほぼ同じように機能します。浮動小数点の等式は正確です。マイナーな例外(NaN値と+0。および-0。の場合)を除いて、検討中の2つの浮動小数点数が同じ表現である場合に限り、等式はtrueと評価されます。

2つの浮動小数点値が等しいかどうかをテストするためにイプシロンは必要ありません。そして、デュワーが実質的に言っているように、警告が意味をなすためには、例の警告はオンではなくオンに0.3 + 0.4 == 0.7なっている必要があります。+==

最後に、イプシロン内と比較すると、等しくない値は等しく見えることを意味します。これは、すべてのアルゴリズムに適しているわけではありません。

于 2012-07-10T21:30:18.573 に答える
12

この場合、 と を使用してみて>=ください<=

于 2012-07-10T22:23:26.990 に答える
7

比較に確信があり、それを鳴らしたい場合は、コードを次のように囲みます。

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
/* My code triggering the warnings */
#pragma clang diagnostic pop
于 2016-08-22T13:39:41.190 に答える