我正在尝试将A*B
乘以16位定点,同时尽可能保持准确性。 A
在无符号整数范围内为16位,B
除以1000,始终在0.001
和9.999
之间。我处理过类似的问题已经有一段时间了,所以:
A*B/1000
,然后剥离回16位有没有简单的方法呢?
编辑:A
将在0到4000之间,因此所有可能的结果也都在16位范围内。
编辑:B
来自用户,在X.XXX
掩码中逐位设置,这就是操作/1000
的原因。
答案 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位来优化它。这应该比做倒数乘法技巧快得多。