优化问题:int加倍

时间:2014-11-15 03:15:35

标签: c++ optimization interpolation

我在我的一些程序中使用了这两种插值方法......

__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); 
}

方法InterpolateInteger()只是调用InterpolateDouble()方法来保持一些小数精度。从整数到双精度的转换是一个问题,有没有办法只使用整数(没有转换)获得准确的结果?

3 个答案:

答案 0 :(得分:0)

在分割前乘法时存在溢出的风险,正如您的代码在此处所做的那样。除了代码中可能的乘法中间计算之外,还必须检查输入的可能值,以确定int类型是否总是足以包含计算。截断以整数除法发生,但如果你想要一个整数结果,那就是预期的。 从CPU的角度来看,从int到double的转换是微不足道的,因为在计算之前在整数的前面有一个0。

答案 1 :(得分:0)

这不是你应该担心的从int到double的转换。这是工作完成后从double到int的转换(截断)。考虑将[0,500]插值为[0,1]。在这种情况下,一旦你进行插值加倍,对于500输入,数字将是1输出,对于输入0-499,数字将小于1。因此,截断后0-499输入将导致0输出,500将导致1。

答案 2 :(得分:0)

如果您在最大优化之后并且插值点已修复,则可以使用以下整数表达式:

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

格式为(A * X + B) / C,其中ABC是三个预先计算的整数常量。这将产生精确的整数答案。

或者,使用具有双精度预计算系数的A * X + B,但需要仔细调整舍入策略。

另一种可能性是使用2的幂重新缩放和舍入AB系数,给出形式的快速除法整数公式

(A * X + B) >> p

(舍入策略也很微妙)。