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-- # 关系运算符 ==.!=.>.<.>=.<= # 逻辑运 ...
随机推荐
- CSS之 :before && :after的用法,伪类和伪元素的区别
一::before && :after的用法 :before 如同对伪元素的名称一样,:before 是用来给指定的元素的内容前面插入新的内容.举例说明: .before:before ...
- Vagrant安装配置
转载自:https://my.oschina.net/u/3424381/blog/888205 Vagrant安装配置 实际上Vagrant只是一个让你可以方便设置你想要的虚拟机的便携式工具,它底层 ...
- 【图解】Web前端实现类似Excel的电子表格
本文将通过图解的方式,使用纯前端表格控件 SpreadJS 来一步一步实现在线的电子表格产品(例如可构建Office 365 Excel产品.Google的在线SpreadSheet). 工具简介: ...
- Ansible--原理
什么是Ansible Ansible是一种IT自动化运维工具,它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署或者是零停机滚动更新Ansible是新出现的自动化运维工具,基于Python ...
- (网页)Java程序员们最常犯的10个错误(转)
转自CSDN: 1.将数组转化为列表 将数组转化为一个列表时,程序员们经常这样做: List<String> list = Arrays.asList(arr); Arrays.asLis ...
- IP地址及子网划分
1.IP地址 2.子网掩码 网络号全转为1,主机号全转为0,之后再转化为10进制表示. 3.无分类编址
- Oracle EBS FA 获取累计折旧
FUNCTION get_ltd_deprn(p_asset_id IN NUMBER, p_book_type_code IN VARCHAR2, p_rate_source_rule IN VAR ...
- 通过日志过滤的方法,统计每天内容详情页面的PV数
1.目的: 每天凌晨0点1分统计用户点击进入内容详情页的次数,对内容点击量形成榜单. 2.分析: A./data/log/epg.access.log日志实时打印用户访问页面的日志,并且每天凌晨0点会 ...
- 第七章 鼠标(CONNECT)
/* CONNECT.C -- Connect-the-Dots Mouse Demo Program (c) Charles Petzold,1998 */ #include <Windows ...
- Win10更换电脑,又不想重装系统的解决方法
问题描述: 在公司因为两年前用的i3的电脑很卡,然后想换i5的电脑,但是又不想重装系统,因为安装的东西太多了,重装很麻烦 Windows to go介绍: Windows To Go是Windows ...