32位有符号整数乘法,不使用64位数据类型

我想在不使用64位数据类型的情况下进行32位有符号整数乘法。 我的输入是Q1.31(两种)格式。

input1 = A32 (Ah Al) - higher, lower half's of A32 input2 = B32 (Bh Bl) - higher, lower half's of B32 

结果应为Q1.31格式,保留溢出情况。

我需要C代码。 请提供格式说明。

有符号的Q1.31格式是一种完全分数格式,能够表示-1和几乎+1之间的操作数。 比例因子是2 31 。 这意味着当每个Q1.31操作数存储在32位有符号整数中时,我们可以通过计算有符号整数的完整双宽乘积来生成Q1.31乘积,然后将结果右移31位。 右移是必要的,因为产品包括比例因子两次,并且移位充当除去比例因子的一个实例的除法。

我们可以通过分别计算完整产品的上下32位来计算两个32位整数的双宽度乘积。 低32位是作为两个输入的普通乘积而平凡计算的。 要计算高32位,我们需要编写一个函数mul32hi() 。 为了避免在中间计算中使用更宽的类型(即使用超过32位的类型),我们需要将原始操作数分成两半,计算它们的部分乘积,然后适当地对这些部分乘积求和。

请注意,各种处理器提供实现mul32hi()function的硬件指令。 在这种情况下,如果不存在内在的,则可能希望使用适当的内部或一些内联汇编代码,而不是使用此处提供的仿真代码。

它有助于首先将问题减少到相应的无符号乘法umul32hi() ,然后通过2的补码表示的定义(在下面的C代码中假设umul32hi()从中导出签名结果:

 #include  /* compute the upper 32 bits of the product of two unsigned 32-bit integers */ uint32_t umul32hi (uint32_t a, uint32_t b) { /* split operands into halves */ uint32_t al = (uint16_t)a; uint32_t ah = a >> 16; uint32_t bl = (uint16_t)b; uint32_t bh = b >> 16; /* compute partial products */ uint32_t p0 = al * bl; uint32_t p1 = al * bh; uint32_t p2 = ah * bl; uint32_t p3 = ah * bh; /* sum partial products */ uint32_t cy = ((p0 >> 16) + (uint16_t)p1 + (uint16_t)p2) >> 16; return p3 + (p2 >> 16) + (p1 >> 16) + cy; } /* compute the upper 32 bits of the product of two signed 32-bit integers */ int32_t mul32hi (int32_t a, int32_t b) { return umul32hi (a, b) - ((a < 0) ? b : 0) - ((b < 0) ? a : 0); } /* compute the full 64-bit product of two signed 32-bit integers */ void mul32wide (int32_t a, int32_t b, int32_t *rhi, int32_t *rlo) { *rlo = a * b; /* bits <31:0> of the product a * b */ *rhi = mul32hi (a, b); /* bits <63:32> of the product a * b */ } /* compute the product of two signed Q1.31 fixed-point numbers */ int32_t mul_q_1_31 (int32_t a, int32_t b) { int32_t hi, lo; mul32wide (a, b, &hi, &lo); /* Q1.31 is scaled by 2**31, trim out scale factor */ return (int32_t)(((uint32_t)hi << 1) | ((uint32_t)lo >> 31)); } 

我将请求解释为“保留溢出情况”意味着忽略溢出。 因此,将-1(0x80000000)乘以-1(0x80000000)与mul_q_1_31()将返回-1(0x80000000)。

以下站点旨在提供一个32位的ANSI-C库实现,通常用于操作Q-number: http : //www.ti.com/tool/sprc542

我没有试过这个,也不能保证它会为你做什么或不会做什么,但是在那个网站上有一个链接可以请求源代码。