3

我正在尝试以A*B16 位定点乘法,同时保持尽可能高的精度。A是无符号整数范围内的 16 位,B除以 1000 并且始终介于0.001和之间9.999。自从我处理这样的问题以来已经有一段时间了,所以:

  • 我知道我可以A*B/1000在移动到 32 位变量后做,然后剥离回 16 位
  • 我想让它比那更快
  • 我想在不移动到 32 位的情况下完成所有操作(因为我只有 16 位乘法)

有什么简单的方法可以做到这一点吗?

编辑:A将介于 0 和 4000 之间,因此所有可能的结果也在 16 位范围内。

编辑:来自用户,在掩码中B逐位设置,这就是为什么操作是.X.XXX/1000

4

1 回答 1

3

不,您必须转到 32 位。一般来说,两个 16 位数字的乘积总是会给你一个 32 位宽的结果。

您应该检查您正在处理的 CPU 的 CPU 指令集,因为 16 位机器上的大多数乘法指令都可以选择直接将结果作为 32 位整数返回。

这会对您有很大帮助,因为:

short testfunction (short a, short b)
{
  int A32 = a;
  int B32 = b;

  return A32*B32/1000
}

将强制编译器执行 32 位 * 32 位乘法。在您的机器上,这可能会非常慢,甚至仅使用 16 位乘法就可以在多个步骤中完成。

一点内联汇编甚至更好的编译器内在函数可以大大加快速度。

以下是德州仪器 C64x+ DSP 的示例,它具有这样的内在函数:

short test (short a, short b) 
{
  int product = _mpy (a,b); // calculates product, returns 32 bit integer
  return product / 1000;
}

另一个想法:你除以 1000。这是你的选择吗?使用 2 的幂作为定点数的基数会快得多。1024 已接近。你为什么不:

  return (a*b)/1024 

反而?编译器可以通过使用右移 10 位来优化这一点。这应该比做倒数乘法技巧快得多。

于 2010-07-18T19:24:42.540 回答