【问题标题】:MIPS division of signed integers有符号整数的 MIPS 除法
【发布时间】:2010-03-10 21:27:57
【问题描述】:

我想知道是否有人可能知道如何在 MIPS 中执行两个有符号整数之间的除法,而不使用内置的除法运算。

在问题规范中,我被告知除数寄存器、ALU 和商寄存器都是 32 位宽,余数寄存器是 64 位。

【问题讨论】:

    标签: assembly integer mips division signed


    【解决方案1】:

    有多种方法 - 我建议Newton-Raphson,它简单快速,只使用乘法和减法。

    如果不允许乘法,那么似乎还有很多整数除法算法只使用移位、按位运算和加/减,例如谷歌第一击:www.bearcave.com/software/divide.htm

    【讨论】:

    • 更多信息:除数寄存器、ALU 和商寄存器都是 32 位宽,余数寄存器是 64 位。 ALU 和除数寄存器减半,余数左移。这将商寄存器与余数寄存器的右半部分结合起来。
    • 从表面上看,也不允许乘法
    【解决方案2】:

    想想你将如何手动执行二进制除法:

    # a/b, where a=2011 and b=18
    
                1101111 ←quotient
          ┌────────────         ↓
    10010 │ 11111011011  a
           -10010↓↓↓↓↓↓  -64b × 1
           ───────↓↓↓↓↓
             11010↓↓↓↓↓
            -10010↓↓↓↓↓  -32b × 1
            ───────↓↓↓↓
              10001↓↓↓↓
             -00000↓↓↓↓  -16b × 0
             ───────↓↓↓
              100011↓↓↓
              -10010↓↓↓   -8b × 1
              ───────↓↓
               100010↓↓
               -10010↓↓   -4b × 1
               ───────↓
                100001↓
                -10010↓   -2b × 1
                ───────
                  11111
                 -10010   -1b × 1
                 ──────                
                   1101  remainder
    

    这个“小学”长除法算法可以写成(用 Python ——我会让你把它转换成 MIPS):

    def unsigned_divide(dividend, divisor):
        if divisor == 0:
            raise ZeroDivisionError()
        if dividend < divisor:
            return 0
        # Determine the position of the first digit of the quotient
        shift_amt = dividend.bit_length() - divisor.bit_length()
        # Loop to find each bit of the quotient
        quotient = 0
        while shift_amt >= 0:
            # Calculate one bit of the quotient
            if dividend >= (divisor << shift_amt):
                 # new bit is 1
                 dividend -= (divisor << shift_amt)
                 quotient |= (1 << shift_amt)
            # Move to the next digit
            shift_amt -= 1
        return quotient
    

    对于有符号除法,您可以在跟踪符号的同时只除绝对值(假设您想要 C 风格的截断除法):

    def signed_divide(dividend, divisor):
        is_negative = (dividend < 0) ^ (divisor < 0)
        abs_quotient = unsigned_divide(abs(dividend), abs(divisor))
        return -abs_quotient if is_negative else abs_quotient
    

    【讨论】:

      猜你喜欢
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      相关资源
      最近更新 更多