【问题标题】:Fixed point multiplication "solution," crazy or viable?定点乘法“解决方案”是疯狂的还是可行的?
【发布时间】:2010-05-26 15:10:42
【问题描述】:

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

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

【问题讨论】:

  • 好吧,我不明白你在这里要做什么。您是否尝试在没有浮点处理器但所有数字都是固定的 32 位机器上将 1.2341 乘以 0.7854,以便前 16 位是小数点前,后 16 位是小数点后?

标签: fixed-point


【解决方案1】:

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

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

如果您确实想提高精度,那么这会起作用,但为什么不使用整个 int 而不是只使用 8 位呢?

好的,通过您的 cmets,您想知道如何在 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)&lt&lt16  - Second 32-bit product var (Don't shift here)
  (bhi16)(alo16)&lt&lt16  - Third  32-bit product var (Don't shift here)
+ (bhi16)(ahi16)&lt&lt32  - 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 位添加到高产品中。最后,将最后一个产品按原样添加到高产品中。

很麻烦,但它适用于任何任意精度的值。

【讨论】:

  • 这编译并给出了预期的答案,所以不......答案不会出错。是的,如果值太大,这绝对会溢出。您可能错过了 fixed1 >>= 8... 但这确实会产生正确的答案。
  • 啊,你是对的,我错过了最初的转变。这完全改变了事情,是的 - 这会提高你的精确度。但是,如果您打算花时间处理额外的 var,不妨更进一步,使用整个 var 而不是 8 位。
  • 谢谢迈克尔。你是绝对正确的,这很容易溢出......我对使用类似的东西很粗略。老实说,总体问题...假设我不会溢出...这会比 float * float 快吗?
  • 我猜我当时不知道...如何在 32 位操作系统上存储 2 个 32 位值的初始乘法而不会溢出?
  • 在没有 FPU 的系统上,速度更快。我已经 10 多年没有使用 FPU 编码了,因此我已经非常习惯于定点数学。如何用溢出来做初始 mul?我将为此编辑我上面的帖子,以便我有空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多