C编程型铸造与定点

C编程型铸造与定点,c,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 我关心的是不同类型的混合,尤其是溢出不会发生。还有,如果有很多类型转换,如何以干净的方式编写它。这里是 unsigned int fu

如何在C代码中实现此函数

U16 newValue function(U16 value, S16 x, U16 y){
   newValue = min((((value - x) * y) >> 10) >> 4, 4095)
   return newValue
} 
y是具有10个小数位的定点

如果x大于该值,则最终结果应为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;
}
unsigned int函数(unsigned int value,signed int x,unsigned int y){
如果(((值-x)*y)>>10)>>4>10)>>4;
否则返回4095;
}

您需要为输入中给定参数的所有可能值编码函数。取表达式
(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
cast替换为
S64
cast,因为您仍然需要它

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

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

您从代码片段中引用了哪个函数,即
min
函数?请首先提供清晰正确的代码(可能是伪代码)。在这里,我们忽略了所有的上下文。应该是C吗?如果是,问题是什么?什么是
U16
min
?@JensGustedt我们都是这里的开发者,我想我们都可以推断出
U16
min
的意思。@sturcotte06,对不起,我不能,有太多悬而未决的问题,我根本不理解这个问题。例如,这种错误的类型
U16
是否应该至少与
int
一样宽?代码的全部含义可能会改变。如果我对这些类型进行一些猜测,我会给出一个版本,其中对有符号整数执行
>10
。这是故意的吗?简而言之,这个问题的质量很差。
S16
=>16位的有符号整数,
U16
=>16位的无符号整数,
min
=>函数总是使用相同的签名实现,返回两个给定数字中的最小数字。我想演绎是一门艺术。我没有得到你的答案,解释一下。告诉我哪一行困扰着你?谢谢。但和y相乘后会发生什么呢?“>>10”移位是在定点乘法后截断小数部分。所有的东西都是定点的,里面没有浮点数,是吗?y输入是定点的,有10个小数位,我必须在与y相乘后将结果右移10以截断小数部分。我认为这对于无符号int没有问题,但不确定当你使用有符号int时会发生什么。好吧,你所有的参数都是定点的(有符号int 16和无符号int 16)。将浮点作为int传递是一种代码气味,如果老师教你这个,你应该责骂他。根据您给出的伪代码,所有参数都是整数,并返回一个整数。如果这在浮点土地上发挥了神奇的作用,那么您只会寻找问题。