一、计算机中存储的都是补码

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的运算符--与(&)、非(~)、或(|)、异或(^)详解的更多相关文章

  1. Java短路运算符和非短路运算符

    在Java中短路运算符指的是"&&"(与) 和"||"(或) ,非短路运算符指的是"&" 和"|" ...

  2. 【java】运算符

    Java的运算符,分为四类: 算数运算符.关系运算符.逻辑运算符.位运算符. 算数运算符(9):+  -  *  /  %  ++  -- 关系运算符(6):==  !=  >  >=   ...

  3. java中运算符与表达式

    运算符是用来完成一个动作的特定语言的语法记号. –赋值运算符 –增减运算符 –算术运算符 –关系运算符 –逻辑运算符 -位运算符 运算符 Java 加 + 减 - 乘 * 除 / 取模 % 1.整数运 ...

  4. LeetCode刷题笔记(3)Java位运算符与使用按位异或(进制之间的转换)

    1.问题描述 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 算法应该具有线性时间复杂度并且不使用额外空间. 输入: [4,1,2,1,2] 输 ...

  5. Java位运算符、位移运算符;原码、反码、补码

    文章背景:雪花算法 id 生成长度问题. Java位运算符 - 异或运算符(^)<p>运算规则:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1.</p> - ...

  6. 二、java基础-运算符_控制语句_break_continue_return

    1.运算符 1)算术运算符:6个+ — * \ % ++  --2)关系运算符:6个>  >=  <  <=   ==   !=3)布尔运算符&&并且  ||或 ...

  7. 【Java】运算符(算术、赋值、比较(关系)、逻辑、条件、位运算符)

    运算符 文章目录 运算符 1. 算术运算符 2. 赋值运算符 3. 比较运算符 4. 逻辑运算符 5. 条件运算符 6. 位运算符 7. 运算符优先级 8. 运算符操作数类型说明 9.code 算术运 ...

  8. 菜鸡的Java笔记 第四 - java 基础运算符

    数学运算符,逻辑运算,三目运算,位运算 double d2 = 314e2; //采用科学计数法的写法,表示10的2次方.= 31400.0 代码写的越简单越好   简化运算符 代码:x=x+y 可以 ...

  9. JAVA的运算符和条件结构

    一.JAVA的运算符. 1.赋值运算符 赋值就是把一个变量的值赋给另一个变量. 语法: 变量名=表达式     例如  n = m + 5 2.算术运算符      算术运算符是数学中常用的加.减.乘 ...

  10. Java 位运算符和 int 类型的实现

    Java 位运算符和 int 类型的实现 其他运算符 # 算术运算符 +.-.*./.++i.i++.--i.i-- # 关系运算符 ==.!=.>.<.>=.<= # 逻辑运 ...

随机推荐

  1. CSS之 :before && :after的用法,伪类和伪元素的区别

    一::before && :after的用法 :before 如同对伪元素的名称一样,:before 是用来给指定的元素的内容前面插入新的内容.举例说明: .before:before ...

  2. Vagrant安装配置

    转载自:https://my.oschina.net/u/3424381/blog/888205 Vagrant安装配置 实际上Vagrant只是一个让你可以方便设置你想要的虚拟机的便携式工具,它底层 ...

  3. 【图解】Web前端实现类似Excel的电子表格

    本文将通过图解的方式,使用纯前端表格控件 SpreadJS 来一步一步实现在线的电子表格产品(例如可构建Office 365 Excel产品.Google的在线SpreadSheet). 工具简介: ...

  4. Ansible--原理

    什么是Ansible Ansible是一种IT自动化运维工具,它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署或者是零停机滚动更新Ansible是新出现的自动化运维工具,基于Python ...

  5. (网页)Java程序员们最常犯的10个错误(转)

    转自CSDN: 1.将数组转化为列表 将数组转化为一个列表时,程序员们经常这样做: List<String> list = Arrays.asList(arr); Arrays.asLis ...

  6. IP地址及子网划分

    1.IP地址 2.子网掩码 网络号全转为1,主机号全转为0,之后再转化为10进制表示. 3.无分类编址

  7. Oracle EBS FA 获取累计折旧

    FUNCTION get_ltd_deprn(p_asset_id IN NUMBER, p_book_type_code IN VARCHAR2, p_rate_source_rule IN VAR ...

  8. 通过日志过滤的方法,统计每天内容详情页面的PV数

    1.目的: 每天凌晨0点1分统计用户点击进入内容详情页的次数,对内容点击量形成榜单. 2.分析: A./data/log/epg.access.log日志实时打印用户访问页面的日志,并且每天凌晨0点会 ...

  9. 第七章 鼠标(CONNECT)

    /* CONNECT.C -- Connect-the-Dots Mouse Demo Program (c) Charles Petzold,1998 */ #include <Windows ...

  10. Win10更换电脑,又不想重装系统的解决方法

    问题描述: 在公司因为两年前用的i3的电脑很卡,然后想换i5的电脑,但是又不想重装系统,因为安装的东西太多了,重装很麻烦 Windows to go介绍: Windows To Go是Windows ...