narrowing conversion from unsigned to double

2019-01-11 16:31发布

static_assert(sizeof(unsigned) == 4, ":(");
static_assert(sizeof(double) == 8 ,":(");
unsigned u{42};
double x{u};

g++ 4.7.1 complains about this code:

warning: narrowing conversion of 'u' from 'unsigned int' to 'double' inside { }

Why is this a narrowing conversion? Isn't every unsigned perfectly representable as a double?

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-11 17:03

(Let's try:) double has exactly 52 bits of significant (binary) digits (according to ieee standard), whereas unsigned int may have good 64 bits on some other system. So the actual unsigned int's width on your system may be of no value for this check.

查看更多
ゆ 、 Hurt°
3楼-- · 2019-01-11 17:17

Why is this a narrowing conversion?

Because the definition includes (with my emphasis):

C++11 8.5.4/7 A narrowing conversion is an implicit conversion [...] from an integer type [...] to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type.

u is not a constant expression, so it's a narrowing conversion whether or not all possible values of the source type might be representable in the target type.

Isn't every unsigned perfectly representable as a double?

That's implementation defined. In the common case of 32-bit unsigned and double with a 52-bit mantissa, that is the case; but some implementations have larger unsigned and/or smaller double representations, so code that depends on that assumption is not portable.

查看更多
Rolldiameter
4楼-- · 2019-01-11 17:28

The warning you have because you initialize x with non-constant expression

Ilyas-iMac:TestC++11 sandye51$ cat main.cpp                   
int main()
{
    static_assert(sizeof(unsigned) == 4, ":(");
    static_assert(sizeof(double) == 8 ,":(");
    constexpr unsigned u{42};
    double x{u};

    return 0;
}Ilyas-iMac:TestC++11 sandye51$ gcc -o main main.cpp -std=c++11
Ilyas-iMac:TestC++11 sandye51$ 

As you can see the code above works without any warning or errors

查看更多
登录 后发表回答