简体   繁体   中英

conversion from 'size_t' to 'const double', possible loss of data

Given a variable size_t idx , an assignment like double value = idx; produces the following warning when compiling under 64 bit:

'initializing': conversion from 'size_t' to 'double', possible loss of data

It seems that it has to do with the fact that a size_t value takes up 8 bytes when compiled under 64 bit. However, the assignment double value = static_cast<double>(idx) does not produce any warnings. Can somebody explain to me why the former assignment does not work while the latter does?

Thanks in advance!

When you do

double value = idx;

The compiler looks at it and goes: "Hey, idx might not be able to fit in value , lets tell the programmer in case it was a mistake.". This is why you get the warning.

When you do

double value = static_cast<double>(idx)

The compiler looks at it and goes: "Oh, the programmer is explicitly casting here, this must be what they want.". That means it wont surface a warning.

static_cast<double> is how you tell the compiler that you are consciously converting to double and are aware of all the implications. This means the compiler should not to warn you of the risks because you have explicitly told it you are already aware of them.

In the first case, where you do not use static_cast , the conversion is legal but carries the risk of losing precision. Since it's possible you didn't notice that this conversion was happening, it makes sense to warn you about it.

Both assignments will 'work' and, in fact, do exactly the same thing! The only difference is that in the second case, double value = static_cast<double>(idx) , your explicit cast makes it clear to the compiler that you "know what you're doing" and that you may lose significant digits in the conversion.

In the first case, the compiler is simply warning you that your conversion may (inadvertently) cause loss of data (or precision, in this case).

It is a warning because the programmer may not realize they are losing bits during assignment.

But if you have an explicit cast there, the compiler assumes that the programmer knows what they're doing because the cast is right there and very in your face.

A 64-bit double uses only 52 bits to store the number and the rest for storing the sign( + or - ) and the exponent. ( Note: This is the IEEE754 implementation, the implementation of double may differ in other standards of the language)

An unsigned int (aka size_t ) uses all of the 64-bits to store the number but there are no spaces left for exponents and hence there is no floating-point precision in integers like size_t

Therefore, the compiler is telling you that if your 64-bit unsigned integer is greater than how much the mantissa of the 64-bit double -type can store (ie, larger than 52 bits ), it can cause loss of data, and possibly Undefined Behavior in the rest of the code afterwards.

Doing static_cast<double>(idx) is an assertion by the programmer telling the compiler to not worry and that you will keep in mind the aforementioned precautions.

Source: https://en.wikipedia.org/wiki/Double-precision_floating-point_format

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM