全部版块 我的主页
论坛 休闲区 十二区 灌水吧
901 0
2016-05-11
  抛砖引玉:
  Java 中定义了 3 种移位运算符,分别是左移运算符“<<”、右移运算符“>>”和无符号右移运算符“>>>”,对于移位运算,移位运算两边的操作数要求为整型,即 byte、short、char、 int 和 long类型,或者通过拆箱转换后为整型。当操作数的类型为 byte、short 或 char 类型时, 会自动提升为 int 类型,运算的结果也为 int类型。对于移位运算,人们对其“误会”实在太深了……
  超过自身位数的移位
  我们知道,int 类型占用 4 字节,32 位,而 long 类型占用 8 字节,64 位。那么,如果将 int 类型(long 类型)移动超过 31位(63 位)便失去了意义,因为用通俗的话来说,就是“全移 走了”。不过幸运的是,当左侧操作数为 int 类型(byte、char 与 short类型自动提升为 int 类型) 或 long 类型时,如果右侧操作数大于 31 或 63,系统做了相关处理。
  是怎么处理的呢?普遍都是这样认为的:如果左侧操作数为 int 类型(包括提升后为 int 类 型),会对右侧操作数进行除数为 32 的求余运算,如果左侧操作数为long 类型,会对右侧操作 数进行除数为64的求余运算,例如:

复制代码

  结果会先进行求余运算:

复制代码

  因此,实际右侧的操作数是 3 与 6,而不是 3 与 70。
  90%的 Java 程序员都持上述观点,然而,遗憾的是,这个想法是不正确的。
  需要注意的是:右侧的操作数可以是任意的整型数值,只要该值没有超过类型变量的取值 范围就可以。那么,当右侧操作数为负值时,例如:

复制代码

  按照上面的观点,首先对 32 求余,即:

复制代码

  结果还是−4,现在问题来了,向左移动−4 位,该怎样移动?
  实际上,当左侧操作数为 int 类型时(包括提升后为 int 类型),右侧操作数只有低5位是有效的(低 5 位的范围为 0~31) ,也就是说可以看作右侧操作数会先与掩码 0x1f 做与运算(&) ,然后左侧操作数再移动相应的位数。类似地,当左侧操作数为 long 类型时,右侧操作数只有低 6 位是有效的,可以看作右侧操作数先与掩码 0x3f做与运算,然后再移动相应的位数。例如, 假设有如下的赋值运算:

复制代码

  取其低 5 位,结果为: 1 0 1 1 0 这个值就是 22,也就是相当于:

复制代码

  因此,不要把移位运算右侧的操作数与求余运算联系在一起,那是不正确的。
  移位运算与乘除运算
  由于数据采用二进制来表示,因此就会普遍存在这样的想法:左移一位就相当于乘以 2, 而右移一位就相当于除以 2,这种想法正确吗?下面的程序将给予验证。
  【例 】移位与乘除

复制代码

  本程序选取了几个数值,然后分别计算该数值乘以 2、除以 2、左移一位与右移一位的值(第 13~16 行),接下来比较乘以 2 与左移一位(第22~26 行)、除以 2 与右移一位(第 28~32 行) 是否相等。程序运行结果如下:

复制代码

  输出结果除了最后一行以外,其余都是相等的。那么最后一行有什么特别吗? 这要从相除的舍入模式说起。在 Java中,当两个操作数都是整型的时候,结果也是整型的 (假设没有发生 ArithmeticException 异常)。如果不能整除,则结果是向 0 舍入的,也就是说,向靠近 0 的方向取值。例如在本程序中,表达式:

复制代码

  的值为 4.5,介于 4 与 5 之间,由于 4 更靠近 0,所以向 0 舍入,结果为 4,这相当于向下舍入, 而表达式:

复制代码

  的值为−4.5,介于−4 与−5 之间,向 0 舍入为−4,这相当于向上舍入。而对于移位运算来说,表达式:

复制代码

  的值为 4,相当于向下舍入,而表达式:

复制代码

  的值为−5,还是相当于向下舍入,因此,不同的数值出现了。由于相乘运算与整除的时候不涉及如上舍入模式的问题,所以,值是相等的。但是,一旦不能整除,就会涉及舍入模式,这样, 结果就会存在差异了。表 2-4 给出了具体的情况。
  所以,乘以 2n与左移 n 位的值是相等的,如果可以整除,除以 2n与右移 n 位的值也是相等 的。如果不能整除,当被除数为正数时,除以 2n与右移n 位的值相等,当被除数为负数时,除 以 2n与右移 n 位的值则是不相等的。
  注意 以上所指的右移,如无特殊说明,均指有符号右移(>>)。
  本文出自柠檬派 ,作者:梁勇http://www.lemonpai.com/1009.html 请务必保留此出处 ,否则将追究法律责任!
  相关阅读:大数据Java基础——移位运算的真实剖析 (二) http://www.lemonpai.com/1023.html 有问题希望大家多多指点。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群