【问题标题】:Multiplying two 32 bit numbers without using 64 bit int在不使用 64 位 int 的情况下将两个 32 位数字相乘
【发布时间】:2010-11-24 05:40:59
【问题描述】:

我们正在使用以下算法进行一些 32 位 * 32 位乘法

让我们想将 a(32 位)与 b(32 位)相乘,两者都是有符号的,

a = ah * 2^16 + al [ah - 高 16 位,al - 低 16 位]

b = bh * 2^16 + bl [bh - 高 16 位,bl - 低 16 位]

我们正在有效地做

结果 = (al * bl) + (((ah * bl) + (al * bh)) * 2^16) + ((ah * bh) * 2 ^ 32) ~~~


我的问题,

他们有更好的方法吗?

【问题讨论】:

  • 在什么处理器上?例如,在 x86 上,当您将两个 32 位数字相乘时,结果的高 32 位存储在 EDX 中,而低位存储在 EAX 中。与 16 位类似。
  • 我们需要为 32 位处理器设计这个,处理器可以是 ARM、MIPS 之类的任何东西……
  • 使用 int64_t 并让编译器代码生成器操心如何实现它。如果代码生成很差,你只需要手动做一些事情,这对于这样一个简单的情况是不可能的。

标签: algorithm 32bit-64bit multiplication


【解决方案1】:

在任何主流编译器中,在 32 位平台上模拟 64 位整数与您自己进行多步数学运算一样有效。但它会更可靠地正确。

当使用大到足以溢出的值进行简单的算术运算时,即使是我见过的最高度优化的数学库也只使用 int64。

【讨论】:

    【解决方案2】:

    谷歌“Karatsuba 乘法”。

    哦,在您的代码中,将常量 2​​^15(它出现两次)更改为 2^16。

    【讨论】:

      【解决方案3】:

      答案是否定的,除了使用位移位和掩码代替 2^n 之外,没有更好的处理方式。即:

      a * 2^n <=> a << n
      

      其次,您的整数是有符号的还是无符号的?如果他们签署了,那就改变了。

      第三,我不确定你的 2^15 是否正确。如果它至少是无符号的,则您希望将位移动 16 而不是 15。

      最后,您必须注意低位 int 中的整数溢出。如果将溢出的低位 int 中的数字相加,则需要正确递增高位 int。

      【讨论】:

      • +1 我猜 2^15 是一个错误。伤心,这是最好的方法~~~
      【解决方案4】:

      您需要知道(指定)如何存储 64 位值 - 大概是一对 32 位值,可能是数组的两个元素,或结构的两个元素。您还需要考虑如何将标志信息存储在结果中。

      从机械上讲,您可能希望将两个有符号值都转换为无符号值,然后按照您显示的行进行拆分和重新组合,注意确保低位 32 位值的进位在高位得到正确管理32 位值。

      根据您最初的设计决策,您可能还需要调整结果符号的表示,甚至可能需要调整所有其他位。

      类似的 cmets 适用于将两个 16 位数字相乘而没有任何 32 位结果,这曾经很重要,但大多数人不必担心。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-24
        • 2012-03-16
        • 1970-01-01
        相关资源
        最近更新 更多