views:

125

answers:

4

I am writing a piece of code in which i have to convert from double to float values. I am using boost::numeric_cast to do this conversion which will alert me of any overflow/underflow. However i am also interested in knowing if that conversion resulted in some precision loss or not.

For example

    double source =  1988.1012;
    float dest = numeric_cast<float>(source);

Produces dest which has value 1988.1

Is there any way available in which i can detect this kind of precision loss/rounding

+8  A: 

You could cast the float back to a double and compare this double to the original - that should give you a fair indication as to whether there was a loss of precision.

Will A
Better than fair. It will tell you precisely if any information was lost.
Stephen Canon
+8  A: 
float dest = numeric_cast<float>(source);
double residual = source - numeric_cast<double>(dest);

Hence, residual contains the "loss" you're looking for.

Jacob
+1  A: 

Look at these articles for single precision and double precision floats. First of all, floats have 8 bits for the exponent vs. 11 for a double. So anything bigger than 10^127 or smaller than 10^-126 in magnitude is going to be the overflow as you mentioned. For the float, you have 23 bits for the actual digits of the number, vs 52 bits for the double. So obviously, you have a lot more digits of precision for the double than float.

Say you have a number like: 1.1123. This number may not actually be encoded as 1.1123 because the digits in a floating point number are used to actually add up as fractions. For example, if your bits in the mantissa were 11001, then the value would be formed by 1 (implicit) + 1 * 1/2 + 1 * 1/4 + 0 * 1/8 + 0 * 1/16 + 1 * 1/32 + 0 * (64 + 128 + ...). So the exact value cannot be encoded unless you can add up these fractions in such a way that it's the exact number. This is rare. Therefore, there will almost always be a precision loss.

Dave
May I suggest pointing to the often mentioned http://docs.sun.com/source/806-3568/ncg_goldberg.html instead ? (I don't have enough rep to do it myself)
Alexandre C.
+1  A: 

You're going to have a certain level of precision loss, as per Dave's answer. If, however, you want to focus on quantifying it and raising an exception when it exceeds a certain number, you will have to open up the floating point number itself and parse out the mantissa & exponent, then do some analysis to determine if you've exceeded your tolerance.

But, the good news, its usually the standard IEEE floating-point float. :-)

Paul Nathan