我有一个嵌入式 16 位 CPU。在这台机器上,整数是 16 位宽的,它支持 32 位宽的长整数。我需要做一些需要以 64 位存储的乘法运算(例如,将 32 位数乘以 16 位数)。我怎样才能在给定的约束下做到这一点?我没有数学库来做到这一点。
问问题
3115 次
2 回答
3
C 中的一个建议。请注意,使用内联汇编器可能更容易实现此代码,因为 C 中的进位检测似乎并不容易
// Change the typedefs to what your compiler expects
typedef unsigned __int16 uint16 ;
typedef unsigned __int32 uint32 ;
// The 64bit int
typedef struct uint64__
{
uint32 lower ;
uint32 upper ;
} uint64;
typedef int boolt;
typedef struct addresult32__
{
uint32 result ;
boolt carry ;
} addresult32;
// Adds with carry. There doesn't seem to be
// a real good way to do this is in C so I
// cheated here. Typically in assembler one
// would detect the carry after the add operation
addresult32 add32(uint32 left, uint32 right)
{
unsigned __int64 res;
addresult32 result ;
res = left;
res += right;
result.result = res & 0xFFFFFFFF;
result.carry = (res - result.result) != 0;
return result;
}
// Multiplies two 32bit ints
uint64 multiply32(uint32 left, uint32 right)
{
uint32 lleft, uleft, lright, uright, a, b, c, d;
addresult32 sr1, sr2;
uint64 result;
// Make 16 bit integers but keep them in 32 bit integer
// to retain the higher bits
lleft = left & 0xFFFF;
lright = right & 0xFFFF;
uleft = (left >> 16) ;
uright = (right >> 16) ;
a = lleft * lright;
b = lleft * uright;
c = uleft * lright;
d = uleft * uright;
sr1 = add32(a, (b << 16));
sr2 = add32(sr1.result, (c << 16));
result.lower = sr2.result;
result.upper = d + (b >> 16) + (c >> 16);
if (sr1.carry)
{
++result.upper;
}
if (sr2.carry)
{
++result.upper;
}
return result;
}
于 2013-08-25T06:25:27.727 回答
3
您可能想查看Hacker's Delight(这是一本书和一个网站)。他们有来自The Art of Computer Programming Vol.2的 Knuth 的有符号多字乘法和无符号多字乘法的 C 实现。
于 2013-12-11T06:31:45.080 回答