代码之家  ›  专栏  ›  技术社区  ›  user3297557

2的乘除和乘法

  •  4
  • user3297557  · 技术社区  · 10 年前

    我在一篇论文中读到,一个数除以2的幂是一个微不足道的过程。 我在网上找了很多解释,但没有找到。 有人能用简单的语言解释一下这实际上意味着什么吗。

    4 回复  |  直到 6 年前
        1
  •  6
  •   Peter Cordes    6 年前

    从位操作的角度来看,这是微不足道的。乘2等于左移1位,除法等于右移。类似地,乘和除2的任何幂都是同样的小事。

    int a = 123;           // or in binary format: a = 0b01111011;
    
    assert (a * 2) == (a << 1);   // 2 = 2^1, (a << 1) = 11110110
    assert (a / 2) == (a >> 1);   // 2 = 2^1, (a >> 1) = 00111101
    
    assert (a * 8) == (a << 3);   // 8 = 2^3, (a << 3) = 1111011000
    assert (a / 8) == (a >> 3);   // 8 = 2^3, (a >> 3) = 0000001111
    

    还要注意 a*2 = a+a ,根据硬件的不同,添加有时甚至比换档更便宜。

    对于有符号除法,请注意,在某些语言(如C)中,整数除法向零截断,而算术右移(在2的补码的符号位副本中移动)总是向-无限舍入。例如 (-5)/2 == -2 但是 (-5) >> 1 == -3 仍然可以通过移位+额外的操作来实现有符号除以2,以添加符号位以获得截断行为。(看看C编译器的输出。)

        2
  •  3
  •   Wagner DosAnjos    10 年前

    由于所有数字都以二进制形式存储,所以乘法/除法是一种简单的移位操作。

    例如(乘法):

    • 5=101(二进制)
    • 5*2=10=1010(二进制)-仅将所有位1位置向左移动
    • 5*4=20=10100(二进制)-仅将所有位2位置向左移动

    这同样适用于除法(右移操作),但如果需要余数,则需要考虑奇数除法的进位。

        3
  •  2
  •   Roland Krüger    10 年前

    在这种情况下,重要的是,除2(或2的幂)仅对整数运算是微不足道的。当你谈论浮点除法时,它就不那么重要了。

    原因是,某些数字系统(二进制、八进制、十六进制,你可以这么说)的基数除法总是可以通过简单的数字右移来完成。

    例如,在除以十的十进制中,您有:

    230.0 / 10.0 = 23.00 
    

    (将小数点向左移动一个位置,即数字向右移动)

    十六进制数也一样:

    0xA2FF / 0x10 = 0xA2F 
    

    (数字向右移动一个位置)

    二进制数也是如此:

    1101011 / 10 = 110101 (binary notation)
    107     /  2 = 53     (decimal notation for the same equation)
    

    如果要除以2的幂,则需要执行的右移次数与指数相对应。例如,除以4意味着除以2*2,等于两个右移操作:

    1101011 / 100 = 11010 (binary notation, two shift operations)
    107     /   4 = 26    (decimal notation)
    
        4
  •  1
  •   SeraphimFoA    10 年前

    基本上,要对一个数字进行2次乘除,如果这个数字是用二进制表示的,你只需要将所有二进制数字向左或向右平移:

    00100,即4,如果您想乘以2*2*2,只需将所有剩余的数字翻译3次:

    100000,即32(4*8=32)

    相反的方向