4

嗨,我正在为嵌入式系统实现一些定点数学东西,我正在尝试将两个 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 位整数的系统。有人知道怎么做吗?

4

1 回答 1

6

将您的数字想象为每个数字都由两个大“数字”组成。

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

签名版本有点复杂;通常最容易对 的绝对值执行算术x然后y修复符号(除非您溢出,您可以相当乏味地检查它)。

于 2013-02-27T22:35:29.667 回答