固定点乘法,没有64位临时

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

想想你的数字,每个数字由两个大的“数字”组成。

  AB x CD 

数字的“基数”是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的绝对值执行算术,然后修复符号(除非你溢出,你可以检查相当繁琐)。