Java位运算符总结
来源:互联网 发布:美工算平面设计吗 编辑:程序博客网 时间:2024/05/16 15:24
Java中的位操作符
&(与)操作
两个操作数中位都为1,结果才为1,否则结果为0
public class data13{ public static void main(String[] args) { int a=129; int b=128; System.out.println("a 和b 与的结果是:"+(a&b)); }}
运行结果:
a 和b 与的结果是:128
下面分析这个程序:
“a”的值是129,转换成二进制就是10000001,而“b”的值是128,转换成二进制就是10000000。根据与运算符的运算规律,只有两个位都是1,结果才是1,可以知道结果就是10000000,即128。
|(或)运算符
或运算符用符号“|”表示,其运算规律如下:
两个位只要有一个为1,那么结果就是1,否则就为0,下面看一个简单的例子。
public class data14{ public static void main(String[] args) { int a=129; int b=128; System.out.println("a 和b 或的结果是:"+(a|b)); }}
运行结果
a 和b 或的结果是:129
下面分析这个程序段:
a 的值是129,转换成二进制就是10000001,而b 的值是128,转换成二进制就是10000000,根据或运算符的运算规律,只有两个位有一个是1,结果才是1,可以知道结果就是10000001,即129。
^(异或)运算符
异或运算符是用符号“^”表示的,其运算规律是:
两个操作数的位中,相同则结果为0,不同则结果为1。下面看一个简单的例子。
public class data16{ public static void main(String[] args) { int a=15; int b=2; System.out.println("a 与 b 异或的结果是:"+(a^b)); }}
运行结果
a 与 b 异或的结果是:13
分析上面的程序段:a 的值是15,转换成二进制为1111,而b 的值是2,转换成二进制为0010,根据异或的运算规律,可以得出其结果为1101 即13。
~(非)运算符
非运算符用符号“~”表示,其运算规律如下:
如果位为0,结果是1,如果位为1,结果是0,下面看一个简单例子。
public class data15{ public static void main(String[] args) { int a=2; System.out.println("a 非的结果是:"+(~a)); }}
运行结果是: -3, 2的二进制表示是:0000….000010
然后取~, 结果是1111….111101, 将补码转换成十进制就是-3
<< (左移)运算符
<< 和>>为数值位移,>>>为逻辑位移。【注】:Java中不存在<<<。 m<<n
的含义:把整数m表示的二进制数左移n位,高位移出n位都舍弃,低位补0. (此时将会出现正数变成负数的形式)
3<<2
剖析:
3的二进制形式: 00000000 00000000 00000000 00000011,按照左移的原理,得到00000000 00000000 00000000 00001100,即为12.
左移使整数变为负数:
10737418<<8
10737418二进制表示形式:00000000 10100011 11010111 00001010,按照左移的原理,得到10100011 11010111 00001010 00000000,即为:-1546188288.
>>(逻辑右移)运算符
m>>n的含义:把整数m表示的二进制数右移n位,m为正数,高位全部补0;m为负数,高位全部补1.
>> 会根据符号位的正负进行补位
3>>2剖析:
3二进制形式: 00000000 00000000 00000000 00000011,按照右移的原理,得到00000000 00000000 00000000 00000000,即为0.
-3>>2剖析:
-3二进制形式: 11111111 11111111 11111111 11111101,按照右移的原理,得到11111111 11111111 11111111 11111111,即为-1.
以上:每 个整数表示的二进制都是32位的,如果右移32位和右移0位的效果是一样的。依次类推,右移32的倍数位都一样。
>>>(无符号右移)运算符
m>>>n:整数m表示的二进制右移n位,不论正负数,高位都补零。
3>>>2剖析:
3二进制形式: 00000000 00000000 00000000 00000011,按照无符号右移的原理,得到00000000 00000000 00000000 00000000,即为0.
-3>>>2剖析:
-3二进制形式: 11111111 11111111 11111111 11111101,按照无符号右移的原理,得到00111111 11111111 11111111 11111111,即为1073741823.
&0xFF的意义
byte类型转换成int类型时需要进行 &0xFF的操作, 原因跟计算机的存储原理有关。
数据在内存是以补码的形式存在的。
补码:
正数(000000001): 正数的补码和反码都是它本身。
负数(100000001): 反码是对原码除了符号位之外作取反运算即(111111110),补码是对反码作+1运算即(111111111)。
System.out.println(-127 & 0xFF);// 结果是129
下面分析-127&0xFF的过程
-127的补码表示(10000001)
JVM向控制台输出时,检测到byte向int类型的转换于是做了一个补位处理
(10000001) -> (11111111,11111111,11111111,10000001)
这个32位的补码表示也是-127, 此时转换过后的二进制数据的十进制表示仍然是相同的,但是此时补码的因为高位补1已经不一致了,我们为了保证补码的一致性,必须进行&0xFF操作.进行&0xFF操作
&0xff可以将高的24位置为0,低8位保持原样。这样做的目的就是为了保证二进制数据的一致性。
当然,保证了二进制数据性的同时,如果二进制被当作byte和int来解读,其10进制的值必然是不同的,因为符号位位置已经发生了变化。
比如-127&0xff; -127 & 0xff=(11111111,11111111,111111111,10000001) & (00000000,00000000,00000000,11111111) = (00000000,00000000,00000000,10000001) 这个值算一下就是129.
// & 0xFF 的区别System.out.println(Integer.toBinaryString(-127));System.out.println(Integer.toBinaryString(-127 & 0xFF));// 11111111111111111111111110000001// 10000001
Java实现int和long类型的序列化
简单对上面的知识进行一个总结
这个小demo就是将int和long类型的数值写到文件中,然后在读出来,如果结果正确证明序列化成功.
创建文件
private static void createFile() { sFile = new File("./", "obj"); sFile.delete(); if (!sFile.exists()) { try { sFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }
int类型的序列化
int类型占8个字节,每次右移8个单位存储,需要分四次写入
// 将int数据写到硬盘上private static void writeInt(int num) throws IOException { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(sFile)); bos.write((num >> 0) & 0xFF); bos.write((num >> 8) & 0xFF); bos.write((num >> 16) & 0xFF); bos.write((num >> 24) & 0xFF); bos.flush(); bos.close(); } // 同样也是分四次读,每次获取8位数据,然后读四次 // 从文件中读取int类型的值 private static int readInt() throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sFile)); int num = 0; num |= bis.read(); num |= bis.read() << 8; num |= bis.read() << 16; num |= bis.read() << 24; bis.close(); return num; }
long类型的序列化
// long类型在JVM运行时占用8个字节,也就是64位,所以我们需要分8次向文件中写入数据 private static void writeLong(long num) throws IOException { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(sFile)); bos.write((int) ((num >> 0) & 0xFFL)); bos.write((int) ((num >> 8) & 0xFFL)); bos.write((int) ((num >> 16) & 0xFFL)); bos.write((int) ((num >> 24) & 0xFFL)); bos.write((int) ((num >> 32) & 0xFFL)); bos.write((int) ((num >> 40) & 0xFFL)); bos.write((int) ((num >> 48) & 0xFFL)); bos.write((int) ((num >> 56) & 0xFFL)); bos.flush(); bos.close(); } // 同样, 分8次从文件中读取数据,记得 &0xFFL 转换成long类型 private static long readLong() throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sFile)); long num = 0L; num |= (bis.read() & 0xFFL) << 0; num |= (bis.read() & 0xFFL) << 8; num |= (bis.read() & 0xFFL) << 16; num |= (bis.read() & 0xFFL) << 24; num |= (bis.read() & 0xFFL) << 32; num |= (bis.read() & 0xFFL) << 40; num |= (bis.read() & 0xFFL) << 48; num |= (bis.read() & 0xFFL) << 56; bis.close(); return num; }
测试代码
private static void serialIntTest() throws IOException { final int magic = -0x20170507; System.out.println("序列化前: " + magic); writeInt(magic); System.out.println("序列化后: " + readInt()); } private static void serialLongTest() throws IOException{ // 如果是long类型,那么数字结尾处必须加上L,否则会认为是int类型 final long magicLong = -0x2017050720170507L; System.out.println("序列化前: " + magicLong); writeLong(magicLong); System.out.println("序列化后: " + readLong()); }
完整代码
/** * Created by yangtianrui on 17-5-7. */public class WriteByteToFile { private static File sFile; public static void main(String[] args) throws Exception { createFile(); serialIntTest(); serialLongTest(); /* * 结果: * 序列化前: -538379527 * 序列化后: -538379527 * 序列化前: -2312322461839328519 * 序列化后: -2312322461839328519 */ } private static void serialIntTest() throws IOException { final int magic = -0x20170507; System.out.println("序列化前: " + magic); writeInt(magic); System.out.println("序列化后: " + readInt()); } private static void serialLongTest() throws IOException{ // 如果是long类型,那么数字结尾处必须加上L,否则会认为是int类型 final long magicLong = -0x2017050720170507L; System.out.println("序列化前: " + magicLong); writeLong(magicLong); System.out.println("序列化后: " + readLong()); } private static void writeInt(int num) throws IOException { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(sFile)); bos.write((num >> 0) & 0xFF); bos.write((num >> 8) & 0xFF); bos.write((num >> 16) & 0xFF); bos.write((num >> 24) & 0xFF); bos.flush(); bos.close(); } private static int readInt() throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sFile)); int num = 0; num |= bis.read(); num |= bis.read() << 8; num |= bis.read() << 16; num |= bis.read() << 24; bis.close(); return num; } private static void writeLong(long num) throws IOException { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(sFile)); bos.write((int) ((num >> 0) & 0xFFL)); bos.write((int) ((num >> 8) & 0xFFL)); bos.write((int) ((num >> 16) & 0xFFL)); bos.write((int) ((num >> 24) & 0xFFL)); bos.write((int) ((num >> 32) & 0xFFL)); bos.write((int) ((num >> 40) & 0xFFL)); bos.write((int) ((num >> 48) & 0xFFL)); bos.write((int) ((num >> 56) & 0xFFL)); bos.flush(); bos.close(); } private static long readLong() throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sFile)); long num = 0L; num |= (bis.read() & 0xFFL) << 0; num |= (bis.read() & 0xFFL) << 8; num |= (bis.read() & 0xFFL) << 16; num |= (bis.read() & 0xFFL) << 24; num |= (bis.read() & 0xFFL) << 32; num |= (bis.read() & 0xFFL) << 40; num |= (bis.read() & 0xFFL) << 48; num |= (bis.read() & 0xFFL) << 56; bis.close(); return num; } private static void createFile() { sFile = new File("./", "obj"); sFile.delete(); if (!sFile.exists()) { try { sFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } }}
- Java位运算符总结
- Java位运算符总结
- java位运算符总结
- Java 位运算符总结
- Java 位运算和运算符总结
- Java位运算总结
- java位运算总结
- java位运算总结
- java逻辑运算符位运算符总结
- 位运算符总结
- 位运算符总结
- 位运算符总结
- 【转载】Java位运算总结
- Java学习总结(16.05.31)Java位运算符
- Java位运算符
- Java 位运算符
- Java 位运算符
- Java 位运算符
- 搭建nginx反向代理的时候出现nginx启动异常,倒腾了一下总算解决了,具体如下
- php file_put_content 日志写入
- Intellij IDEA如何关闭自动更新提示信息
- 让IntelliJ IDEA 驼峰选择生效
- 算法提高 数字黑洞
- Java位运算符总结
- BNU 51640 Training Plan【Dp】
- hdu 1142
- 模态对话框与非模态对话框(modeless)
- ORACLE Coherence生产部署检查列表
- 雷神:音视频入门基础——000
- sublime 编辑器PackageControl出错及其问题
- poj 2018 斜率DP 求子序列的最大平均值
- 凯撒密码