继续最近想更的东西很多,也对以前的知识有了新的看法,PS最近看了几部像吃了shi一样的电影推荐给大家,《消失的爱人》 《月球》
最近新起项目,从底层搭建,在写一个发送信息或短信的接口,正好用到了Java的位运算,写博客保存,也是装逼的好方法。
以前了解到位运算,但是实际确很少碰到,这次也是一个特别简单的方法,先上示例:
PS:int 的实际大小是32bit,文中为了方便基本上使用16bit代替
一、java位运算中按位与 实例
public static void main(String[] args) {
sendMessage("","",7);
}
/**
* 发送信息的对外接口
* 发送短信flag : 1
* 发送邮件flag : 2
* 发送微信flag : 4
* 同时发送多种 flag : 和(发送短信和邮件就是3)
*/
private static final int SMS = 1;
private static final int MAIL = 2;
private static final int WECHAT = 4;
public static void sendMessage(String title,String content,int flag){
if((flag & SMS) == 1){
System.out.println("调用发送短信接口");
}
if((flag & MAIL) == 2){
System.out.println("调用发送邮件接口");
}
if((flag & WECHAT) == 4){
System.out.println("调用发送微信接口");
}
}
这个方法是比较简单的,使用java的安位与运算能够使逻辑更简洁和明朗。
二、java位运算
1.按位与 &
描述:两位全是1,结果才为1: 0&0=0; 0&1=0; 1&0=0; 1&1=1;
用途:
①清零:把一个数变为0,只要和0进行与运算。50&0=0;
②取一个数中制定位置:想取哪位,哪位置为1,其余为0;
设 x = 1010 1110 想要取得x的低4位
1010 1110
& 0000
1111
————————————————————
0000 1110
2.按位或 |
描述:只要有一个为1,结果就为1: 0|0=0; 0|1=1; 1|0=1; 1|1=1;
用途:
对一个数的某一位 置1:想要把哪位置1,哪位就是1,其余是0;
设 x = 1010 0000 低4位置1
1010 0000
| 0000 1111
————————————————————
1010 1111
3.按位异或 ^
描述:两个位的值为“异”(值不同),该位结果为1,值相同为0
0^0=0; 0^1=1; 1^0=1; 1^1=0;
用途:
①使特定位翻转:想要翻转的位为1,其余为0;
设 x = 1010 1110 低4翻转
1010 1110
^ 0000 1111
————————————————————
1010 0001
②与0异或保留原值
设 x = 1010 1110 保留原值
1010 1110
^ 0000 0000
————————————————————
1010 1110
③两个值进行交换:比较高效的方法
void swap(int x , int y)
{
x ^= y;
y ^= x;
x ^= y;
}
4.取反运算 ~
~1 = 0; ~0 = 1;
5.左移运算 <<
描述:将一个运算对象的各二进制位全部左移若干位(左边二进制丢弃,右边补0)
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。
2<<1=4;
0000 0010 左移1位 0000 0100 为4; => 2*2=4;
6.右移运算 >>
描述:将一个运算对象的各二进制位全部右移若干位(
正数左补0,负数左补1,右边丢弃)
每右移一位,相当于该数除以2;
4>>2=1;
0000 0100 右移两位 0000 0001 为1; => 4/2/2=1;
7.无符号右移运算 >>>
描述:各个位向右移制定位数(左边补0,右边丢弃)
8.负数移位举例
负数是以其正值的补码形式来表示的
原码:一个正数按照绝对值大小转化成的二进制数称为原码
14原码: 0000 0000 0000 0000 0000 0000 0000 1110
反码:将原码按位取反,所得二进制称为原二进制的反码
14反码: 1111 1111 1111 1111 1111 1111 1111 0001
补码:反码加1称为补码
14补码: 1111 1111 1111 1111 1111 1111 1111 0010 =>即-14的二进制表示
求-14<<2
1111 1111 1111 1111 1111 1111 1111 0010 左移两位,右边补0
1111 1111 1111 1111 1111 1111 1100 1000 然后这个二进制的十进制是多少呢?肯定是一个负数,所以需要按照上面顺序反向求出该二进制的十进制。
先减一:
1111 1111 1111 1111 1111 1111 1100 0111
取反:
0000 0000 0000 0000 0000 0000 0011 1000 =>56
所以 -14<<2 = -56;
以上是负数的取反的分析过程。
从网上找到一个位运算的口诀:
清零取数要用与,某位置一可用或
若要取反和交换,轻轻松松用异或
三、java进制转换
1.进制转换API
//十进制到十六进制
Integer.toHexString(int i);
//十进制到八进制
Integer.toOctalString(int i);
//十进制到二进制
Integer.toBinaryString(int i);
//十六进制到十进制
Integer.parseInt("0xff", 16);
//八进制到十进制
Integer.parseInt("0123", 8);
//二进制到十进制
Integer.parseInt("1010", 2);
2.Java基本数据类型
byte : 8bit;
short : 16bit;
int : 32bit;
long : 64bit;
float : 32bit;
double : 64bit;
char : unicode字符16bit;
3.java数据类型转换为字节的底层实现原理([color=red]就是使用位运算哦)[/color]
例:8143(00000000 00000000 00011111 11001111)转化为字节数组为:
byte[] b = [-49,31,0,0]
实现:
①低8位:
8143>>0*8 & 0xff; 8143右移0位 和十六进制0xff进行 & 运算。
0xff:11111111 功能就是屏蔽掉前面24位取得最后8位。
结果为:11001111 十进制:207 或者 -49;
②第二低8位:
8143 >> 1*8 & 0xff; 8143右移1位 和十六进制0xff进行 & 运算。
向右移8位,然后与运算屏蔽前面24位取得第二8位。
结果为:00011111 十进制:31;
③第三低8位:
8143 >> 2*8 & 0xff; 8143右移2位 和十六进制0xff进行 & 运算。
结果为0;
③第四低8位:
8143 >> 3*8 & 0xff; 8143右移3位 和十六进制0xff进行 & 运算。
结果为0;
综上,每次进行移位取特定的8位,转化成相应的字节数组,以上的方式是采用小端表示法。
4.javaIO的源码中位运算
java源码中与上面例子十分相似的有一个IO流的writeInt方法。
DataOutputStream中的writeInt()方法:
public final void writeInt(int v) throws IOException {
out.write((v >>> 24) & 0xFF);
out.write((v >>> 16) & 0xFF);
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
incCount(4);
}
java底层的实现很多都用到了位运算,所以掌握好了还是可以帮助查看源码的。
5.大小端
上面举例是采用小端的方式来输出字节数组的。
小端(Little-Endian):低位字节排放到内存的低地址端即该值的起始地址,高位字节排放到内存的高地址端。
大端(Big-Endian):高位字节排放到内存的低地址端即该值的起始地址,低位字节排放到内存的高地址端。
byte b = [-49,31,0,0]
小端
内存地址 | 0x4000 | 0x4001 | 0x4002 | 0x4003 |
存放内容 | -49 | 31 | 0 | 0 |
大端
内存地址 | 0x4000 | 0x4001 | 0x4002 | 0x4003 |
存放内容 | 0 | 0 | 31 | -49 |
先这些吧,累屎,不过每次自己码完博客,对待问题都会有更新的认识,明天继续JAVA IO流。
分享到:
相关推荐
Java运算,Java实例运算,面向基础.zip
Java位运算和逻辑运算的区别实例,请参考下面代码,希望对你有所帮助
从本章起,我们就正在进入Java基础知识的学习。就像人与人之间交流使用的语言需要遵循一定的语法规则一样,Java语言也离不开特定语法的支持,如基本语法、数据类型、变量、常量、运算符与表达式、类型转换和输入输出...
3.6.3 String型对象与基本数据类型间的运算 25 3.7 运算符 25 3.7.1 逻辑非(!) 26 3.7.2 位非运算符(~) 26 3.7.3 符号运算符(+、-) 27 3.7.4 增减运算符(++、--) 27 3.7.5 算术运算符(+、-、*、/) 29...
实例015 加密可以这样简单(位运算) 20 实例016 用三元运算符判断奇数和偶数 21 实例017 不用乘法运算符实现2×16 22 实例018 实现两个变量的互换 (不借助第3个变量) 23 第4章 流程控制 25 实例019 判断某一年...
java调用Gmssl中国密接口进行对称与非对称加解密等运算,动态so库进行接口jni方式调用,采取接口形式对外暴露,方便对接系统调用相关java接口进行相关运算操作。
使用java多态性,编写复数的四则运算实例
主要介绍了Java实现大数运算的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
完整java实例代码,包含猜数字、复数运算、回文判断、希腊字母表的输杨辉三角的输出。
超多Java初学者学习实例集锦,涉及到Java中算术运算符的使用、Java中位运算符的使用、break语句的使用、continue语句的使用、用do-while语句计算10的阶乘、用for语句计算10的阶乘、Java中逻辑运算符的使用、求三个数...
异或运算是基于⼆进制的位运算,采⽤符号XOR或者^来表⽰,运算规则是就与⼆进制,如果是同值取0、异值取1。 简单的理解就是不进位加法,例如1+1=0,0+0=0,1+0=0; 性质: 1. 交换律 可以任意交换运算因⼦,结果不变...
Java 实例 - 数字求和运算源代码-详细教程.zip
Java中位运算(移位、位与、或、异或、非) 的简单实例,需要的朋友可以参考一下
本书内容包括java语言概述、 ...实例015 加密可以这样简单(位运算) 实例016 用三元运算符判断奇数和偶数 . 实例017 不用乘法运算符实现2×16 实例018 实现两个变量的互换(不借助第3个变量)
* 一个参数通配符的实例 * 说明:对一个包含了数值元素的集合进行汇总运算。在这种情况下,用户并不关心 * 集合中的每一个对象是什么类型,只要它是数值型即可,而且,用户也希望集合中可以 * 存放不同类型的数值...
java实例第1章 记忆测试软件 1.1. 设计内容 1.2. 设计要求 1.3. 总体设计 1.4. 具体设计 1.4.1. 运行效果与程序发布 1.4.2. 主类Memory 1.4.3. 方块 Block 1.4.4. 记忆测试板MemoryTestPane 1.4.5. 显示成绩 ...