【问题标题】:Integer multiplication without * [closed]没有*的整数乘法[关闭]
【发布时间】:2013-02-13 14:11:34
【问题描述】:

我在其中一个网站上看到一个 C 语言面试问题,要求你编写一个函数,该函数获取 2 个整数、num 和 times,并在不使用 * 运算符的情况下将它们相乘,这意味着主要使用左移和右移。我想出了一个可行的答案(除非有人发现了一个错误),但是有没有人有更好的方法在更好的时间或内存消耗中解决它?

这是我写的:

#include <stdio.h>

int multiply_with_shift (int num, int times)
{
   int cnt=0;
   int org_times=times;
   if((num & times)==0)
       return 0;
   else
   {
   while(times >1)   
   {
      times=  times >> 1;
      cnt++;
   }
   int val= 1;
      val= val <<cnt;              
   int sub= org_times-val;         
   int res= num << cnt;            
   for( int i=0 ; i < sub; i++)    
   {
      res+=num;
   }
      return res;
   }
}


void main()
{
    int tmp;
    tmp=multiply_with_shift(5,15);
    printf(" the answer is : %d \n", tmp);
    printf("\n");
}

?

【问题讨论】:

  • 在这里可能会得到更好的答案:codereview.stackexchange.com
  • 我同意 fire.eagle。顺便说一句,这 -> if((num &amp; times)==0) 应该是 if((num &amp;&amp; times)==0)
  • @BinyaminSharet 不,应该是if ((num | times) == 0)
  • @H2CO3 - 我认为两者都可以(虽然你的更漂亮:))
  • 这是重复的问题:stackoverflow.com/questions/4456442/…

标签: c


【解决方案1】:

这是一个更简洁且无错误(我相信)的实现,它甚至不会调用未定义的行为:

unsigned mul(unsigned a, unsigned b)
{
    unsigned acc = 0;
    while (b) {
        if (b & 1) acc += a;
        b >>= 1;
        a <<= 1;
    }
    return acc;
}

您的代码有几个缺陷:

  1. 可读性、长度等...
  2. if ((num &amp; times) == 0) return 0; -> 对于在其二进制表示中不共享至少一个 2 的公共幂的数字,这将返回 0,即。 e. 4 * 8 = 0.
  3. 符号位的移位在 C 中是未定义的行为 - 您需要使用无符号整数来完成此任务。

【讨论】:

  • &lt;comments removed&gt; 此答案下的 cmets 已过时,或纯噪声,随后已被删除。请保持 cmets 具有建设性、专业性和主题性。
  • @TimPost OneManCrew 指责我做了一些我没有做过的事情。这是不公平的。
  • @H2CO3 我真的很喜欢你的回答,找不到错误,它处理各种整数,例如 2^n 和零。你知道如何处理有符号整数吗?
  • @KBE MatsPetersson 的解决方案也处理有符号整数(但您也可以对 a &lt; 0b &lt; 0 进行异或运算)。
【解决方案2】:

如果你想要一个有符号整数变体,这会起作用:

int mul(int a, int b)
{
    sign = (a ^ b) >> (sizeof(a) * CHAR_BIT - 1);
    if (a > 0)
        a = -a;
    if (b > 0)
        b = -b;
    int acc = 0;
    while (b) {
        if (b & 1) acc += a;
        b >>= 1;
        a <<= 1;
    }
    if (sign) acc = -acc;
    return acc;
}

[感谢 H2CO3 在另一篇文章中对大部分算法的实现]

【讨论】:

  • 那它需要返回int,对吧? :)
  • 是的,典型的复制粘贴错误。
  • 这不起作用。 a &amp;= ~SIGN 不是在 2 的补码系统上取绝对值的正确方法。
  • 当然不是。你能说我上次做这种事情已经有一段时间了吗? ;)
  • @MatsPetersson 我相信 XOR-ing a &gt;&gt; (sizeof(a) * CHAR_BIT - 1)b &gt;&gt; (sizeof(b) * CHAR_BIT - 1) 会很好。
猜你喜欢
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多