64-bit - 如何在16位机器上进行64位乘法?

标签 64-bit 16-bit multiplication integer-arithmetic

我有一个嵌入式 16 位 CPU。在这台机器上,int 是 16 位宽,并且支持 32 位宽的 long。我需要进行一些需要存储在 64 位中的乘法(例如,将 32 位数字乘以 16 位数字)。在给定的限制下我该如何做到这一点?我没有数学库来执行此操作。

最佳答案

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;
}

关于64-bit - 如何在16位机器上进行64位乘法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44129902/

相关文章:

.NET 堆栈内存限制

c++ - x64 程序集双字上的符号扩展

assembly - 计算设置位。 16位汇编奇偶校验程序

java - 无法添加两个 JTabbedPane

sql-server-2005 - 通过 Openrowset 和 Microsoft.ACE.OLEDB.12.0 从 csv 导入(到不同的列)

visual-studio-2010 - VS2010中64位windows服务的部署包

c++ - 将表达式评估为函数参数时,Visual Studio 2013 有符号/无符号整数数学行为不同,编译器开关?

c - 是什么导致 16 位架构上的地址错误?

Pythonic 整数乘法和加法

c++ - 是否可以使用纹理内存加速矩阵乘法?