没有64位临时的定点乘法

Pgr*_*rAm 4 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;
}
Run Code Online (Sandbox Code Playgroud)

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

Dou*_*rie 5

想想你的数字,每个数字由两个大的"数字"组成.

  A.B
x C.D
Run Code Online (Sandbox Code Playgroud)

数字的"基数"是2 ^ bit_width,即2 ^ 16或65536.

所以,产品是

D*B       + D*A*65536 + C*B*65536 + C*A*65536*65536
Run Code Online (Sandbox Code Playgroud)

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

D*B/65536 + D*A       + C*B        + C*A*65536
Run Code Online (Sandbox Code Playgroud)

在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);
Run Code Online (Sandbox Code Playgroud)

签名版本有点复杂; 它往往是最容易上的绝对值进行算术xy,然后修复号(除非你溢出,它可以检查相当繁琐).

  • 这比你最初尝试的方式要快得多. (2认同)