嗨我正在为嵌入式系统实现一些定点数学的东西,我试图将两个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位整数的系统。有谁知道怎么做?
答案 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);
签名版本有点复杂;通常最简单的方法是对x
和y
的绝对值执行算术,然后修复符号(除非你溢出,你可以检查相当繁琐)。