两个数字相乘

时间:2019-12-05 12:44:07

标签: c multiplication

我分配了一个函数,该函数将2个整数相乘并且不使用*或'-'。我只能使用'+''/'和'%'。

我注意到很多人都在使用换档方法,但是我不能不使用它,因为我们还没有学到它。

在没有1 while循环的情况下,我可以做的很多事情就是,窍门应该是在n log n或log n运行时效率上。

没有列出任何数组,尽管我仍然看不到任何使用它们的方法。

有什么可能的方法吗?

5 个答案:

答案 0 :(得分:5)

此算法为O(nlogn)。分而治之。

double Multiply(int n, double x) {
    if (n == 0) 
        return 0.0;
    if (n == 1)
        return x;
    double a = Multiply(n/2, x);
    if ((n%2) == 1)
        return x + a + a;
    return a + a;
}

注意:该代码尚未经过测试。我无法在iPad上编译C代码。

答案 1 :(得分:4)

根据Ian Abbot的评论,此处 是实现目标的一种<嬉皮士方式:

double Multiply(int n, double x) {
    if (n == 0) return 0.0;
    else return x / (1.0 / n);
}

或者,如果您想要更简洁的单线:

double Multiply(int n, double x) { return n ? x / (1.0 / n) : 0.0; }

对Ian的“答案”所做的一项更改(但恕我直言,这是一项重要更改)是因为int参数被检查为零,因为这更加可靠比尝试测试double(或float)的精确度为 零。

注意:原始问题指定数字为“整数和双精度”,因此我给出了相应答案。

答案 2 :(得分:3)

这是另一个快速且肮脏的解决方案,没有递归性,符合OP的要求:

int Multiply(int a, int b)
{
  int result = 0;
  while (b > 0)
  {
    if (b % 2 != 0)
      result += a;

    a += a;
    b /= 2;
  }
  return result;
}

与chmike的答案中的算法基本相同。

我并不担心复杂性,但是看起来很像O(log n)。

b绝对不能与负值一起使用,我将其保留为练习。

答案 3 :(得分:2)

只是为了扩展Jabberwocky的答案(OP应该完全接受),这里有几种处理负数的方法。

如果需要获得正确的结果符号,则第一种方法会在主循环之前使用-作弊:

int Multiply(int a, int b)
{
  int result = 0;
  if (b < 0)
    a = -a; /* Cheat! But at least its a unary operation. */
  while (b != 0)
  {
    if (b % 2 != 0)
      result += a;

    a += a;
    b /= 2;
  }
  return result;
}

第二种方法利用unsigned int进行2的补码运算。从技术上讲,这存在一个小问题,因为可以根据C标准规则将正确的否定结果替换为实现定义的结果。无论如何,对于大多数以2的补码表示有符号整数的实现来说,这都不是问题。

int Multiply(int a_, int b_)
{
  unsigned int a = a_;
  unsigned int b = b_;
  unsigned int result = 0;
  while (b != 0)
  {
    if (b % 2 != 0)
      result += a;

    a += a;
    b /= 2;
  }
  // N.B. negative result might be replaced with implementation-defined result!
  return (int)result;
}

此外:忽略有符号整数的处理,这种乘法方法也称为Russian peasant method

答案 4 :(得分:1)

这是使用移位和加法的另一种方法。它与其他一些答案有很多共同点,但是在可能的地方使用按位运算,并且对负数的处理略有不同(它还避免了Ian Abbot承认的“一元负”可能是“作弊”):

int mult(int a, int b)
{
    int answer = 0;
    int minus = 0;
    if (a < 0) {
        minus ^= 1;
        a ^= -1; ++a; // Negate (without using *) - assuming 2s complement representation ...
    }
    if (b < 0) {
        minus ^= 1;
        b ^= -1; ++b; // ... where "-x" is the BIT INVERSE of "x" PLUS ONE
    }
    while (a) {
        if (a & 1) answer += b; // If the nth bit of "a" is set we add "b << n"
        b <<= 1; // But shift up (multiply by 2)
        a >>= 1; // Bit shift down (divide by 2)
    }
    if (minus) { // ONE (and only ONE) number was negative ...
        answer ^= -1; ++answer; // ... so we negate our answer!
    }
    return answer;
}

这将适用于负数(一个或两个),但不能处理整数溢出(但是,本机z = x * y也不会这样做)。

请随时要求进一步的澄清和/或解释。