【问题标题】:How can I perform multiplication without the '*' operator?如何在没有“*”运算符的情况下执行乘法?
【发布时间】:2019-12-15 16:08:46
【问题描述】:

我在学习 C 时只是在学习一些基本的东西。我遇到了一个问题,即不使用 * 运算符将数字乘以 7。基本上是这样的

      (x << 3) - x;

现在我知道了基本的位操作操作,但是我不知道如何在不使用 * 运算符的情况下将一个数字乘以任何其他奇数?有没有通用的算法?

【问题讨论】:

  • 那是 (8*x)-x 或 IOW 7x
  • 请注意,大多数编译器已经优化了这样的事情。即,将 15*x 变成 ((x
  • 代数 :) - (x
  • 只需使用* 运算符;这就是它的用途。这几乎是this question 的副本。请注意,(x&lt;&lt;3) - x 可能会溢出 x 的某些值,而更简单、更清晰的 x * 7 不会溢出。
  • 相关Java only在此重复。

标签: java c++ c bit-manipulation


【解决方案1】:

想想你如何用铅笔和纸做十进制乘法:

  12
x 26
----
  72
 24
----
 312

乘法在二进制中是什么样子的?

   0111
x  0101
-------
   0111
  0000
 0111
-------
 100011

注意到什么了吗?与十进制乘法不同,当以二进制乘法时,您需要记住“时间表”,在将其写入列表加数之前,您总是将其中一项乘以 0 或 1。不需要时间表。如果第二项的数字是 1,则添加第一项。如果它是0,你不知道。还要注意加数是如何逐渐向左移动的。

如果您不确定这一点,请在纸上做一些二进制乘法。完成后,将结果转换回十进制,看看它是否正确。在你完成了一些之后,我想你会明白如何使用移位和加法来实现二进制乘法。

【讨论】:

    【解决方案2】:

    每个人都忽略了显而易见的事情。不涉及乘法:

    10^(log10(A) + log10(B))
    

    【讨论】:

    • C 中的哪个是exp(log(A) + log(B))
    • 我想你是在讽刺,但如果你不是,你有没有看过 logn 的源代码?
    • 我认为它更像是一堂历史课,而不是讽刺。今天的人们往往会忘记我们在拥有计算机甚至电子计算器之前所做的事情。我见过许多工程师和程序,他们接受了“魔术盒”的结果,却不了解它是如何工作的。没有人可以知道一切,但我们应该尽可能多地了解。我知道计算日志的通用算法,但我承认我没有深入研究过它们。正如许多人指出的那样,它们涉及到二进制乘法的移位。不出所料,早期的 CPU 只能加移位。
    • 即使是许多现代 CPU(小型、低功耗的 CPU)也无法进行乘法或除法运算。既然可以在软件中轻松完成,为什么还要在上面浪费微码?
    • 旧计算尺实现!一定会喜欢阿波罗 13 号中 10 名工程师同时计算他们的计算尺的场景——多核处于起步阶段!
    【解决方案3】:

    问题说:

    不使用 * 运算符将数字乘以 7

    这不使用*

     number / (1 / 7) 
    

    编辑:
    这可以在 C 中编译并正常工作:

     int number,result;
     number = 8;
     result = number / (1. / 7);
     printf("result is %d\n",result);
    

    【讨论】:

    • 这个想法 +1,但它在 Java 中不起作用:java.lang.ArithmeticException: / by zero 因为 (1 / 7) 是通过整数除法完成的(解决方法很简单)
    • 实际上它在 c 中也不起作用!我敢肯定,如果你运行那条线,你会得到一个核心转储:)。
    • @Chris Dodd,AndreyT - 没错,FP 可以字节你。我的观点是想法,而不是实施。
    • @Loadmaster:您不需要显式转换即可将double 转换为int。这是 C 和 C++ 中的标准转换,因此不需要强制转换。人们可能使用显式强制转换的唯一原因是为了抑制一些烦人的编译器警告。
    • JAVA 版本:双重结果 = paramThird / ( 1. / (paramFirst / (1. / paramSecond))); System.out.println("结果:" + 结果);
    【解决方案4】:

    如果不溢出,整数左移乘以 2。接近后,只需酌情加减即可。

    【讨论】:

      【解决方案5】:
      int multiply(int multiplicand, int factor)
      {
          if (factor == 0) return 0;
      
          int product = multiplicand;
          for (int ii = 1; ii < abs(factor); ++ii) {
              product += multiplicand;
          }
      
          return factor >= 0 ? product : -product;
      }
      

      你想要没有* 的乘法,你明白了,伙计!

      【讨论】:

      • 哇,谢谢 dkantowitz。我不知道! +10 对你我的好人! (哦,问题中的 nothing 需要移位,但我相信你也意识到了这一点。)
      • -1。此代码已损坏,因为它不是将multiplicand 添加到运行总和(最初为0),而是将multiplicand 添加到自身,这导致multiplicand 乘以2^(abs(factor)-1)*sgn(factor) 而不是factor。跨度>
      【解决方案6】:

      很容易避免使用“*”运算符:

      mov eax, 1234h
      mov edx, 5678h
      imul edx
      

      看不到“*”。当然,如果你想深入了解它的精神,你也可以使用可信赖的老班次并添加算法:

      mult proc
      ; Multiplies eax by ebx and places result in edx:ecx
          xor ecx, ecx
          xor edx, edx
      mul1:
          test ebx, 1
          jz  mul2
          add ecx, eax
          adc edx, 0
      mul2:
          shr ebx, 1
          shl eax, 1
          test ebx, ebx
          jnz  mul1
      done:
          ret
      mult endp
      

      当然,在现代处理器中,所有 (?) 都有乘法指令,但在 PDP-11 还很新奇的时候,这样的代码才真正有用处。

      【讨论】:

      • 这不公平,问题被标记为cc++java ;)
      • @dreamlax:非常正确——如果有人从汇编代码中对算法进行逆向工程以在他们的 C、C++ 或 Java 作业中获得 A,我愿意相信他们可能获得了分数。 ..
      • 我的第一台家用电脑是 TRS-80,配备 1.7MHz Z80,我输入了很多这样的乘法例程。结果发现,最快的方法是根据需要进行尽可能多的 8x16 位乘法运算,然后将它们相加。
      • 一定要喜欢 x86 的 LEA 指令...转移并添加一条指令 :)
      • 即使是许多现代 CPU(小型、低功耗的 CPU)也无法进行乘法或除法运算。既然可以在软件中轻松完成,为什么还要在上面浪费微码?
      【解决方案7】:

      从数学上讲,乘法分布超过加法。本质上,这意味着:

      x * (a + b + c ...) = (x * a) + (x * b) + (x * c) ...

      任何实数(在您的情况下为7)都可以表示为一系列加法(例如8 + (-1),因为减法实际上只是错误的加法)。这允许您将任何单个乘法语句表示为等效的一系列乘法语句,它们将得出相同的结果:

      x * 7
      = x * (8 + (-1))
      = (x * 8) + (x * (-1))
      = (x * 8) - (x * 1)
      = (x * 8) - x
      

      bitwise shift 运算符本质上只是将一个数字乘以或除以 2 的幂。只要您的等式只处理这些值,就可以使用位移来替换所有出现的乘法运算符。

      (x * 8) - x = (x * 23) - x = (x

      类似的策略可以用于任何其他整数,无论​​是奇数还是偶数都没有区别。

      【讨论】:

        【解决方案8】:

        x*8-x = x*(8-1) = x*7

        【讨论】:

          【解决方案9】:

          任何数字,无论是奇数还是偶数,都可以表示为 2 的幂之和。例如,

               1   2   4   8
          ------------------
           1 = 1
           2 = 0 + 2
           3 = 1 + 2
           4 = 0 + 0 + 4
           5 = 1 + 0 + 4
           6 = 0 + 2 + 4
           7 = 1 + 2 + 4
           8 = 0 + 0 + 0 + 8
          11 = 1 + 2 + 0 + 8
          

          因此,您可以通过执行正确的移位和加法将 x 乘以任意数字。

           1x = x
           2x = 0 + x<<1
           3x = x + x<<1
           4x = 0 +  0   + x<<2
           5x = x +  0   + x<<2
          11x = x + x<<1 +   0  + x<<3
          

          【讨论】:

          • 有用!但是类似于 OP 的场景如何,例如通过移位和 减法 相乘?即 6x = (x
          • 我认为唯一的规则是避免使用* 运算符。
          • 另外,你的桌子有点偏,2x 是 (x
          • @dreamlax:被乘数中有 2 个连续的1s 的因子可以用相同数量的减法运算代替。对于超过 2 个连续的1s,减法使用的操作更少。
          【解决方案10】:

          归根结底,乘以一个正整数可以这样完成:

          int multiply(int a, int b) {
            int ret = 0;
            for (int i=0; i<b; i++) {
              ret += b;
            }
            return ret;
          }
          

          高效?几乎不。但这是正确的(考虑到整数等的限制)。

          因此,使用左移只是乘以 2 的捷径。但是,一旦达到 b 下的最高 2 次方,您只需将 a 添加必要的次数,所以:

          int multiply(int a, int b) {
            int ret = a;
            int mult = 1;
            while (mult <= b) {
              ret <<= 1;
              mult <<= 1;
            }
            while (mult < b) {
              ret += a;
            }
            return ret;
          }
          

          或类似的东西。

          换句话说,乘以 7。

          • 左移 2(乘以 4)。左移 3 为 8 即 >7;
          • 添加b 3次。

          【讨论】:

          • 在您的第一个示例中,您的意思是:ret += a;i &lt; a。你应该提到它在“等等”中假设非负整数。
          • 我不明白....我们添加 3 次是什么?就像数字是 7 乘以 7 一样,就像我写的那样,左移 3 减去 7,结果是 49。b 到底是什么?请原谅我缺乏知识。
          【解决方案11】:

          一天晚上,我发现自己非常无聊,于是把这个煮了:

          #include <iostream>
          
          typedef unsigned int uint32;
          
          uint32 add(uint32 a, uint32 b) {
              do {
                  uint32 s = a ^ b;
                  uint32 c = a & b;
                  a = s;
                  b = c << 1;
              } while (a & b)
              return (a | b)
          }
          
          uint32 mul(uint32 a, uint32 b) {
              uint32 total = 0;
              do {
                  uint32 s1 = a & (-(b & 1))
                  b >>= 1; a <<= 1;
                  total = add(s1, total)
              } while (b)
              return total;
          }
          
          int main(void) {
              using namespace std;
              uint32 a, b;
          
              cout << "Enter two numbers to be multiplied: ";
              cin >> a >> b;
          
              cout << "Total: " << mul(a,b) << endl;
              return 0;
          }
          

          上面的代码应该是不言自明的,因为我试图让它尽可能简单。它应该或多或少地以 CPU 执行这些操作的方式工作。我知道的唯一错误是 a 不允许大于 32,767 并且 b 不允许大到足以溢出 a (即不处理乘法溢出,所以 64-位结果是不可能的)。如果输入正确为reinterpret_cast&lt;&gt;,它甚至可以处理负数。

          【讨论】:

          • The code above should be quite self-explanatory相信我,它不是。
          【解决方案12】:

          O(log(b)) 方法

          public int multiply_optimal(int a, int b) {
          
              if (a == 0 || b == 0)
                  return 0;
              if (b == 1)
                  return a;
              if ((b & 1) == 0)
                  return multiply_optimal(a + a, b >> 1);
              else
                  return a + multiply_optimal(a + a, b >> 1);
          
          }
          

          递归代码的工作原理如下:
          基本情况:
          如果其中一个数字为 0,则产品为 0。
          如果 b=1,则产品 =a。

          如果 b 是偶数:
          ab 可以写成 2a(b/2)
          2a(b/2)=(a+a)(b/2)=(a+a)(b>>1) where'>>' java 算术右移运算符。

          如果 b 是奇数:
          ab 可以写成 a+a(b-1)
          a+a(b-1)=a+2a(b-1)/2=a+(a+a)(b-1)/2=a+(a+a)((b-1)>>1)
          因为 b 是奇数 (b-1)/2=b/2=b>>1
          所以 ab=a+(2a*(b>>1))
          注意:每个递归调用 b 减半 => O(log(b))

          【讨论】:

            【解决方案13】:
            unsigned int Multiply(unsigned int m1, unsigned int m2)
            {
                unsigned int numBits = sizeof(unsigned int) * 8; // Not part of the core algorithm
                unsigned int product = 0;
                unsigned int mask = 1;
                for(int i =0; i < numBits; ++i, mask = mask << 1)
                {
                    if(m1 & mask)
                    {
                        product += (m2 << i);
                    }
                }
                return product;
            }
            

            【讨论】:

            • 与其使用* 8,不如使用&lt;&lt; 3 :)
            【解决方案14】:

            @Wang,这是一个很好的概括。但这里有一个稍快的版本。但它假定没有溢出并且 a 是非负数。

            int mult(int a, int b){
                int p=1;
                int rv=0;
                for(int i=0; a >= p && i < 31; i++){
                    if(a & p){
                        rv += b;
                    }
                    p = p << 1;
                    b = b << 1;
                }
            
                return rv;
            }
            

            它最多会循环 1+log_2(a) 次。如果在 a > b 时交换 a 和 b,可能会更快。

            【讨论】:

              【解决方案15】:
              import java.math.BigInteger;
              
              public class MultiplyTest {
                  public static void main(String[] args) {
                      BigInteger bigInt1 = new BigInteger("5");
                      BigInteger bigInt2 = new BigInteger("8");
                      System.out.println(bigInt1.multiply(bigInt2));
                  }
              }
              

              【讨论】:

                【解决方案16】:

                当被乘数为负时,移位和加法不起作用(即使使用符号扩展)。有符号乘法必须使用Booth encoding

                LSB开始,从0到1的变化是-1;从 1 到 0 的变化为 1,否则为 0。在 LSB 下方还有一个隐含的额外位 0。

                例如,数字 5 (0101) 将被编码为:(1)(-1)(1)(-1)。您可以验证这是正确的:

                5 = 2^3 - 2^2 + 2 -1

                此算法也适用于 2 的补码形式的负数:

                -1 在 4 位 2 的补码中是 1111。使用 Booth 算法:(1)(0)(0)(0)(-1),其中最左边的位 1 没有空间,所以我们得到: (0)(0)(0)(-1) 即 -1。

                /* Multiply two signed integers using the Booth algorithm */
                int booth(int x, int y)
                {
                    int prev_bit = 0;
                    int result = 0;
                
                    while (x != 0) {
                        int current_bit = x & 0x1;
                        if (prev_bit & ~current_bit) {
                            result += y;
                        } else if (~prev_bit & current_bit) {
                            result -= y;
                        }
                
                        prev_bit = current_bit;
                
                        x = static_cast<unsigned>(x) >> 1;
                        y <<= 1;
                    }
                
                    if (prev_bit)
                        result += y;
                
                    return result;
                }
                

                上面的代码不检查溢出。下面是一个稍微修改的版本,将两个 16 位数字相乘并返回一个 32 位数字,因此它永远不会溢出:

                /* Multiply two 16-bit signed integers using the Booth algorithm */
                /* Returns a 32-bit signed integer */
                int32_t booth(int16_t x, int16_t y)
                {
                    int16_t prev_bit = 0;
                    int16_t sign_bit = (x >> 16) & 0x1;
                    int32_t result = 0;
                    int32_t y1 = static_cast<int32_t>(y);
                
                    while (x != 0) {
                        int16_t current_bit = x & 0x1;
                        if (prev_bit & ~current_bit) {
                            result += y1;
                        } else if (~prev_bit & current_bit) {
                            result -= y1;
                        }
                
                        prev_bit = current_bit;
                
                        x = static_cast<uint16_t>(x) >> 1;
                        y1 <<= 1;
                    }
                
                    if (prev_bit & ~sign_bit)
                        result += y1;
                
                    return result;
                }
                

                【讨论】:

                  【解决方案17】:
                  unsigned int Multiply( unsigned int a, unsigned int b )
                  {
                      int ret = 0;
                      // For each bit in b
                      for (int i=0; i<32; i++) {
                  
                          // If that bit is not equal to zero
                          if (( b & (1 << i)) != 0) {
                  
                              // Add it to our return value
                              ret += a << i;
                          }
                      }
                      return ret;
                  }
                  

                  我避开了符号位,因为它不是帖子的主题。这是Wayne Conrad 基本上所说的实现。 Here is another problem is you want to try more low level math operations. Project Euler 很酷!

                  【讨论】:

                    【解决方案18】:

                    如果可以使用日志功能:

                    public static final long multiplyUsingShift(int a, int b) {
                        int absA = Math.abs(a);
                        int absB = Math.abs(b);
                    
                        //Find the 2^b which is larger than "a" which turns out to be the 
                        //ceiling of (Log base 2 of b) == numbers of digits to shift
                        double logBase2 = Math.log(absB) / Math.log(2);
                        long bits = (long)Math.ceil(logBase2);
                    
                        //Get the value of 2^bits
                        long biggerInteger = (int)Math.pow(2, bits);
                    
                        //Find the difference of the bigger integer and "b"
                        long difference = biggerInteger - absB;
                    
                        //Shift "bits" places to the left
                        long result = absA<<bits;
                    
                        //Subtract the "difference" "a" times
                        int diffLoop = Math.abs(a);
                        while (diffLoop>0) {
                            result -= difference;
                            diffLoop--;
                        }
                    
                        return (a>0&&b>0 || a<0&&b<0)?result:-result;
                    }
                    

                    如果不能使用日志功能:

                    public static final long multiplyUsingShift(int a, int b) {
                        int absA = Math.abs(a);
                        int absB = Math.abs(b);
                    
                        //Get the number of bits for a 2^(b+1) larger number
                        int bits = 0;
                        int bitInteger = absB;
                        while (bitInteger>0) {
                            bitInteger /= 2;
                            bits++;
                        }
                    
                        //Get the value of 2^bit
                        long biggerInteger = (int)Math.pow(2, bits);
                    
                        //Find the difference of the bigger integer and "b"
                        long difference = biggerInteger - absB;
                    
                        //Shift "bits" places to the left
                        long result = absA<<bits;
                    
                        //Subtract the "difference" "a" times
                        int diffLoop = absA;
                        while (diffLoop>0) {
                            result -= difference;
                            diffLoop--;
                        }
                    
                        return (a>0&&b>0 || a<0&&b<0)?result:-result;
                    }
                    

                    我发现这样更有效率:

                    public static final long multiplyUsingShift(int a, int b) {
                        int absA = Math.abs(a);
                        int absB = Math.abs(b);
                    
                        long result = 0L;
                        while (absA>0) {
                            if ((absA&1)>0) result += absB; //Is odd
                            absA >>= 1;
                            absB <<= 1;
                        }
                    
                        return (a>0&&b>0 || a<0&&b<0)?result:-result;
                    }
                    

                    还有另一种方式。

                    public static final long multiplyUsingLogs(int a, int b) {
                        int absA = Math.abs(a);
                        int absB = Math.abs(b);
                        long result = Math.round(Math.pow(10, (Math.log10(absA)+Math.log10(absB))));
                        return (a>0&&b>0 || a<0&&b<0)?result:-result;
                    }
                    

                    【讨论】:

                      【解决方案19】:

                      在 C# 中:

                      private static string Multi(int a, int b)
                      {
                          if (a == 0 || b == 0)
                              return "0";
                      
                          bool isnegative = false;
                      
                          if (a < 0 || b < 0)
                          {
                              isnegative = true;
                      
                              a = Math.Abs(a);
                      
                              b = Math.Abs(b);
                          }
                      
                          int sum = 0;
                      
                          if (a > b)
                          {
                              for (int i = 1; i <= b; i++)
                              {
                                  sum += a;
                              }
                          }
                          else
                          {
                              for (int i = 1; i <= a; i++)
                              {
                                  sum += b;
                              }
                          }
                      
                          if (isnegative == true)
                              return "-" + sum.ToString();
                          else
                              return sum.ToString();
                      }
                      

                      【讨论】:

                        【解决方案20】:

                        JAVA:
                        考虑到每个数字都可以分成二的幂:

                        1 = 2 ^ 0
                        2 = 2 ^ 1
                        3 = 2 ^ 1 + 2 ^ 0
                        ...
                        

                        我们想在哪里得到 x:
                        x = n * m

                        所以我们可以通过以下步骤来实现:

                        1.   while m is greater or equal to 2^pow:
                             1.1  get the biggest number pow, such as 2^pow is lower or equal to m
                             1.2  multiply n*2^pow and decrease m to m-2^pow
                        2.   sum the results
                        

                        使用递归的示例实现:

                        long multiply(int n, int m) {
                            int pow = 0;
                            while (m >= (1 << ++pow)) ;
                            pow--;
                            if (m == 1 << pow) return (n << pow);
                            return (n << pow) + multiply(n, m - (1 << pow));
                        }
                        

                        我在上次工作面试中得到了这个问题,这个答案被接受了。

                        编辑:正数的解决方案

                        【讨论】:

                          【解决方案21】:

                          这是最简单的 C99/C11 正数解决方案:

                          unsigned multiply(unsigned x, unsigned y) { return sizeof(char[x][y]); }
                          

                          【讨论】:

                            【解决方案22】:

                            另一个跳出框框思考的答案:

                            BigDecimal a = new BigDecimal(123);
                            BigDecimal b = new BigDecimal(2);
                            BigDecimal result = a.multiply(b);
                            System.out.println(result.intValue());
                            

                            【讨论】:

                            • 这在“C”中是如何工作的?我认为您可能误读了原始问题。
                            • @S.Robins:例如使用 libgmp。 mpz_mul (mpz_t rop, mpz_t op1, mpz_t op2)
                            【解决方案23】:
                            public static int multiply(int a, int b) 
                            {
                                int temp = 0;
                                if (b == 0) return 0;
                                for (int ii = 0; ii < abs(b); ++ii) {
                                    temp = temp + a;
                                }
                            
                                return b >= 0 ? temp : -temp;
                            }
                            
                            public static int abs(int val) {
                            
                                return val>=0 ? val : -val;
                            }
                            

                            【讨论】:

                              【解决方案24】:
                              public static void main(String[] args) {
                                  System.out.print("Enter value of A -> ");
                                  Scanner s=new Scanner(System.in);
                                  double j=s.nextInt();
                                  System.out.print("Enter value of B -> ");
                                  Scanner p=new Scanner(System.in);
                                  double k=p.nextInt();
                                  double m=(1/k);
                                  double l=(j/m);
                                  System.out.print("Multiplication of A & B=> "+l);
                              }
                              

                              【讨论】:

                              【解决方案25】:
                              package com.amit.string;
                              
                              // Here I am passing two values, 7 and 3 and method getResult() will
                              // return 21 without use of any operator except the increment operator, ++.
                              //
                              public class MultiplyTwoNumber {
                              
                                  public static void main(String[] args) {
                                      int a = 7;
                                      int b = 3;
                                      System.out.println(new MultiplyTwoNumber().getResult(a, b));
                                  }
                              
                                  public int getResult(int i, int j) {
                                      int result = 0;
                              
                                      // Check for loop logic it is key thing it will go 21 times
                                      for (int k = 0; k < i; k++) {
                                          for (int p = 0; p < j; p++) {
                                              result++;
                                          }
                                      }
                                      return result;
                                  }
                              }
                              

                              【讨论】:

                              • 不要只发布一段代码,请解释为什么这段代码可以解决所提出的问题。没有解释,这不是答案。
                              • 请注意代码的缩进。如果发布的代码难以阅读,那么它的帮助就较小。
                              【解决方案26】:

                              循环播放。运行一个循环七次并通过你乘以七的数字进行迭代。

                              伪代码:

                              total = 0
                              multiply = 34
                              
                              loop while i < 7
                              
                                  total = total + multiply
                              
                              endloop
                              

                              【讨论】:

                                【解决方案27】:

                                让 N 是我们想要乘以 7 的数字。

                                N x 7 = N + N + N + N + N + N + N
                                N x 7 = N + N + N + N + N + N + N + (N - N)
                                N x 7 = (N + N + N + N + N + N + N + N) - N
                                N x 7 = 8xN - N
                                

                                我们知道,任何数左移一位乘以 2。因此,任何数乘以 8 相当于将其右移 3 位

                                N x 7 = (N << 3) - N 
                                

                                我在这里找到了这个描述 http://www.techcrashcourse.com/2016/02/c-program-to-multiply-number-by-7-bitwise-operator.html

                                希望对您有所帮助。

                                【讨论】:

                                  【解决方案28】:

                                  通过使用递归,我们可以将两个整数与给定的约束相乘。

                                  要将 x 和 y 相乘,递归地加上 x y 次。

                                       #include<stdio.h>
                                       /* function to multiply two numbers x and y*/
                                       int multiply(int x, int y)
                                       {
                                          /* multiplied with anything gives */
                                          if(y == 0)
                                          return 0;
                                  
                                          /* Add x one by one */
                                          if(y > 0 )
                                          return (x + multiply(x, y-1));
                                  
                                          /* the case where y is negative */
                                          if(y < 0 )
                                          return -multiply(x, -y);
                                       }
                                  
                                       int main()
                                       {
                                         printf("\n %d", multiply(5, -11));
                                         getchar();
                                         return 0;
                                       }
                                  

                                  【讨论】:

                                    【解决方案29】:

                                    正数的 JavaScript 方法

                                    function recursiveMultiply(num1, num2){
                                        const bigger = num1 > num2 ? num1 : num2; 
                                        const smaller = num1 <= num2 ? num1 : num2; 
                                        const indexIncrement = 1;
                                        const resultIncrement = bigger;
                                    
                                        return recursiveMultiplyHelper(bigger, smaller, 0, indexIncrement, resultIncrement)
                                    }
                                    
                                    function recursiveMultiplyHelper(num1, num2, index, indexIncrement, resultIncrement){
                                        let result = 0;
                                        if (index === num2){
                                            return result;
                                        } 
                                    
                                        if ((index+indexIncrement+indexIncrement) >= num2){
                                            indexIncrement = 1;
                                            resultIncrement = num1;
                                        } else{
                                            indexIncrement += indexIncrement;
                                            resultIncrement += resultIncrement;
                                        }
                                    
                                        result = recursiveMultiplyHelper(num1, num2, (index+indexIncrement), indexIncrement, resultIncrement);
                                        result += resultIncrement;
                                        console.log(num1, num2, index, result);
                                    
                                        return result;
                                    }
                                    

                                    【讨论】:

                                      【解决方案30】:

                                      想想我们使用的正常乘法方法

                                               1101 x        =>13
                                               0101          =>5
                                      ---------------------
                                               1101
                                              0000
                                             1101
                                            0000
                                      ===================        
                                            1000001 .        => 65
                                      

                                      在代码中写上相同的内容

                                      #include<stdio.h>
                                      
                                      int multiply(int a, int b){
                                          int res = 0,count =0;
                                          while(b>0) {
                                              if(b & 0x1)
                                                  res = res + (a << count);
                                              b = b>>1;
                                              count++;
                                          }
                                          return res;
                                      }
                                      int main() {
                                          printf("Sum of x+y = %d", multiply(5,10));
                                          return 0;
                                      }
                                      

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2018-12-06
                                        • 2018-08-19
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多