java基础篇 之 位运算符
按位操作符
按位操作符用来操作基本数据类型中的单个“比特”(bit),即二进制位。按位操作符会对两个参数中对应的位执行布尔代数运算,并最终生成一个结果。
我们常用的按位操作符有以下几种:
&:与,如果参加运算的两个输入位都是1,则结果为1,否则生成一个输出位0
|:或,只要有一个输入位为1,则结果为1。换言之,只有两个输入位为0,结果才为0
~:非,非运算符为一元运算符,只对一个操作符操作,也叫取反运算符
^:异或,只有参加运算的两个输入数相反时,才会输出1
我们做以下实验:
public class Main {
public static void main(String[] args) {
int a = 16;
int b = 15;
String binaryStringA = Integer.toBinaryString(a);
String binaryStringB = Integer.toBinaryString(b);
// 填充到32位
String a32 = StringUtils.leftPad(binaryStringA, 32,"0");
String b32 = StringUtils.leftPad(binaryStringB, 32,"0");
System.out.println(a+"的二进制为:"+a32);
System.out.println(b+"的二进制为:"+b32);
System.out.println("a&b="+(a&b));
}
}
输出如下:
16的二进制为:00000000000000000000000000010000
15的二进制为:00000000000000000000000000001111
a&b=0
**解释**:这里因为操作数都是int,所以我将其都填充到32,这样更直观,我们可以看到,转换成二进制后,16,15每个bit上的值都是不一样的,所以最终的运算结果为0
上面我们测试了两个int类型的与操作,不知道大家有没有疑惑,如果参加运算的两个输入数类型不一致会怎么样呢?比如一个为int,另外一个为long呢?
我们来测试下:
```java
结果如下:
我们可以得出结论:
当数据类型不一致时,会自动将低级的数据类型往高级转,在我们上面的例子中,很明显,a被转成了long类型。
我们也可以对编译生成的class文件进行反编译,可以看到如下的代码:
public class Main {
public Main() {
}
public static void main(String[] args) {
int a = 16;
long b = 9223372036854775807L;
String binaryStringA = Integer.toBinaryString(a);
String binaryStringB = Long.toBinaryString(b);
String a32 = StringUtils.leftPad(binaryStringA, 32, "0");
String b32 = StringUtils.leftPad(binaryStringB, 64, "0");
System.out.println(a + "的二进制为:" + a32);
System.out.println(b + "的二进制为:" + b32);
System.out.println("a&b=" + ((long)a & b));
}
}
可以看到(long)a & b,在这里编译器自动进行了转换。
或跟异或在这里就不多赘述了,跟与操作差不多。
需要注意的是,非运算符,这是一个一元运算符,也就是说参与运算的只能有一个输入数,所以对于与,或,非,我们可以与赋值运算符“=”一起使用,但是非不行。比如我们可以写成a&=b或者a|=b,但是非是不行的。另外对于布尔类型,不能执行非操作
移位操作符
移位操作符操作的运算对象也是二进制的bit位。移位运算符只能用来处理整数类型(基本类型的一种)。左移运算符(<<)能按照操作符右侧指定的位数将操作符左边的数字向左移动(低位自动补0),对于右移这一操作,分为无符号右移(>>>)跟有符号右移(>>),所谓有符号右移是指,在进行运算时,如果原操作符的符号为正,则在高位补0,若为负,则在高位补1。而无符号右移,代表了不论正负,都会在高位补0。
如果对char,byte,short类型的数值进行移位处理,那么在进行操作之前他们会被转成int类型,并且得到的结果也是一个int类型的值。到这里不知道大家会不会有一个疑惑,如果会被转成int类型的话,我们知道int类型的长度为32位(其中一位为符号位),那么如果移位的位数超过32怎么办呢?我们以a>>>n这个表达式为例,n代表移位的位数,实际上更准确的讲,移位的位数=n%32,即n除以32取余。
测试代码如下:
public class Main {
public static void main(String[] args) {
// 32%32=0,所以结果还是8
System.out.println("8>>32=" + (8 >> 32));
// 33%32=1,所以相当于右移一位,其实右移一位,就是除以2,左移一位就是乘以2
// 以此类推,右移n位,相当于除以2的n次方
// 左移n位,相当于乘以2的n次方(在数字没有溢出的前提下结论才成立)
// 这个结论大家可以用画图的方式自己推导下
System.out.println("8>>33=" + (8 >> 33));
}
}
移位操作符与“=”赋值运算符配合使用
在这里我们讨论下<<=,>>=,>>>=这几个运算符。
主要讨论下面这种情况:我们知道对char,byte,short类型的数据进行移位运算时,会将其转换为int类型,那么在这种情况下,对一个byte类型的数据使用>>=,或者>>>=,会怎么样呢?主要就是讨论,如果运算后的结果超过了byte类型的上限怎么办呢?(这里只是以byte为例,对于其他两种类型也是一样的)
测试代码:
public class Main {
public static void main(String[] args) {
byte b = -1;
System.out.println(Integer.toBinaryString(b));
b >>>= 10;
System.out.println(Integer.toBinaryString(b));
System.out.println(Integer.toBinaryString(b>>>10));
}
}
结果如下:
11111111111111111111111111111111
11111111111111111111111111111111
(0000000000)1111111111111111111111
这是因为,在运算过程中,byte类型会先转成int类型,但是当被赋值到一个byte上时,会被截断。在这种情况下就出现了这种诡异的情况(括号中的0是我手动补的)
补充知识:
在计算机中,负数以原码的补码形式表达。
什么叫补码呢?这得从原码,反码说起。
原码:一个正数,按照绝对值大小转换成的二进制数;一个负数按照绝对值大小转换成的二进制数,然后最高位补1,称为原码。
比如 00000000 00000000 00000000 00000101 是 5的 原码;10000000 00000000 00000000 00000101 是 -5的 原码。
反码:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
比如:正数00000000 00000000 00000000 00000101 的反码还是 00000000 00000000 00000000 00000101 ;
负数10000000 00000000 00000000 00000101每一位取反(除符号位),得11111111 11111111 11111111 11111010。
称:10000000 00000000 00000000 00000101 和 11111111 11111111 11111111 11111010互为反码。
补码:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
比如:10000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011
java基础篇 之 位运算符的更多相关文章
- Java基础——逻辑运算符、位运算符
逻辑运算符.位运算符.三元运算符 逻辑运算符 public class Demon05 { public static void main(String[] args) { ...
- 第二十二节:Java语言基础-详细讲解位运算符与流程控制语句
位运算符(二进制位运算) 运算符 运算 例子 << 左移 3 << 2 = 12 --> 3 * 2 * 2 =12 >> 右移 3 >> 1 = ...
- 小白—职场之Java基础篇
java基础篇 java基础 目录 1.java是一种什么语言,jdk,jre,jvm三者的区别 2.java 1.5之后的三大版本 3.java跨平台及其原理 4.java 语言的特点 5.什么是字 ...
- java基础篇1
JAVA基础篇1 注释 单行注释 //这是一个单行注释,由两个斜杠组成,不能嵌套多行注释 多行注释 /*这是一个 多行注释 ,//里面不能嵌套多行注释, 但是可以嵌套单行注释*/ 文档注释 /**ja ...
- 金三银四跳槽季,BAT美团滴滴java面试大纲(带答案版)之一:Java基础篇
Java基础篇: 题记:本系列文章,会尽量模拟面试现场对话情景, 用口语而非书面语 ,采用问答形式来展现.另外每一个问题都附上“延伸”,这部分内容是帮助小伙伴们更深的理解一些底层细节的补充,在面试中可 ...
- java基础篇---HTTP协议
java基础篇---HTTP协议 HTTP协议一直是自己的薄弱点,也没抽太多时间去看这方面的内容,今天兴致来了就在网上搜了下关于http协议,发现有园友写了一篇非常好的博文,博文地址:(http: ...
- Python基础篇(格式化输出,运算符,编码):
Python基础篇(格式化输出,运算符,编码): 格式化输出: 格式:print ( " 内容%s" %(变量)) 字符类型: %s 替换字符串 %d 替换整体数字 ...
- SQL Server调优系列基础篇(联合运算符总结)
前言 上两篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符的优化技巧,本篇我们总结联合运算符的使用方式和优化技巧. 废话少说,直接进入本篇的主题. 技术准备 基于SQL Server200 ...
- java基础篇---I/O技术
java基础篇---I/O技术 对于任何程序设计语言而言,输入输出(I/O)系统都是比较复杂的而且还是比较核心的.在java.io.包中提供了相关的API. java中流的概念划分 流的方向: 输 ...
随机推荐
- Python-气象-大气科学-可视化绘图系列(三)—— 地图上自动标注省会名称(demo调整中)(代码+示例)
本文为原创文章 本文链接:https://www.cnblogs.com/zhanling/p/12606990.html # -*- coding: utf-8 -*- ''' Author: He ...
- stand up meeting 12/8/2015
part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 -------------- -- ----------- -- PDF Reader 朱玉影 ...
- ATcoder E - Flatten 质因子分解求LCM
题解:其实就是求n个数的lcm,由于数据特别大,求lcm时只能用质因子分解的方法来求. 质因子分解求lcm.对n个数每个数都进行质因子分解,然后用一个数组记录某个质因子出现的最大次数.然后累乘pow( ...
- Jmeter实现multipart/form-data类型请求
http请求有三种content-type:application/json.x-www-form-urlencoded.multipart/form-data,前两种比较常见,这里主要说multip ...
- bluecms v1.6 sp1 代码审计学习
前言 正式开始代码审计的学习,拓宽自己的知识面.代码审计学习的动力也是来自团队里的王叹之师傅,向王叹之师傅学习. 这里参考了一些前辈,师傅的复现经验和bluecms审计的心得 安装 install.p ...
- MySQL笔记总结-其他
数据库相关概念 一.数据库的好处 1.可以持久化数据到本地 2.结构化查询 二.数据库的常见概念 ★ 1.DB:数据库,存储数据的容器 2.DBMS:数据库管理系统,又称为数据库软件或数据库产品,用于 ...
- 实现Nginx Upload 模块 功能上传文件。
分析(也许我表达的让人难以理解,但是我想说一句,直接实践是最好的.....): 一.Ningx 上传( 1.安装Nginx 的模块文件(upload):https://www.nginx.com/re ...
- mac、window版编辑器 webstorm 2016... 永久破解方法。
第一步:从官网下载最新版本的webstorm编辑器(建议在官网下载,防止第三方插件恶意攻击!): 下载链接 http://www.jetbrains.com/webstorm/ , 点击 DOWN ...
- 杂园日记-H5-IOS-Android混合开发
1.js 调用 原生API iOS: window.webkit.messageHandlers.yourFunName.postMessage({"1":"3" ...
- Display a QMessageBox from a QThread
Emit a signal. Since you cannot do UI stuff in a Qthread, instead send your message as an argument o ...