Java的运算符--与(&)、非(~)、或(|)、异或(^)详解
一、计算机中存储的都是补码
java也是如此:
System.out.println(Integer.toBinaryString(2));
System.out.println(Integer.toBinaryString(-2));
运行结果:
10
11111111111111111111111111111110
由于整数默认int型,32位。正数的补码和原码都一样,高位的0默认不打印。因此是10。
-2
原码:1000 0000 0000 0000 0000 0000 0000 0010
反码:1111 1111 1111 1111 1111 1111 1111 1101 (在源码基础上符号位不变,其余位取反)
补码:1111 1111 1111 1111 1111 1111 1111 1110 (反码+1)
从上面的结论来看,java二进制数据是以补码来存储的。
二、运算也是在反码的基础上进行运算的
1. ~ 按位非(NOT)操作。每位取反。即原来是0的变成1,原来是1的变成0。
System.out.println(~ (-2)); //结果为1
分析:
step1 -> -2原码:1000 0000 0000 0000 0000 0000 0000 0010
step2 -> -2反码:1111 1111 1111 1111 1111 1111 1111 1101
step3 -> -2补码:1111 1111 1111 1111 1111 1111 1111 1110
step4 -> 对-2的补码进行取反即可得到~(-2)的补码
step5 -> ~(-2)补码:0000 0000 0000 0000 0000 0000 0000 0001
step6 -> 由于符号位为0表示正数,因此补码和源码一样。转换为十进制就是1
2. & 按位与(AND)操作。1和1为1,1和0为0,0和0为0。
System.out.println(-3 & 2); //结果为0
分析:
step1 -> -3的原码:1000 0000 0000 0000 0000 0000 0000 0011
step2 -> -3的反码:1111 1111 1111 1111 1111 1111 1111 1100
step3 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101
step4 -> 2的补码:0000 0000 0000 0000 0000 0000 0000 0010
step5 -> step3和step4进行与运算即可得-3&2的补码,结果是正数,补码和原码相同。
step6 -> -3&2补码: 0000 0000 0000 0000 0000 0000 0000 0000
step7 -> 转换为十进制就为0
3. | 按位或(OR)操作。1和1为1,1和0为1,0和0为0。
System.out.println(-3 | 2); //结果为-1
分析:
step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101
step2 -> 2的补码:0000 0000 0000 0000 0000 0000 0000 0010
step3 -> step1和step2进行或运算即可得到-3|2的补码
step4 -> -3|2补码: 1111 1111 1111 1111 1111 1111 1111 1111
step5 -> 由于结果是在补码的基础上运算得来个,最高位为1表示负数,负数的补码和原码不相同,因此需要将补码转换为原码。
step6 -> -3|2反码: 1111 1111 1111 1111 1111 1111 1111 1110(反码到补码是反码+1,因此补码到反码是补码-1)
step7 -> -3|2原码: 1000 0000 0000 0000 0000 0000 0000 0001(符号位不变,反码取反)
step7 -> 将step7的二进制转换为十进制,即为-1
4. ^ 按位异或(XOR)操作。不同为1,相同为0。1和1为0,1和0为1,0和0为0。
System.out.println(-3 ^ 2); //结果为-1
分析:
step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101
step2 -> 2的补码:0000 0000 0000 0000 0000 0000 0000 0010
step3 -> step1和step2做异或运算得到补码
step4 -> -3^2补码: 1111 1111 1111 1111 1111 1111 1111 1111
step5 -> 由于结果是负数,因此需要将运算得补码转换为原码。
step6 -> -3^2反码: 1111 1111 1111 1111 1111 1111 1111 1110(补码-1)
step7 -> -3^2原码: 1000 0000 0000 0000 0000 0000 0001 0001(符号位不变,反码取反)
step8 -> 将step7的二进制原码转换为十进制数,结果为-1
5. >> 右移位操作(var >> bit)。指定值所有位向右移动指定位数。低位舍弃,高位按符号位填充。没有溢出的情况下,相当于除以2的n次方。
System.out.println(-3 >> 3); //结果为-1
分析:
step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101
step2 -> 右移3位
step3 -> 右移后补码:1111 1111 1111 1111 1111 1111 1111 1111
step4 -> 高位为负数因此,高位补1,低位舍弃。负数要转换为原码
step5 -> 右移后反码:1111 1111 1111 1111 1111 1111 1111 1110(补码-1)
step6 -> 右移后原码:1000 0000 0000 0000 0000 0000 0000 0001(符号位不变,反码取反)
step7 -> step6转换为十进制值为-1
6. >>> 无符号右移位操作(var >>> bit)。指定值所有位向右移动指定位数。低位舍弃,高位补0。
System.out.println(-3 >>> 3); //结果为536870911
分析:
step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101
step2 -> 无符号右移3位,高位补0,低位舍弃。
step3 -> 右移后补码:0001 1111 1111 1111 1111 1111 1111 1111
step4 -> 正数的补码和原码一样。结果为536870911
7. << 左移位操作(var << bit)。指定值所有位向左移动指定位数。低位补0,高位保留符号位。没有溢出的情况下,相当于乘以2的n次方。
System.out.println(-3 << 3); //结果为-24
分析:
step1 -> -3的补码:1111 1111 1111 1111 1111 1111 1111 1101
step2 -> 左移3位,高位不变。低位补0
step3 -> 右移后补码:1111 1111 1111 1111 1111 1111 1110 1000
step4 -> 右移后反码:1111 1111 1111 1111 1111 1111 1110 0111
step5 -> 右移后原码:1000 0000 0000 0000 0000 0000 0001 1000
step6 -> 将step5转换为十进制即为-24
Java的运算符--与(&)、非(~)、或(|)、异或(^)详解的更多相关文章
- Java短路运算符和非短路运算符
在Java中短路运算符指的是"&&"(与) 和"||"(或) ,非短路运算符指的是"&" 和"|" ...
- 【java】运算符
Java的运算符,分为四类: 算数运算符.关系运算符.逻辑运算符.位运算符. 算数运算符(9):+ - * / % ++ -- 关系运算符(6):== != > >= ...
- java中运算符与表达式
运算符是用来完成一个动作的特定语言的语法记号. –赋值运算符 –增减运算符 –算术运算符 –关系运算符 –逻辑运算符 -位运算符 运算符 Java 加 + 减 - 乘 * 除 / 取模 % 1.整数运 ...
- LeetCode刷题笔记(3)Java位运算符与使用按位异或(进制之间的转换)
1.问题描述 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 算法应该具有线性时间复杂度并且不使用额外空间. 输入: [4,1,2,1,2] 输 ...
- Java位运算符、位移运算符;原码、反码、补码
文章背景:雪花算法 id 生成长度问题. Java位运算符 - 异或运算符(^)<p>运算规则:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1.</p> - ...
- 二、java基础-运算符_控制语句_break_continue_return
1.运算符 1)算术运算符:6个+ — * \ % ++ --2)关系运算符:6个> >= < <= == !=3)布尔运算符&&并且 ||或 ...
- 【Java】运算符(算术、赋值、比较(关系)、逻辑、条件、位运算符)
运算符 文章目录 运算符 1. 算术运算符 2. 赋值运算符 3. 比较运算符 4. 逻辑运算符 5. 条件运算符 6. 位运算符 7. 运算符优先级 8. 运算符操作数类型说明 9.code 算术运 ...
- 菜鸡的Java笔记 第四 - java 基础运算符
数学运算符,逻辑运算,三目运算,位运算 double d2 = 314e2; //采用科学计数法的写法,表示10的2次方.= 31400.0 代码写的越简单越好 简化运算符 代码:x=x+y 可以 ...
- JAVA的运算符和条件结构
一.JAVA的运算符. 1.赋值运算符 赋值就是把一个变量的值赋给另一个变量. 语法: 变量名=表达式 例如 n = m + 5 2.算术运算符 算术运算符是数学中常用的加.减.乘 ...
- Java 位运算符和 int 类型的实现
Java 位运算符和 int 类型的实现 其他运算符 # 算术运算符 +.-.*./.++i.i++.--i.i-- # 关系运算符 ==.!=.>.<.>=.<= # 逻辑运 ...
随机推荐
- js之返回网页顶部
目标效果:浏览网页过程中,滑动滚轮,显示返回顶部按钮,点击返回顶部后,返回网页顶端. 代码如下: <!DOCTYPE html> <html lang="en"& ...
- pygame编程之font模块
方法一:pygame.font.Font(file, size=-1) 参数file:采用字体文件的路径,如果file参数设置为None则默认采用系统自带字体,如果自带字体文件无法打开就会报错: 参数 ...
- layui switch 开关监听 弹出确定状态转换
不废话,直接上图: 原始状态: 点击确定: 点击取消或者X 代码: <!doctype html> <html lang="en"> <head& ...
- 洛谷P3721 [AH2017/HNOI2017]单旋(线段树 set spaly)
题意 题目链接 Sol 这题好毒瘤啊.. 首先要观察到几个性质: 将最小值旋转到根相当于把右子树变为祖先的左子树,然后将原来的根变为当前最小值 上述操作对深度的影响相当于右子树不变,其他的位置-1 然 ...
- 微信小程序-06-详解介绍.js 逻辑层文件-注册页面
上一篇介绍的是 app.js 逻辑层文件中注册程序,对应的每个分页面都会有的 js 文件中 page() 函数注册页面 微信小程序-06-详解介绍.js 逻辑层文件-注册页面 宝典官方文档: http ...
- OpenCV 填充(ROI)+模糊操作
1.ROI 操作 src = cv.imread('./1.jpg') cv.imshow('src',src) dst = src[40:240,100:300] gray = cv.cvtColo ...
- [Android] ubuntu 下不识别 Android 设备
之前的android手机给家人用了,手里现在有一个旧手机,调试过程又出现不识别的问题,这次要记录一下. 首先,需要把手机开发者选项打开,在设置里对着android版本或者型号多点几次,就会打开. 原文 ...
- JavaScript大杂烩13 - 总结ECMAScript 5新功能
虽说这个标准已经出来很久了,所有的主流浏览器的最新版本也都支持了这些特性,但是很多的教程中并没有包含这个部分,这一节我们专门来总结一下这个标准中的新功能. Object的新方法 在最新的JavaScr ...
- ocLazyLoad按顺序加载
$ocLazyLoad.load({ serie:true, files: [oneFile,twoFile] }) 使用serie:true 这是 传送门
- 进程管理-PV操作
1.临界资源:诸进程需要互斥方式对其进行共享的资源. 2.临界区:每个进程中访问临界资源的那段代码. 3.信号量:一种特殊的变量.