应几个法国巴西和印度小程序员的邀请,
我每周在Facebook上发布Java系列小文章,与你们也共享一下。
翻译 | 王楷涵
这个问题的回答是:2<<3。
“<<” 是位运算操作符,这将左移1位,接下来将展示该位运算操作符是如何工作的:
初始的值为2,其对应的二进制数值为00000010,<<3这个操作意味着左移3次,移动后结果将变为00010000(十进制为16)。
基本上,向左位移一次等于乘以2。
现在,我们可以尝试更多的例子:
2<<9 其结果为1073741824
2<<30 其结果为-2147483648
2<<31 其结果为0
2<<32 其结果为2
为了解释以上“非正常”的结果,我们必须知道,在Java中,<<应用于int值。因此每一个操作数都有32位,我们可以将2表示为
00000000 00000000 00000000 00000010
对于这个值,<<29(向左位移29次)将得到以下二进制值:
01000000 00000000 00000000 00000000
这是1073741824这个数值的二进制展示。
对于<<30,将会得到:
10000000 00000000 00000000 00000000
Integer的值是一个带符号的值,内部用补码系统实现,最高位定义了整数的正负,0表示为正,1表示为负。
因此,二进制值0000000 00000000 00000000 00000000是一个负数,反码值为01111111 11111111 11111111 11111111,再加1,实现的原始值为10000000 00000000 00000000 00000000,这就是231,或者2147483648,因此这个结果为-2147483648。
请注意,-2147483648和2147483648这两个数字对应的二进制数是相通的,不必担心这个,事实上一个32位的整数仅能表示4G(232(4294967296))个数字,你可以将这些数字视为位置索引,从0到4294967295,或者从-2147483648到2147483647,前一种是无符号值,而后一种是有符号值。在代数系统中,这是一个闭环,因此在2147483647这最后一个位置,加1则会让整数回到-2147483648。
在理解了这个系统的实现后,其他例子也就变得清晰明了。
左位移能用循环简单且直接地实现,因此这是理论上实现乘法最快的方式。但其实际执行结果依赖于编译器的优化。