我有一个嵌入式16位CPU。在这台机器上,它是16位宽,它支持32位宽的long。我需要进行一些需要以64位存储的乘法(例如,将32位数乘以16位数)。如何使用给定的约束来做到这一点?我没有数学库来做这件事。
答案 0 :(得分: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;
}
答案 1 :(得分:2)
您可能需要查看Hacker's Delight(这是一本书和一个网站)。他们有来自signed multiword multiplication的Knuth unsigned multiword multiplication和The Art of Computer Programming Vol.2的C实现。