我正在尝试乘以 A*B
在 16 位定点中,同时保持尽可能高的准确性。 A
是 16 位无符号整数范围,B
除以 1000 并且总是在 0.001
之间和 9.999
.我已经有一段时间没有处理这样的问题了,所以:
A*B/1000
移动到 32 位变量后,然后剥离回 16 位 有没有什么简单的方法可以做到这一点?
编辑:
A
将在 0 到 4000 之间,因此所有可能的结果也在 16 位范围内。编辑:
B
来自用户,在 X.XXX
中逐位设置掩码,这就是为什么操作是 /1000
.
最佳答案
不,你必须去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 位来优化它。这应该比做倒数乘法技巧要快得多。
关于c - 已知范围内的定点乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3276864/