如何在C代码中实现此功能?
U16 newValue function(U16 value, S16 x, U16 y){
newValue = min((((value - x) * y) >> 10) >> 4, 4095)
return newValue
}
y是10个小数位的固定点
如果x大于值,则最终结果应为0.
我担心的是特别是不同类型之间的混合,并且不会发生溢出。还有如何写一个干净的为什么如果会有很多类型转换。
答案 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;
}