【问题标题】:extracting the first 32 bits of ASCII integer提取 ASCII 整数的前 32 位
【发布时间】:2011-10-06 17:46:39
【问题描述】:

你有一个 ASCII 字符串代表一个 128 位无符号整数 n,即 0

给出一个算法来提取 n 的二进制表示的最高有效 32 位,并将它们作为它们编码的无符号 32 位整数返回。

有什么快速的方法可以做到这一点,即比实现自己的大数除法和模 2 运算更好的方法。 假设一台 32 位机器,i。 e.你没有 64 位的内置类型。

示例: 为简洁起见,让我们取 4 位整数并提取前 2 位:

2(0010) --> 0(00) 7(0111) --> 1(01) 8(1000) --> 2(10) 13(1101) --> 3(11)

这不是家庭作业问题。更新我的算法技能以进行面试。

【问题讨论】:

  • MSB,整数也是十进制格式。
  • 为什么需要最高有效的 32 位?如果只使用最低的 32 位,会不会容易很多?我知道这只是一个面试练习,但我不明白为什么这很重要。
  • 澄清一下:你的意思是整数本身的 32 位,而不是它的字符串表示?数字可以有多大 - 最多 + 无穷大?前 32 位要考虑什么 - 从第一个非零位开始?
  • @RocketR 是的,位本身,作为 32 位 int 的结果给出,即该函数将返回单个 int,其位表示与前 32 位相同。
  • @RocketR 假设这些数字是可以放入 128 位的无符号整数。如果我们不给出固定的位大小表示,问题确实变得不清楚。

标签: algorithm bit-manipulation biginteger binary-data


【解决方案1】:

我认为没有比简单地模拟(有限形式的)128 位算术更有效的方法了。

假设我们有一个函数mul10add(a, b),它计算10*a + b并返回答案的低32位和一个进位值。如果我们有 64 位算术,它可以实现为(在伪代码中):

(word32, word32) mul10add(word32 a, word32 b):
    word64 result = 10*a + b
    word32 carry  = result >> 32
    return (result, carry)

现在,我们采用正常的十进制到二进制算法,并用四个 32 位字 xyzw 表示 128 位数字 n,这样 @987654329 @。然后,我们可以将对mul10add 的调用链接在一起,以执行与n = 10*n + digitToInt(decimal[i]) 等效的操作。

word32 high32bits(string decimal):
    word32 x = 0, y = 0, z = 0, w = 0

    # carry
    word32 c = 0

    for i in 0..length(decimal)-1
       (w, c) = mul10add(w, digitToInt(decimal[i]))
       (z, c) = mul10add(z, c)
       (y, c) = mul10add(y, c)
       (x, _) = mul10add(x, c)

    return x

然而,我们实际上并不需要 64 位架构来实现 mul10add。在 x86 上,我们有 mul 指令,它将两个 32 位数字相乘得到一个 64 位数字,高 32 位存储在 edx 中,低位存储在 eax 中。还有adc 指令,它将两个数字相加,但包括前一个add 的进位。所以,在伪汇编中:

(word32, word32) mul10add(word32 a, word32 b):
    word32 result, carry
    asm:
        mov a, %eax
        mul 10
        add b, %eax
        adc 0, %edx
        mov %eax, result
        mov %edx, carry
    return (result, carry)

【讨论】:

  • 这是一个不错的解决方案。我很好奇它是否可以扩展到具有 n 位整数而不是 128 位的一般情况。
  • @Spassski:当然,只需添加更多的词来表示n 和对mul10add 的相应调用。或者使用一个数组加上一个循环来使它在任意数量的位上工作。 (尽管对于不是 32 的倍数的位数,您必须将前两个单词中的位组合起来)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 2019-05-21
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 2011-06-10
相关资源
最近更新 更多