0和-0浮点值之间有什么区别?

时间:2014-08-13 03:27:04

标签: c++ visual-studio floating-point

Visual Studio 2013中的此代码段:

double a = 0.0;
double b = -0.0;

cout << (a == b) << " " << a << " " << b;

打印1 0 -0ab之间有什么区别?

2 个答案:

答案 0 :(得分:4)

C ++不保证区分+0和-0。这是每个特定数字表示的特征。用于浮点运算的IEEE 754标准确实做出了这种区分,即使数字变为零,也可用于保持符号信息。 std::numeric_limits并不会直接告诉您是否有可能签名的零。但如果std::numeric_limits<double>::is_iec559为真,那么您可以在实践中假设您拥有IEEE 754 表示,因此可能为负零。


a comment中的“gmch”注意到,用于检查零符号的C ++ 11标准库方法是使用std::copysign,或更直接地使用std::signbit,例如如下:

#include <iostream>
#include <math.h>       // copysign, signbit

using namespace std;

auto main() -> int
{
    double const z1 = +0.0;
    double const z2 = -0.0;

    cout << boolalpha;
    cout << "z1 is " << (signbit( z1 )? "negative" : "positive") << "." << endl;
    cout << "z2 is " << (signbit( z2 )? "negative" : "positive") << "." << endl;
}

没有copysignsignbit,例如对于C ++ 03编译器,检测负零z的一种方法是检查1.0/z是否为负无穷大,例如通过检查它是否只是消极。

#include <iostream>
using namespace std;

auto main() -> int
{
    double const z1 = +0.0;
    double const z2 = -0.0;

    cout << boolalpha;
    cout << "z1 is " << (1/z1 < 0? "negative" : "positive") << "." << endl;
    cout << "z2 is " << (1/z2 < 0? "negative" : "positive") << "." << endl;
}

但是,虽然这可能在大多数实现中都有效,但它正式 * 未定义的行为。

需要确保表达式评估不会陷阱。


*) C ++11§5.6/ 4“如果/%的第二个操作数为零,则行为未定义”

答案 1 :(得分:2)

请参阅http://en.m.wikipedia.org/wiki/Signed_zero

简而言之,这是由于符号被存储为IEEE 754浮点表示中的独立位。这导致能够具有零指数和小数部分,但仍然设置符号位 - 因此为负零。对于存储在二进制补码中的有符号整数,这是不会发生的情况。