3

我目前正在尝试弄清楚如何在定点表示中将两个数字相乘。

说我的数字表示如下:

[SIGN][2^0].[2^-1][2^-2]..[2^-14]

就我而言,数字10.01000000000000 = -0.25.

例如,我将如何做0.25x0.25-0.25x0.25等等?

希望你能帮忙!

4

3 回答 3

4

乘以一个更大的变量,然后右移定点精度的位数。

于 2012-12-23T03:39:26.360 回答
3

您应该使用 2 的补码表示而不是单独的符号位。对此进行数学运算要容易得多,不需要特殊处理。范围也得到了改进,因为负 0 没有浪费的位模式。要乘法,只需像正常的定点乘法一样。正常的 Q2.14 格式将为 x的位模式存储值 x/2 14 ,因此如果我们有 A 和 B,那么

\frac{A}{2^{14}}\times\frac{B}{2^{14}} = \frac{A \times B}{2^{14}}\times \frac{1}{ 2^{14}}

因此,您只需将 A 和 B 直接相乘,然后将乘积除以 2 14即可将结果返回为 x/2 14的形式,如下所示

AxB = ((int32_t)A*B) >> 14;

需要一个舍入步骤来获得最接近的值。您可以在Q 数字格式#Math operations中找到方法。最简单的舍入到最接近的方法就是像这样加回最后移出的位(即第一个小数位)

AxB = (int32_t)A*B;
AxB = (AxB >> 14) + ((AxB >> 13) & 1);

您可能还想阅读这些

使用 2 位可以表示 [-2, 1] 的整数范围。因此使用 Q2.14 格式,-0.25 将存储为11.11000000000000. 使用 1 个符号位只能表示 -1、0、1,这会使计算更加复杂,因为您需要拆分符号位,然后在最后将其组合回来。

于 2013-09-26T00:26:39.510 回答
1

这是 C 语言中的一个简单示例:

int a =  0.25 * (1 << 16);
int b = -0.25 * (1 << 16);
int c = (a * b) >> 16;
printf("%.2f * %.2f = %.2f\n", a / 65536.0, b / 65536.0 , c / 65536.0);

您基本上将所有内容都乘以一个常数,以将小数部分提升到整数范围,然后将这两个因子相乘,然后(可选地)除以其中一个常数,将乘积返回到标准范围,以供将来计算使用。这就像以小数美元表示的价格乘以 100,然后以美分计算(即 1.95 美元 * 100 美分/美元 = 195 美分)。

小心不要溢出要乘入的变量范围。您的常量可能需要更小以避免溢出,例如在上面的示例中使用1 << 8而不是1 << 16

于 2013-01-30T20:15:05.667 回答