Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

narrowing conversion from unsigned to double

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?

like image 877
fredoverflow Avatar asked Jul 17 '12 10:07

fredoverflow


3 Answers

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.

like image 176
Mike Seymour Avatar answered Nov 13 '22 17:11

Mike Seymour


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

like image 25
Ilya Lavrenov Avatar answered Nov 13 '22 15:11

Ilya Lavrenov


(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.

like image 1
Vlad Avatar answered Nov 13 '22 17:11

Vlad