【问题标题】:Is booth multiplication algorithm for multiplying 2 positive numbers?展位乘法算法是用于将 2 个正数相乘吗?
【发布时间】:2011-11-19 04:08:38
【问题描述】:

booth algorithm for multiplication 是否仅用于乘以 2 个负数 (-3 * -4) 或一个正数和一个负数 (-3 * 4) ?每当我使用展位算法将 2 个正数相乘时,我都会得到错误的结果。

示例:5 * 4

A = 101 000 0 // binary of 5 is 101

S = 011 000 0 // 2's complement of 5 is 011

P = 000 100 0 // binary of 4 is 100

x = 3 number of bits in m

y = 3 number of bits in r

m = 5

-m = m 的 2 的补码

r = 4

  1. P 右移 1 位后 0 000 100

  2. P 右移 1 位后 0 000 010

  3. P+S = 011 001 0

    右移1位后0 011 001

  4. 丢弃 LSB 001100

    但那是 12 的二进制数。应该是 20(010100)

更新 @ruakh 回答后

5 * 4 = 20

m = 0101 is 5

r = 0100 is 4

A = 0101 0000 0

S = 1010 0000 0

P = 0000 0100 0

  1. 将 P 右移 1 位:0 0000 0100

  2. 将 P 右移 1 位:0 0000 0010

  3. P+S = 10100010 右移 1 位:1101 0001

  4. P+A = 1 0010 0001 here 1 is the carry generated 右移 1 位:110010000

离开LSB:11001000(不等于20)

