2

假设这么多:
我使用的是 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));

所以问题是......这是天才的一击(并不是说它还没有被想到或任何东西)还是完全浪费时间?

4

1 回答 1

1

重新编辑-因为我错了:)

看起来您正试图通过使用额外的 var 来获得更高的精度?

如果您确实在尝试提高精度,那么这将起作用,但为什么不使用整个 int 而不是仅使用 8 位呢?

好的,从您的评论中,您想知道如何在 32 位处理器上执行 64 位精度 muls。最简单的方法是如果你下面的处理器有一个长的乘法运算。如果它是 ARM,那么您很幸运,可以使用 long long 来执行您的 mul,然后移开您的越界低位并完成。

如果没有,您仍然可以进行 long long 乘法,并让编译器编写器为您完成处理溢出的繁重工作。这些是最简单的方法。

如果做不到这一点,你可以做 4 个 16 位乘法和一堆加法和移位:


// The idea is to break the 32-bit multiply into 4 16-bit 
parts to prevent any overflow.  You can break any 
multiply into factors and additions (all math here is unsigned):
      (ahi16)(alo16)
X     (bhi16)(blo16)
--------------------
      (blo16)(alo16)  - First  32-bit product var
  (blo16)(ahi16)<<16  - Second 32-bit product var (Don't shift here)
  (bhi16)(alo16)<<16  - Third  32-bit product var (Don't shift here)
+ (bhi16)(ahi16)<<32  - Forth  32-bit product var (Don't shift here)
--------------------
Final Value.  Here we add using add and add 
with carry techniques to allow overflow.

基本上,我们有一个低产品和一个高产品。低产品被分配第一个部分产品。然后将 2 个中间产品添加到上移 16。对于每个溢出,您将 1 添加到高产品并继续。然后将每个中间产品的高 16 位添加到高产品中。最后,将最后一个产品按原样添加到高产品中。

屁股很痛,但它适用于任何任意精确的值。

于 2010-05-26T15:36:22.037 回答