【问题标题】:How to do 64 bit multiply on 16 bit machine?如何在 16 位机器上做 64 位乘法?
【发布时间】:2013-08-25 03:53:57
【问题描述】:

我有一个嵌入式 16 位 CPU。在这台机器上,整数是 16 位宽的,它支持 32 位宽的长整数。我需要做一些需要以 64 位存储的乘法运算(例如,将 32 位数字乘以 16 位数字)。我怎样才能在给定的约束下做到这一点?我没有数学库来做这件事。

【问题讨论】:

  • 您需要一个数学库,以函数调用的形式提供这种服务。
  • 嗯......你没有提供足够的信息。你是用汇编程序还是 C 或其他东西编程?您将需要自己获取或编写一个执行乘法运算的函数或子程序。尝试在 Google 上搜索“微处理器数学库的名称”。如果可能的话开源,然后你可以看到它是如何完成的源代码,如果你不想在你的程序中包含整个库,只需复制说明即可。 (这不是我的专业领域,我做这种编程已经 35 年了,我很惊讶它仍然是必要的。)
  • 如果您提供微处理器的名称可能会有所帮助,而不仅仅是说“嵌入式 16 位 cpu”。
  • 现在我想起来了,在“过去的美好时光”中,微处理器制造商通常会提供免费的数学库和/或发布建议的算术函数来做这类事情。但就像我说的,我不知道现在如何为微处理器进行低级编程。

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您可能想查看Hacker's Delight(这是一本书和一个网站)。他们有来自 The Art of Computer Programming Vol.2 的 Knuth 的 signed multiword multiplicationunsigned multiword multiplication 的 C 实现。

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 2012-11-07
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 2014-11-02
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多