C编程型铸造和定点

时间:2017-02-21 20:26:21

标签: c

如何在C代码中实现此功能?

U16 newValue function(U16 value, S16 x, U16 y){
   newValue = min((((value - x) * y) >> 10) >> 4, 4095)
   return newValue
} 

y是10个小数位的固定点

如果x大于值,则最终结果应为0.

我担心的是特别是不同类型之间的混合,并且不会发生溢出。还有如何写一个干净的为什么如果会有很多类型转换。

2 个答案:

答案 0 :(得分:0)

这是

unsigned int function(unsigned int value, signed int x, unsigned int y){
  if((((value - x) * y) >> 10) >> 4<4095)
  return (((value - x) * y) >> 10) >> 4;
  else return 4095;
}

答案 1 :(得分:0)

您需要为输入中给出的参数的所有可能值编写函数。取表达式(value - x)。如果value等于2 ^ 16且x等于2 ^( - 15),则(value - x)的结果将为98304,大于U16。因此,我会在此操作之前将value强制转换为S32

让表达式(value - x)折叠到其最大值98304.表达式((value - x) * y)的最大值将是98304 * 2 ^ 16,等于6442450944,这是一个比32位整数更大的值可以容纳。因此,您需要将此表达式计算为U64。您只需将最初的U32演员阵容替换为S64演员阵容,因为您无论如何都需要它。

右移位操作仅减少有效位数。因此,这不需要计算更多的位数。

min调用确保结果不能大于4095,可以保存在U16;不再需要施放。

最终功能:

uint16_t newValue(uint16_t value, int16_t x, uint16_t y){
    int64_t newValue = (int64_t)(value);
    newValue -= x;
    newValue *= y;
    newValue >>= 10;
    newValue >>= 4;
    newValue = min(newValue, 4095);

    // Or as a one liner.
    // uint64_t newValue = min(((((int64_t)value - x) * y) >> 10) >> 4, 4095);

    return (uint16_t) newValue;
}