位移x *一个数字
你如何从这些位移实践问题中获得-10
数字?
根据我的理解, X*32
可以写成x<<5
。 但你怎么得到像x*66
或X*(-10)
?
一般说明
位移主要旨在移动数字的二进制表示。 它不是为了乘法。
23 = 0001 0111 23 << 1 = 0001 0111 << 1 = 0010 1110 = 46
但是,随着数字的二进制表示改变,它所代表的数字也会改变。 这就是计算机二进制系统的工作原理。 因此人们有时会利用这种行为作为“黑客”,主要是为了加快计算时间。
让我们试着更多地了解它:
左移位和右移位
现在,当表示的数字是integer
类型时,将数字的二进制表示向左移动将等于将其乘以 2:
23 = 0001 0111 23 << 1 = 0001 0111 << 1 = 0010 1110 = 46 //left bit-shift by 1, number becomes doubled
鉴于给定数据类型没有溢出 :
255 = 1111 1111 //assuming 8-bit data type 255 << 1 = 1111 1111 << 1 = 1111 1110 = 254 //not multiplied by 2, because of overflow
虽然向右移动整数将等同于将其除以2然后将其向下舍入 :
23 = 0001 0111 23 >> 1 = 0001 0111 >> 1 = 000 1011 = 11 //right bit-shift by 1, number becomes halved, rounded down
有些使用并链接到乘法和除法
由于位移操作通常比乘法成本更低,为了加快速度,你会在某些程序中看到,人们使用左位移操作(作为乘法的替代),当它们意味着乘以an integer number of power of 2
(即2,4,8,16等):
int a = 23; ... a = a << 2; //=102; multiply by 4, equivalent to a = a * 4, but faster operation
或者使用正确的位移操作(作为除法和舍入的替代)将其除以an integer number of power of 2
(即2,4,8,16等)
int a = 23; ... a = a >> 2; //=5; divide by 4 and rounding down, equivalent to integer division a = a / 4, but faster
结束语
请注意,只有使用幂为2的数字进行操作时,上面的所有乘法和除法才能被左移位或右移位替换。
在你的例子中,66和-10不是2的幂的整数,因此你不能通过二进制移位操作“破解”乘法/除法。
一般情况下,如果你的意思是位移,则使用位移操作,因为位移具有许多其他用途,而不仅仅是用于整数倍2的乘法/除法的“黑客”。如果你想乘法或除法,很高兴只使用乘法( *
)或除法( /
)运算符。
一些补充说明:
话虽这么说,我只想补充一些关于位移的内容以进一步解释(它不会造成伤害):
- 有符号
integer
类型可以保存正数或负数 - 处理负数时,逻辑位移和算术位移之间存在差异。 一个人在转移后在空旷空间给
0
,而另一个将给1
- 因此,最好注意位移主要用于
unsigned
类型,例如通过位移创建位掩码。 也就是说,当您处理负数(右)位移时,建议使用unsigned
来避免符号扩展意外。