4

こんにちは、組み込みシステム用の固定小数点演算を実装しています。64 ビットの一時ファイルを作成せずに、2 つの 16.16 固定小数点数の乗算を実行しようとしています。これまでのところ、最小の命令を生成するコードを思いつきました。

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

このコードの問題は、一時的な 64 ビット整数を使用しているため、不適切なアセンブリ コードが生成されるように見えることです。64 ビット整数の代わりに 2 つの 32 ビット整数を使用するシステムを作成しようとしています。誰でもこれを行う方法を知っていますか?

4

1 に答える 1

6

数字はそれぞれ 2 つの大きな「数字」で構成されていると考えてください。

  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 に答える