【问题讨论】:

    标签: algorithm hardware computer-science multiplication


    【解决方案1】:

    您没有为标志处理提供足够的空间。 5 不是101,而是0101:它必须以0 开头,因为以1 开头的值是负数。 101其实是-3:是011的补码,也就是3。同样,4不是100,而是0100100 是-4。因此,当您将101 乘以100 时,实际上是在将-3 乘以-4;这就是你得到 12 的原因。

    【讨论】:

    • 请查看更新。我仍然没有得到结果。怎么了?
    • @grassPro:现在你的 S 错了:你倒置了位,但忘记加 1。:-)
    • 是的,我犯了一个错误。在第四步更正并计算P+A 后,在 P+A 的 MSB 中生成了一个进位。如果我省略它,我会得到正确的答案。但是为什么我们必须省略它。就像在第 4 步中一样:P+A = 110110001 + 010100000 = 1 001010001,查看 MSB 中生成的进位 (1)。如果我省略它,我将在下一步中得到正确答案,我必须省略数字的 LSB。
    • @grassPro:回复:“为什么我们必须省略它”:嗯,因为这就是算法所说的。 (您链接到的维基百科文章说“忽略任何溢出。”)如果您想要更深层次的原因,请记住 1011...11111011 的含义相同,not ...00001011。所以如果你执行符号扩展,这个携带的1实际上会无限期地继续向左携带,一路上将所有1s更改为0s。
    • @ruakh 当我使用展位算法乘以 11*13 时,我得到了错误的结果。我得到 0010001111 但我应该得到 10001111 。 MSB 中的两个零丢失。会有所作为吗
    【解决方案2】:

    Booth 算法适用于有符号整数,即每个整数可以是正数或负数或零。

    这是一个示例 C 程序,它说明了将两个 8 位有符号(2 的补码)整数相乘并得到一个 16 位有符号乘积的实现和中间结果:

    #include <stdio.h>
    #include <limits.h>
    #include <string.h>
    
    typedef signed char int8;
    typedef short int16;
    
    char* Num2BaseStr(unsigned long long num, unsigned base, int maxDigits)
    {
      static char s[sizeof(num) * CHAR_BIT + 1];
      char* p = &s[sizeof(s) - 1];
    
      memset(s, 0, sizeof(s));
    
      do
      {
        *--p = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[num % base];
        num /= base;
      } while ((num != 0) || (p > s));
    
      // Keep at most maxDigits digits if requested
      if ((maxDigits >= 0) && (&s[sizeof(s) - 1] - p > maxDigits))
      {
        p = &s[sizeof(s) - 1] - maxDigits;
      }
      // Skip leading zeroes otherwise
      else
      {
        while (*p == '0') p++;
      }
    
      return p;
    }
    
    int16 BoothMul(int8 a, int8 b)
    {
      int16 result = 0;
      int16 bb = b;
      int f0 = 0, f1;
      int i = 8;
    
      printf("a = %sb (%d)\n", Num2BaseStr(a, 2, 8), a);
      printf("b = %sb (%d)\n", Num2BaseStr(b, 2, 8), b);
      printf("\n");
    
      while (i--)
      {
        f1 = a & 1;
        a >>= 1;
    
        printf("        %sb\n", Num2BaseStr(result, 2, 16));
        printf("(%d%d)  ", f1, f0);
        if (!f1 && f0)
        {
          printf("+ %sb\n", Num2BaseStr(bb, 2, 16));
          result += bb;
        }
        else if (f1 && !f0)
        {
          printf("- %sb\n", Num2BaseStr(bb, 2, 16));
          result -= bb;
        }
        else
        {
          printf("no +/-\n");
        }
        printf("\n");
    
        bb <<= 1;
    
        f0 = f1;
      }
    
      printf("a * b = %sb (%d)\n", Num2BaseStr(result, 2, 16), result);
    
      return result;
    }
    
    int main(void)
    {
      const int8 testData[][2] =
      {
        {  4,  5 },
        {  4, -5 },
        { -4,  5 },
        { -4, -5 },
        {  5,  4 },
        {  5, -4 },
        { -5,  4 },
        { -5, -4 },
      };
      int i;
    
      for (i = 0; i < sizeof(testData)/sizeof(testData[0]); i++)
        printf("%d * %d = %d\n\n",
               testData[i][0],
               testData[i][1],
               BoothMul(testData[i][0], testData[i][1]));
    
      return 0;
    }
    

    输出:

    a = 00000100b (4)
    b = 00000101b (5)
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (10)  - 0000000000010100b
    
            1111111111101100b
    (01)  + 0000000000101000b
    
            0000000000010100b
    (00)  no +/-
    
            0000000000010100b
    (00)  no +/-
    
            0000000000010100b
    (00)  no +/-
    
            0000000000010100b
    (00)  no +/-
    
    a * b = 0000000000010100b (20)
    4 * 5 = 20
    
    a = 00000100b (4)
    b = 11111011b (-5)
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (10)  - 1111111111101100b
    
            0000000000010100b
    (01)  + 1111111111011000b
    
            1111111111101100b
    (00)  no +/-
    
            1111111111101100b
    (00)  no +/-
    
            1111111111101100b
    (00)  no +/-
    
            1111111111101100b
    (00)  no +/-
    
    a * b = 1111111111101100b (-20)
    4 * -5 = -20
    
    a = 11111100b (-4)
    b = 00000101b (5)
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (10)  - 0000000000010100b
    
            1111111111101100b
    (11)  no +/-
    
            1111111111101100b
    (11)  no +/-
    
            1111111111101100b
    (11)  no +/-
    
            1111111111101100b
    (11)  no +/-
    
            1111111111101100b
    (11)  no +/-
    
    a * b = 1111111111101100b (-20)
    -4 * 5 = -20
    
    a = 11111100b (-4)
    b = 11111011b (-5)
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (00)  no +/-
    
            0000000000000000b
    (10)  - 1111111111101100b
    
            0000000000010100b
    (11)  no +/-
    
            0000000000010100b
    (11)  no +/-
    
            0000000000010100b
    (11)  no +/-
    
            0000000000010100b
    (11)  no +/-
    
            0000000000010100b
    (11)  no +/-
    
    a * b = 0000000000010100b (20)
    -4 * -5 = 20
    
    a = 00000101b (5)
    b = 00000100b (4)
    
            0000000000000000b
    (10)  - 0000000000000100b
    
            1111111111111100b
    (01)  + 0000000000001000b
    
            0000000000000100b
    (10)  - 0000000000010000b
    
            1111111111110100b
    (01)  + 0000000000100000b
    
            0000000000010100b
    (00)  no +/-
    
            0000000000010100b
    (00)  no +/-
    
            0000000000010100b
    (00)  no +/-
    
            0000000000010100b
    (00)  no +/-
    
    a * b = 0000000000010100b (20)
    5 * 4 = 20
    
    a = 00000101b (5)
    b = 11111100b (-4)
    
            0000000000000000b
    (10)  - 1111111111111100b
    
            0000000000000100b
    (01)  + 1111111111111000b
    
            1111111111111100b
    (10)  - 1111111111110000b
    
            0000000000001100b
    (01)  + 1111111111100000b
    
            1111111111101100b
    (00)  no +/-
    
            1111111111101100b
    (00)  no +/-
    
            1111111111101100b
    (00)  no +/-
    
            1111111111101100b
    (00)  no +/-
    
    a * b = 1111111111101100b (-20)
    5 * -4 = -20
    
    a = 11111011b (-5)
    b = 00000100b (4)
    
            0000000000000000b
    (10)  - 0000000000000100b
    
            1111111111111100b
    (11)  no +/-
    
            1111111111111100b
    (01)  + 0000000000010000b
    
            0000000000001100b
    (10)  - 0000000000100000b
    
            1111111111101100b
    (11)  no +/-
    
            1111111111101100b
    (11)  no +/-
    
            1111111111101100b
    (11)  no +/-
    
            1111111111101100b
    (11)  no +/-
    
    a * b = 1111111111101100b (-20)
    -5 * 4 = -20
    
    a = 11111011b (-5)
    b = 11111100b (-4)
    
            0000000000000000b
    (10)  - 1111111111111100b
    
            0000000000000100b
    (11)  no +/-
    
            0000000000000100b
    (01)  + 1111111111110000b
    
            1111111111110100b
    (10)  - 1111111111100000b
    
            0000000000010100b
    (11)  no +/-
    
            0000000000010100b
    (11)  no +/-
    
            0000000000010100b
    (11)  no +/-
    
            0000000000010100b
    (11)  no +/-
    
    a * b = 0000000000010100b (20)
    -5 * -4 = 20
    

    【讨论】:

      【解决方案3】:
      5*4 =20
      
      m=5,r=4,x=y=4
      
      m=0101 , r=0100 , -m=1011 ,x=y=4
      
      A=0101 0000 0
      S=1011 0000 0
      P=0000 0100 0
      
      1.  P=0000 0100 0       //last two bits are 00 so simply shift P
      
          P=0000 0010 0
      
      2.  P=0000 0010 0      //last two bits are 00 so simply shift P
      
          P=0000 0001 0
      
      3.  P=0000 0001 0      //last two bits are 10 so perform  P = P+S
      
          P=1011 0001 0
      
          P=1101 1000 1     // after shifting P
      
      4.  P=1101 1000 1     //last two bits are 01 so perform P = P+A
      
          P=0010 1000 1
      
          P=0001 0100 0       // after shifting P
      
      
      5. now remove LSB 
      
         the product is P=00010100(20)
      

      【讨论】:

        【解决方案4】:

        我认为x 应该是2 而不是3——因为311,只有两位长。

        【讨论】:

          【解决方案5】:

          下面是布斯算法的实现,其流程图在所谓的“计算机组织与架构,第八版 - William Stallings”的第 9 章中说明。 该程序将两个以 4 位表示的数字相乘。 当 VERBOSE == 1 时,程序显示算法的不同步骤。 PS:程序把数字当作字符串来操作。

          祝你好运!

          #include <stdio.h>
          #define WORD 4
          #define VERBOSE 1 //0
          
          /*
           * CSC 2304 - Al Akhawayn University
           * Implementation of the Booth's Algorithm.
           */
          
          void twosComplementAddition(char[], char[]);
          void rightShift(char[], char);
          void addition(char[], char[]);
          
          char* twosComplementMultiplication(char M[], char Q[]) {
              char C;
              char *A = (char*) malloc(sizeof(char)*(2 * WORD + 1));
              char processedQ[WORD+ 1];
              char Q0, Q_1 = '0';
              int i, j;
              strcpy(A, "0000");
              if (VERBOSE) {
                  printf("\n  A   |   Q   |   M   |");
                  printf("\n  %s  |   %s  |   %s  |   Initial", A, Q, M);
                  printf("\n-------------------------------------------------------------");
              }
              for (i = 0, j = 1; i < WORD; i++, j++) {
                  Q0 = Q[WORD - 1];
                  if (VERBOSE) {
                      printf("\n  %s  |   %s  |   %s  |   Cycle %d", A, Q, M, j);
                  }
                  if (Q0 == '0' && Q_1 == '1') {
                      addition(A, M);
                      if (VERBOSE) {
                          printf("\n  %s  |   %s  |   %s  |   Addition", A, Q, M);
                      }
                  } else {
                      if (Q0 == '1' && Q_1 == '0') {
                          twosComplementAddition(A, M);
                          if (VERBOSE) {
                              printf("\n  %s  |   %s  |   %s  |   Two's Complement", A, Q, M);
                          }
                      }
                  }
                  Q_1 = Q[WORD - 1];
                  rightShift(Q, A[WORD - 1]);
                  rightShift(A, A[0]);
                  if (VERBOSE) {
                      printf("\n  %s  |   %s  |   %s  |   Right Shift", A, Q, M);
                      getch();
                  }
                  printf("\n-------------------------------------------------------------");
              }
              strcat(A, Q);
              return A;
          }
          void rightShift(char reg[], char bit) {
              int i;
              for (i = WORD - 1; i > 0; i--) {
                  reg[i] = reg[i - 1];
              }
              reg[0] = bit;
          }
          
          void addition(char A[], char M[]) {
              int i;
              char c = '0';
              for (i = WORD - 1; i >= 0; i--) {
                  if (A[i] == '0' && M[i] == '0') {
                      A[i] = c;
                      c = '0';
                  } else {
                      if ((A[i] == '1' && M[i] == '0') || (A[i] == '0' && M[i] == '1')) {
                          if (c == '0') {
                              A[i] = '1';
                          } else {
                              A[i] = '0';
                          }
                      } else {
                          if (A[i] == '1' && M[i] == '1') {
                              A[i] = c;
                              c = '1';
                          }
                      }
                  }
              }
          }
          void twosComplementAddition(char A[], char M[]) {
              int i;
              char temp[WORD + 1];
              for (i = 0; i < WORD; i++) {
                  if (M[i] == '0') {
                      temp[i] = '1';
                  } else {
                      temp[i] = '0';
                  }
              }
              temp[WORD] = '\0';
              addition(temp, "0001");
              addition(A, temp);
          }
          
          int main() {
              char QQ[WORD + 1];
              char M[WORD + 1];
              char Q[WORD + 1];
              char *result;
          
              printf("\nBooth's Algorithm");
              printf("\n*****************");
              printf("\nEnter M: ");
              scanf("%s", M);
              printf("\nEnter Q: ");
              scanf("%s", Q);
              strcpy(QQ, Q);
              result = twosComplementMultiplication(M, Q);
              printf("\n%s * %s = %s", M, QQ, result);
          
              printf("\n");
              return 0;
          
          }
          

          【讨论】:

            【解决方案6】:

            始终建议使用 Booth 算法将 X+1 位 用于 X 位 数乘法。额外的一位用于处理符号值。这是您的方法的一个问题。没有它,像 101(十进制:5)这样的数字充当负 1。

            【讨论】:

              【解决方案7】:

              布斯算法用于有符号数的乘法,其中一个应该有符号,或者两个都应该有符号。 我们不能对两个无符号数应用布斯算法。

              【讨论】:

                【解决方案8】:

                布斯算法用于有符号数的乘法,其中一个应该有符号,或者两个都应该有符号。 我们也可以对两个无符号数应用布斯算法,但我们必须检查这些数字是否在给定范围内。 例如,如果我们采用 4 位数字,例如 2*3 是可能的。如果我们做 9*4 或 9*-4 或 -9*-4 是不可能的,因为 9 或 -9 不在 4 位数字的范围内,所以booth算法乘法是不可能的。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-04-14
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-07-25
                  • 1970-01-01
                  • 2011-05-26
                  相关资源
                  最近更新 更多