如何在没有'*'运算符的情况下执行乘法运算?

Rac*_*ace 45 c c++ java bit-manipulation

当我正在学习C时,我只是经历了一些基本的东西.我遇到了一个问题,即在不使用*运算符的情况下将数字乘以7.基本上就是这样的

      (x << 3) - x;
Run Code Online (Sandbox Code Playgroud)

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

Way*_*rad 59

想想你如何使用铅笔和纸张乘以十进制:

  12
x 26
----
  72
 24
----
 312
Run Code Online (Sandbox Code Playgroud)

乘法在二进制中看起来像什么?

   0111
x  0101
-------
   0111
  0000
 0111
-------
 100011
Run Code Online (Sandbox Code Playgroud)

注意什么?与十进制中的乘法不同,在需要记忆"时间表"时,当乘以二进制时,您总是将其中一个项乘以0或1,然后再将其写入列表加数.没有时间表需要.如果第二项的数字为1,则在第一项中添加.如果是0,则不然.还要注意加数是如何逐渐向左移动的.

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


Jim*_*m C 25

每个人都忽略了明显的.不涉及乘法:

10^(log10(A) + log10(B))
Run Code Online (Sandbox Code Playgroud)

  • 我把它看作是历史课,然后是讽刺的.今天的人们往往会忘记我们在拥有计算机甚至电子计算器之前做过的事情.我见过许多工程师和程序,他们接受"魔术盒"的结果而不了解它是如何工作的.没有人能够知道一切,但我们应该尽可能多地了解.我知道计算日志的通用算法,但我承认我没有深入研究它们.正如许多人所指出的那样,它们涉及的是二元乘法.不出意外,早期的CPUS只能添加和转移. (7认同)
  • 我想你是在讽刺,但如果你不是,你有没有看过logn的源代码? (3认同)
  • 在C中哪个是`exp(log(A)+ log(B))`. (2认同)
  • 旧的幻灯片规则实现!一定要喜欢Apollo 13中的场景,10位工程师同时在他们的幻灯片规则上进行计算 - 多核处于起步阶段! (2认同)

Car*_*rez 20

问题是:

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

这不使用*:

 number / (1 / 7) 
Run Code Online (Sandbox Code Playgroud)

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

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


Ign*_*ams 19

左移整数乘以2,前提是它不会溢出.一旦你接近,只需加上或减去.


小智 17

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;
}
Run Code Online (Sandbox Code Playgroud)

你想要乘法*,你得到它,朋友!

  • -1.这段代码打破了,因为它不是将"multiplicand"添加到运行总和(最初为0),而是将"multiplicand"添加到自身,这导致"multiplicand"乘以"2 ^(abs(factor)-1)*sgn(factor)`而不是`factor`. (8认同)

Jer*_*fin 12

避免'*'运算符很容易:

mov eax, 1234h
mov edx, 5678h
imul edx
Run Code Online (Sandbox Code Playgroud)

看不到'*'.当然,如果你想了解它的精神,你也可以使用可靠的旧班次和添加算法:

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
Run Code Online (Sandbox Code Playgroud)

当然,对于现代处理器,所有(?)都有乘法指令,但是当PDP-11闪亮而且新的时候,像这样的代码真正使用了.

  • @dreamlax:非常正确 - 如果有人从汇编代码中反转工程师的算法来获得他们的C,C++或Java作业的A,我愿意相信他们可能获得了成绩...... (10认同)
  • 这不公平,问题是标记为`c`,`c ++`和`java`;) (6认同)
  • 即使是许多现代CPU(小型,低功率CPU)也无法倍增或分裂.当它可以在软件中轻松完成时,为什么要浪费微码呢? (2认同)

gol*_*udo 10

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

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
Run Code Online (Sandbox Code Playgroud)

按位移操作本质上只是乘以或除以一个数由2的幂只要你的方程只处理这样的值,位可以被用来代替乘法运算符的所有移位发生.

(x*8) - x =(x*2 3) - x =(x << 3) - x

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


Igo*_*aka 8

It is the same as x*8-x = x*(8-1) = x*7


ben*_*ado 7

任何数字,奇数或偶数,可以表示为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
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过执行正确的移位和添加来将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
Run Code Online (Sandbox Code Playgroud)


cle*_*tus 5

When it comes down to it, multiplication by a positive integer can be done like this:

int multiply(int a, int b) {
  int ret = 0;
  for (int i=0; i<b; i++) {
    ret += b;
  }
  return ret;
}
Run Code Online (Sandbox Code Playgroud)

Efficient? Hardly. But it's correct (factoring in limits on ints and so forth).

So using a left-shift is just a shortcut for multiplying by 2. But once you get to the highest power-of-2 under b you just add a the necessary number of times, so:

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;
}
Run Code Online (Sandbox Code Playgroud)

or something close to that.

To put it another way, to multiply by 7.

  • Left shift by 2 (times 4). Left shift 3 is 8 which is >7;
  • Add b 3 times.

  • 在你的第一个例子中,你要么意思是:`ret + = a;`或`i <a`.你应该提到它假定"等等"中的非负数整数. (4认同)