没有64位临时的定点乘法

时间:2013-02-27 22:22:36

标签: c optimization fixed-point

嗨我正在为嵌入式系统实现一些定点数学的东西,我试图将两个16.16定点数相乘而不创建64位临时数。到目前为止,我提出的代码产生的指令最少。

int multiply(int x, int y){
    int result;
    long long temp = x;
    temp *= y;
    temp >>= 16;
    result = temp;
    return result;
}

此代码的问题在于它使用临时的64位整数,这似乎会生成错误的汇编代码。我正在尝试制作一个使用两个32位整数而不是64位整数的系统。有谁知道怎么做?

1 个答案:

答案 0 :(得分:5)

将您的数字视为由两个大数字组成的数字。

  A.B
x C.D

数字的“基数”是2 ^ bit_width,即2 ^ 16或65536。

所以,产品是

D*B       + D*A*65536 + C*B*65536 + C*A*65536*65536

但是,要将产品右移16,您需要将所有这些项除以65536,所以

D*B/65536 + D*A       + C*B        + C*A*65536

在C:

uint16_t a = x >> 16;
uint16_t b = x & 0xffff;
uint16_t c = y >> 16;
uint16_t d = y & 0xffff;

return ((d * b) >> 16) + (d * a) + (c * b) + ((c * a) << 16);

签名版本有点复杂;通常最简单的方法是对xy的绝对值执行算术,然后修复符号(除非你溢出,你可以检查相当繁琐)。