定点乘法“解”,疯狂还是可行?
假设这么多:
我使用的是 16.16 定点系统。
系统是32位的。
CPU没有浮点处理器。
对于大于 1.0 * 0.4999 的任何乘法,溢出都是迫在眉睫的
最后一个假设...假设我正在工作的值不会太高而导致此操作溢出...
//assume that in practical application
//this assignment wouldn't be here as 2 fixed values would already exist...
fixed1 = (int)(1.2341 * 65536);
fixed2 = (int)(0.7854 * 65536);
mask1 = fixed1 & 0xFF; //mask off lower 8 bits
fixed1 >>= 8; //keep upper 24 bits... assume value here isn't too large...
answer = (((fixed2 * fixed1) >> 8) + ((fixed2 * mask1) >> 16));
所以问题是..这是天才之举(并不是说还没有想到过)还是完全浪费时间?
Assume this much:
I'm using a 16.16 fixed point system.
System is 32 bit.
CPU has no floating point processor.
Overflow is pretty imminent for multiplication for anything larger than 1.0 * 0.4999
To make one last assumption... lets say the values I'm working will not be so high as to cause overflow in this operation...
//assume that in practical application
//this assignment wouldn't be here as 2 fixed values would already exist...
fixed1 = (int)(1.2341 * 65536);
fixed2 = (int)(0.7854 * 65536);
mask1 = fixed1 & 0xFF; //mask off lower 8 bits
fixed1 >>= 8; //keep upper 24 bits... assume value here isn't too large...
answer = (((fixed2 * fixed1) >> 8) + ((fixed2 * mask1) >> 16));
So the question is... is this a stroke of genius (not to say it hasn't already been thought of or anything) or a complete waste of time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
重新编辑 - 因为我错了:)
看来您正在尝试通过使用额外的 var 来获得更高的精度?
如果您确实想提高精度,那么这会起作用,但为什么不使用整个 int 而不是仅使用 8 位呢?
好的,根据您的评论,您想知道如何在 32 位处理器上进行 64 位精度乘法。最简单的方法是如果您下面的处理器有一个长乘法运算。如果它是 ARM,那么您很幸运,可以使用 long long 进行乘法,然后移走超出范围的低位并完成。
如果没有,您仍然可以执行 long long 乘法,并让编译器编写者为您完成处理溢出的繁重工作。这些是最简单的方法。
如果做不到这一点,你就需要进行 4 次 16 位乘法以及一系列加法和移位:
基本上,我们有一个低乘积和一个高乘积,低乘积被分配给第一个部分乘积。然后,将 2 个中间乘积向上移动 16。对于每次溢出,将 1 添加到高乘积并继续。然后将每个中间乘积的高 16 位添加到高乘积中。最后,将最后一个产品按原样添加到高产品中。
这是一个很大的痛苦,但它适用于任何任意精度的值。
Re-edit - because I was wrong :)
Looks like you are trying to get higher precision by using an extra var?
If you are indeed trying to increase precision, then this would work, but why not use the whole int instead of just 8-bits?
Ok, from your comments, you wanted to know how to do 64-bit precision muls on a 32-bit processor. The easiest way is if the processor underneath you has a long multiply op. If it's an ARM, you are in luck and can use long long to do your mul then shift away your out of bounds low bits and be done.
If it does not, you can still do a long long multiply and let the compiler writer do the heavy lifting of handling overflow for you. These are the easiest methods.
Failing that, you get to do 4 16-bit multiplies and a bunch of adds and shifts:
Basically, we have a low product and a high product The low product gets assigned the first partial product. You then add in the 2 middle products shifted up 16. For each overflow, you add 1 to the high product and continue. Then add the upper 16-bits of each middle product into the high product. Finally, add the last product as is into the high product.
A big pain in the butt, but it works for any abitrary precision of values.