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-- # 关系运算符 ==.!=.>.<.>=.<= # 逻辑运 ...
随机推荐
- PHP7.27: MySqlhelper class
https://github.com/ThingEngineer/PHP-MySQLi-Database-Class https://github.com/wildantea/php-pdo-mysq ...
- JavaScript异步和单线程
一,同步和异步的区别: 同步会阻塞代码执行,而异步不会.(比如alert是同步,setTimeout是异步) 二,前端使用异步的场景: 1,定时任务:setTimeout,setInterval 2, ...
- Flutter 布局(九)- Flow、Table、Wrap详解
本文主要介绍Flutter布局中的Flow.Table.Wrap控件,详细介绍了其布局行为以及使用场景,并对源码进行了分析. 1. Flow A widget that implements the ...
- Android Studio 通过一个登录功能介绍SQLite数据库的使用
前言: SQLite简介:是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经在 ...
- 创建Android Apps的30个经验教训
这个世界上有两种人-从经验教训中学习的人以及听从别人建议的人.这里是我一路走来学到的一些东西,分享给大家: 在添加任何第三方party之前,请三思:这真的是一个成熟的项目吗? 如果一个东西用户看不到, ...
- Spring 事件
JDK事件 java通过java.util.EventObject类和java.util.EventListener接口描述事件和监听器 事件源,事件的产生者,任何一个EventObject都必须拥有 ...
- Tensorflow实现稀疏自动编码(SAE)
1.概述 人在获取图像时,并不是像计算机逐个像素去读,一般是扫一眼物体,大致能得到需要的信息,如形状,颜色,特征.怎么让机器也有这项能力呢,稀疏编码来了. 定义: 稀疏自编码器(Sparse Auto ...
- mysql ANSI_QUOTES 这个sql_mode的作用(字段可以使用双引号)
首先sql_mode用于mysql的行为,sql_mode的多个值之间用','分隔: 如果想使用双引号就这样做: 1. 修改/etc/my.cnf文件 , 双引号模式是ANSI_QUOTES 或 ...
- 5.3Python函数(三)
目录 目录 前言 (一)装饰器 ==1.简单的装饰器== ==2.修饰带参数函数的装饰器== ==3.修饰带返回值函数的装饰器== ==4.自身带参数的装饰器== (二)迭代器 (三)生成器 ==1. ...
- MySQL基本简单操作03
MySQL基本简单操作 现在我创建了一个数据表,表的内容如下: mysql> select * from gubeiqing_table; +----------+-----+ | name | ...