已知范围内的定点乘法

时间:2010-07-18 19:11:51

标签: c math fixed-point

我正在尝试将A*B乘以16位定点,同时尽可能保持准确性。 A在无符号整数范围内为16位,B除以1000,始终在0.0019.999之间。我处理过类似的问题已经有一段时间了,所以:

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

有没有简单的方法呢?

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

编辑:B来自用户,在X.XXX掩码中逐位设置,这就是操作/1000的原因。

1 个答案:

答案 0 :(得分: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位乘法的多个步骤完成。

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

以下是具有此类内在函数的Texas Instruments 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位来优化它。这应该比做倒数乘法技巧快得多。