2017-02-21 103 views
-1

你应该如何在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

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

+0

你从你的代码片段中,'min'功能指的是功能? – Sitram

+1

请提供清晰正确的代码(可能是伪代码)。在这里,我们错过了所有的上下文。它应该是C吗?如果是,那么问题是什么?什么是'U16','min'? –

+0

@JensGustedt我们都是开发人员,我想我们都可以推断'U16'和'min'的含义。 – sturcotte06

回答

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

谢谢。但是在乘以y之后会发生什么,这是固定点? “>> 10”移位是在定点乘法之后截断小数部分。 – Perry

+0

一切都是固定点,那里没有浮子,是吗? – sturcotte06

+0

y输入是固定点,有10个小数位,我必须用y乘以10后右移结果以截断小数部分。我认为这对于unsigned int没有问题,但不知道当你用带符号的int来做这件事时会发生什么。 – Perry

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

我没有得到你的解决方案,解释它。 –

+0

告诉我哪一条线在困扰你? –

+0

第二和第三行 –