0

i'm working on a project and to finish it i need to do some comparison with double, float ... the problem is when i compare two double which are respectively the biggest value for a double and the biggest value for a double + 1, the comparison fail ... i do

if (std::max(d_max + 1.1, (d_max)) == d_max)
  std::cout << "bad" << std::endl;

the answer of the function max is d_max and "bad" is displayed ... is anyone having an idea or a solution to get a good precision with my comparison ? i checked on google but i found out more explanations than real solution to my problem ... thanks so much !

4

2 に答える 2

7

C++のすべてのオブジェクトには型があります。のタイプはd_maxですdouble。のタイプd_max + 1.1はまだ2倍です。d_maxがの最大値である場合doubled_max + 1.1は表現できず、最も近い表現可能な値が使用されますd_max(ただし、大幅に大きい値を追加すると、最も近い表現可能な値は正の無限大と見なされます)。したがって、std::max呼び出しは次と同等です。

std::max(d_max, d_max)

実証するために:

double d_max = std::numeric_limits<double>::max();
bool b = (d_max == (d_max + 1.1));
std::cout << std::boolalpha << b << std::endl;

これはtrue出力として与えられます。


あなたのコメントに応えて、私はあなたがこのようなことをしていると思います:

double d_max = std::numeric_limits<double>::max();
long double ld = d_max + 1;
std::cout << (d_max == ld) << std::endl;

そして不思議なことに、あなたはそれを明らかにd_maxそしてld等しいと思います。なんで?まあd_maxですdouble。を実行するd_max + 1と、操作の結果もaになります。前述のように、doubleの値はd_max + 1aで表すことができないdoubleため、最も近い表現可能な値(d_max)が選択されます。次に、この値がに割り当てられldます。

これは、演算子の結果がlong double(おそらくd_max + 1.0L)になることを確認するだけでは修正されない可能性があることに注意してください。このような膨大な数(10^308IEEE 754表現を含む)では、1を追加しても、の次の表現可能な値に移動することはありませんlong double。私の実装では、実際に値を変更するには、 10 289 (1の後に289個のゼロが続く)を追加する必要があります。

double d_max = std::numeric_limits<double>::max();
long double ld = d_max + 1E289L;
std::cout << (d_max == ld) << std::endl;

また、long doubleよりも精度が高いという保証はありませんdouble。唯一の保証は、精度が低下しないことです。

于 2013-02-23T14:11:23.080 に答える
1

double が 10 進浮動小数点数、科学表記法で表されているとしましょう。次に、d_max次のようなものになります

9.999999999999999999 ⋅ 10⁹⁹

1.1次に、それに追加しましょう。

9.999999999999999999 ⋅ 10⁹⁹ + 1.1
= 999999999999999999900000000...000 + 1.1
= 999999999999999999900000000...001.1

それを20、または40の有効数字に丸めます(これらのタイプは、long doubleでさえ、有限の情報容量しか持たないため、これを行う必要があります)、あなたは得ます...?さて、d_maxまた。


同じことが減算にも適用されることに注意してください。

int main() {
  long double d_max = std::numeric_limits<double>::max();
  if(d_max == d_max - 1.1)
    std::cout << "   d_max       = " << d_max
            << "\n== d_max - 1.1 = " << d_max + 1.1 << std::endl;
  return 0;
}

出力

   d_max       = 1.79769e+308
== d_max - 1.1 = 1.79769e+308

つまり、これは利用可能な最大値であることとはまったく関係ありませんがd_max、追加した値よりもはるかに大きいこととは関係ありません。

于 2013-02-23T14:17:37.240 に答える