网站首页 > java教程 正文
开始之前,想必大家都很熟悉这样一道面试题:
java面试题int a=2*8怎样运算效率最快
用移位运算 int a=2<<3;
a就是2乘以8 最后结果是16 这是最省内存 最有效率的方法
解释一下:
2的二进制是10, 在32位存储器里面是0000 0000 0000 0010
左移三位后变成 0000 0000 0001 0000 也就是16
java中的位运算
首先要明白一点,这里面所有的操作都是针对存储在计算机中中二进制的操作,那么就要知道,正数在计算机中是用二进制表示的,负数在计算机中使用补码表示的。
左移位:<<,有符号的移位操作
左移操作时将运算数的二进制码整体左移指定位数,左移之后的空位用0补充
右移位:>>,有符号的移位操作
右移操作是将运算数的二进制码整体右移指定位数,右移之后的空位用符号位补充,如果是正数用0补充,负数用1补充。
扩展:
1.原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。
2.反码的表示方法是:正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
3.补码的表示方法是:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1。 (即在反码的基础上+1)
4.原码和反码的相互转换:符号位不变,数值位按位取反
5.原码和补码的相互转换:符号位不变,数值位按位取反,末位再加1
6.已知补码,求原码的负数的补码:符号位和数值位都取反,末位再加1
例子:
public static void main(String[] args) { System.out.println(3<<2);//3左移2位 System.out.println(-3<<2);//-3左移2位 System.out.println(6>>2);//6右移2位 System.out.println(-6>>2);//-6右移2位 } 输出结果 12 -12 1 -2
下面解释一下:
00000000 00000000 00000000 00000011 3在32位计算机中表示
00000000 00000000 00000000 0000001100 左移2位,补0,结果为12
----------------------------------------------------------------------------------------------
00000000 00000000 00000000 00000011 +3在在32位计算机中表示
11111111 11111111 11111111 11111100 取反码
11111111 11111111 11111111 11111101 -3在计算机中表示(反码+1)
11111111 11111111 11111111 1111110100 左移2位,补0,结果为负数,就是补码了,
10000000 00000000 00000000 00001011 求原码
10000000 00000000 00000000 00001100 结果-12
----------------------------------------------------------------------------------------------
00000000 00000000 00000000 00000110 +6在计算机中表示方法
0000000000 00000000 00000000 000001 右移两位,正数补0,结果为1
----------------------------------------------------------------------------------------------
00000000 00000000 00000000 00000110 +6在32位计算机中表示方法
11111111 11111111 11111111 11111001
11111111 11111111 11111111 11111010 -6在在32位计算机中的表示
1111111111 11111111 11111111 111110 右移两位,结果为负数
1000000000 00000000 00000000 000001
1000000000 00000000 00000000 000010 结果为-2
这个地方很容易弄混,多想几次就会慢慢理解了。
上面解释了带符号的移位操作,下面解释一下不带符号的移位操作
无符号的移位只有右移,没有左移,使用“>>>”进行移位,都补充0
例如:
public static void main(String[] args) { System.out.println(6>>>2); System.out.println(-6>>>2); } 结果: 1 1073741822
分析:
00000000 00000000 00000000 00000110 +6在计算机中表示方法
0000000000 00000000 00000000 00000110 右移两位,正数补0,结果为1
-----------------------------------------------------------------------------------------------
00000000 00000000 00000000 00000110 +6在计算机中表示方法
11111111 11111111 11111111 11111001
11111111 11111111 11111111 11111010 -6在计算机中的表示
0011111111 11111111 11111111 11111010 右移两位,补充0,结果为1073741822
补充
移位操作要注意的问题是高(低)位是补0还是补1和对char, byte, short型的操作:
(1)<< : (left-shift), 最低位补0
(2)>> : (signed right-shift), 右移过程使用符号位扩展(sign extension),即如果符号为1则高位补1, 是0则补0,也就是逻辑右移
(3)>>> : (unsigned right-shit),右移过程使用零扩展(zero extension),即最高位一律补0,也就是算术右移
(4)移位操作的数据类型可以是byte, char, short, int, long型,但是对byte, char, short进行操作时会先把它们变成一个int型,最后得到一个int型的结果,对long型操作时得到一个long型结果,不可以对boolean型进行操作。
(5)移位操作符可以和=合并起来,即 <<= 、 >>= 和 >>>=。例如 a >>= 2; 表示将a右移两位后的值重新赋给a。当时在使用这三个操作符对 byte, char, short型数据进行操作时要注意,例如有一下代码片段:
public class ShiftTest { public static void main(String [] args) { byte a; byte b; byte c; a = 127; b = 127; c = 127; a <<= 2; System.out.println(a); System.out.println(b <<= 2); System.out.println(c << 2); } } 运行结果是: -4 -4 508
这说明了在操作a <<= 2 执行过程是这样的:先将 byte型的数 127变成int型,左移2位得到 508,然后把508赋给byte型变量a时只是简单地"折断"(truncate)得到数-4。编译时编译器不会提示你可能损失精度(实际上在本例中确实是损失精度了),但是如果你把a <<= 2改成 a = a << 2;编译器就会提示可能损失精度了。
总结
移位操作的简单计算方法
>>右移操作
x>>y
就是x除以2的y此方,取最小整数
<<左移操作
X<<y
就是x乘以2的y次方
猜你喜欢
- 2024-10-24 Bigo的Java面试,我挂在了第三轮技术面上...
- 2024-10-24 纯干货|盘点Java常见的30个误区与细节
- 2024-10-24 JAVA中红黑树(javahashmap红黑树)
- 2024-10-24 一文让你理解java中的类加载器(java类加载器的作用)
- 2024-10-24 初识java—(三十五)Math类、Random类和BigDecimal类
- 2024-10-24 终于有人把Git最火Java全套详细笔记(吐血放出)资料给分享出来了
- 2024-10-24 【算法题】1749. 任意子数组和的绝对值的最大值
- 2024-10-24 Java 的流程控制是什么样子的(java中的流程控制语句有哪些)
- 2024-10-24 Java常用内置函数(java内部类怎么调用)
- 2024-10-24 Java编程——数据库两大神器:索引和锁
你 发表评论:
欢迎- 最近发表
-
- 一招解决vscode报java插件版本不一致以及相关缓存引起的问题
- 关于Java 8版本的理解(java中的接口怎么理解)
- Java 9 到 Java 16 的版本演进:一次模块化革命和语言的持续进化
- 如何选择合适的Java版本(如何选择jdk版本)
- 晚会互动小游戏(晚会节目互动小游戏)
- 基于JavaSwing的象棋游戏系统java休闲游戏jsp源代码Mysql
- Java 猜字母游戏!会写会玩才是真本事!
- 基于JavaSwing的贪吃蛇大作战java休闲游戏jsp源代码mysql
- Java & Python 康威生命游戏 - 命令行版
- 高玩随机种子无损速通《我的世界》10分钟不到刷新世界纪录
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)