不带64位临时性的定点乘法 [英] fixed point multiplication without 64 bit temporary

查看:80
本文介绍了不带64位临时性的定点乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为嵌入式系统实现一些定点数学知识,并且我尝试对两个16.16定点数进行乘法运算,而不创建64位临时数.到目前为止,这里是我想出的产生最少指令的代码.

Hi I'm implementing some fixed point math stuff for embedded systems and I'm trying to do the multiplication of two 16.16 fixed point numbers without creating a 64bit temporary. So far here is the code I came up with that generates the least instructions.

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

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

the problem with this code is that it uses a temporary 64 bit integer which seem to generate bad assembly code. I'm trying to make a system that uses two 32 bit integers instead of a 64 bit one. Anyone know how to do this?

推荐答案

请考虑一下您的数字,因为每个数字都由两个大的数字"组成.

Think of your numbers as each composed of two large "digits."

  A.B
x C.D

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

The "base" of the digits is the 2^bit_width, i.e., 2^16, or 65536.

因此,产品是

D*B       + D*A*65536 + C*B*65536 + C*A*65536*65536

但是,要将乘积右移16,则需要将所有这些项除以65536,因此

However, to get the product shifted right by 16, you need to divide all these terms by 65536, so

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的绝对值进行算术运算,然后修正符号(除非您溢出,可以很麻烦地对其进行检查).

The signed version is a bit more complicated; it is often easiest to perform the arithmetic on the absolute values of x and y and then fix the sign (unless you overflow, which you can check for rather tediously).

这篇关于不带64位临时性的定点乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