为什么我的双重比较失败了c ++

bot*_*tus 0 c++ double comparison

我正在做一个项目并完成它我需要做一些比较double,float ...问题是当我比较两个double,它们分别是double的最大值和double + 1的最大值,比较失败......我做

if (std::max(d_max + 1.1, (d_max)) == d_max)
  std::cout << "bad" << std::endl;
Run Code Online (Sandbox Code Playgroud)

函数max的答案是d_max并显示"bad"......是否有人有想法或解决方案来获得我的比较的精确度?我检查谷歌,但我发现了更多的解释,而不是真正解决我的问题...非常感谢!

Jos*_*eld 7

C++中的所有对象都有一个类型.类型d_maxdouble.类型d_max + 1.1仍然是两倍.如果d_max是a的最大值double,则d_max + 1.1不可表示并且将使用最接近的可表示值,d_max但是(但是,如果添加更大的值,则最接近的可表示值被视为正无穷大).所以你的std::max电话相当于:

std::max(d_max, d_max)
Run Code Online (Sandbox Code Playgroud)

展示:

double d_max = std::numeric_limits<double>::max();
bool b = (d_max == (d_max + 1.1));
std::cout << std::boolalpha << b << std::endl;
Run Code Online (Sandbox Code Playgroud)

这给出true了输出.


在回应你的评论时,我认为你做的是这样的:

double d_max = std::numeric_limits<double>::max();
long double ld = d_max + 1;
std::cout << (d_max == ld) << std::endl;
Run Code Online (Sandbox Code Playgroud)

而奇怪的是你会发现,显然d_maxld相等.为什么?好吧d_maxdouble.当你这样做时d_max + 1,操作的结果也是double- 如前所述,d_max + 1不能在a中double表示的值,因此选择最接近的可表示值(d_max).然后将该值分配给ld.

请注意,只有确保运算符导致long double(可能有d_max + 1.0L),才可能无法解决此问题.如此庞大的数字(10^308使用IEEE 754表示),添加1将不会将您带到a中的下一个可表示值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;
Run Code Online (Sandbox Code Playgroud)

此外,无法保证long double精度高于double.唯一的保证是它没有更低的精度.