简体   繁体   中英

Optimization concern : int to double

I have these two interpolation methods that I use in some of my programs...

__forceinline double InterpolateDouble(double dOldVal, double dOldMin, double dOldMax, double dNewMin, double dNewMax) 
{ 
    return (((dOldVal - dOldMin) * (dNewMax - dNewMin)) / (dOldMax - dOldMin)) + dNewMin; 
}

__forceinline int InterpolateInteger(int nOldVal, int nOldMin, int nOldMax, int nNewMin, int nNewMax) 
{ 
    return (int)InterpolateDouble((double)nOldVal, (double)nOldMin, (double)nOldMax, (double)nNewMin, (double)nNewMax); 
}

The method InterpolateInteger() simply calls the InterpolateDouble() method to maintain some fractional accuracy. Is the conversion from integer to double a concern, and is there any way to get an accurate result using only integers (no casting)?

There is a risk of overflow when multiplying before dividing, as your code does here. You must check the possible values of your inputs, in addition to the possible intermediate calculations of multiplication within the code to determine whether an int type will always be sufficient to contain the calculation. Truncation will happen with integer division, but if you want an integer result, that's expected. Conversion from int to double is trivial from a CPU perspective, since there's a 0 prepended on the front of the integer before calculation.

It's not the conversion from int to double you should worry about. It's the conversion (truncation) back from double to int after the work is done. Consider interpolating [0, 500] to [0, 1]. In that case, once you do the interpolate double, the number will be 1 output for 500 input, and less than one for input 0-499. So 0-499 input will result in 0 output after truncation, and 500 will result in 1.

If you are after maximum optimization and the interpolation points are fixed, you can use the following integer expression:

(dOldVal * dNewDelta + dNewMin * dOldDelta - dOldMin * dNewDelta) / dOldDelta

which is of the form (A * X + B) / C , where A , B and C are three precomputed integer constants. This will yield exact integer answers.

Alternatively, use A * X + B with double precision precomputed coefficients, but the rounding strategy needs to be carefully adjusted.

Yet another possibility is to rescale and round the A and B coefficients using a power of 2, giving a fast division-less integer formula of the form

(A * X + B) >> p

(rounding strategy also delicate).

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