DAY001_二进制运算
左移和右移
| 无符号左移? | Java没有无符号左移 |
|---|---|
| 无符号右移 | 左边补0 |
| 有符号右移 | 左边用原符号位补位 即正数补0效果同无符号右移、负数补1 |
| 有符号左移 | 右边补0 |
import org.junit.Test;
public class TestAaaBinary {
@Test
public void test01() {
//调用 JDK 的自带方法 toBinaryString 输出二进制数
test01(false);
//自己写的打印,结果与上面是一样的
test01(true);
}
private void test01(boolean print) {
int num_5 = 5;
int num_5_2 = -5;
System.out.println("无符号右移:正数");
for (int i = 0; i < 5; i++) {
print(num_5 >>> i, print);
}
System.out.println("无符号右移:负数");
for (int i = 0; i < 5; i++) {
print(num_5_2 >>> i, print);
}
System.out.println("有符号右移:正数");
for (int i = 0; i < 5; i++) {
print(num_5 >> i, print);
}
System.out.println("有符号右移:负数");
for (int i = 0; i < 5; i++) {
print(num_5_2 >> i, print);
}
System.out.println("有符号左移:正数");
for (int i = 0; i < 32; i++) {
print(num_5 << i, print);
}
System.out.println("有符号左移:负数");
for (int i = 0; i < 32; i++) {
print(num_5_2 << i, print);
}
}
private void print(int x, boolean print) {
if (print) {
print(x);
} else {
System.out.println(Integer.toBinaryString(x));
}
}
/**
* 输出十进制数的二进制格式
*/
private void print(int num) {
for (int i = 31; i >= 0; i--) {
System.out.print((num & (1 << i)) == 0 ? "0" : "1");
}
System.out.println();
}
}
输出如下:
无符号右移:正数
00000000000000000000000000000101
00000000000000000000000000000010
00000000000000000000000000000001
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000101
无符号右移:负数
11111111111111111111111111111011
01111111111111111111111111111101
00111111111111111111111111111110
00011111111111111111111111111111
00001111111111111111111111111111
00000111111111111111111111111111
00000011111111111111111111111111
00000001111111111111111111111111
00000000111111111111111111111111
00000000011111111111111111111111
00000000001111111111111111111111
00000000000111111111111111111111
00000000000011111111111111111111
00000000000001111111111111111111
00000000000000111111111111111111
00000000000000011111111111111111
00000000000000001111111111111111
00000000000000000111111111111111
00000000000000000011111111111111
00000000000000000001111111111111
00000000000000000000111111111111
00000000000000000000011111111111
00000000000000000000001111111111
00000000000000000000000111111111
00000000000000000000000011111111
00000000000000000000000001111111
00000000000000000000000000111111
00000000000000000000000000011111
00000000000000000000000000001111
00000000000000000000000000000111
00000000000000000000000000000011
00000000000000000000000000000001
11111111111111111111111111111011
有符号右移:正数
00000000000000000000000000000101
00000000000000000000000000000010
00000000000000000000000000000001
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000101
有符号右移:负数
11111111111111111111111111111011
11111111111111111111111111111101
11111111111111111111111111111110
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111011
有符号左移:正数
00000000000000000000000000000101
00000000000000000000000000001010
00000000000000000000000000010100
00000000000000000000000000101000
00000000000000000000000001010000
00000000000000000000000010100000
00000000000000000000000101000000
00000000000000000000001010000000
00000000000000000000010100000000
00000000000000000000101000000000
00000000000000000001010000000000
00000000000000000010100000000000
00000000000000000101000000000000
00000000000000001010000000000000
00000000000000010100000000000000
00000000000000101000000000000000
00000000000001010000000000000000
00000000000010100000000000000000
00000000000101000000000000000000
00000000001010000000000000000000
00000000010100000000000000000000
00000000101000000000000000000000
00000001010000000000000000000000
00000010100000000000000000000000
00000101000000000000000000000000
00001010000000000000000000000000
00010100000000000000000000000000
00101000000000000000000000000000
01010000000000000000000000000000
10100000000000000000000000000000
01000000000000000000000000000000
10000000000000000000000000000000
00000000000000000000000000000101
有符号左移:负数
11111111111111111111111111111011
11111111111111111111111111110110
11111111111111111111111111101100
11111111111111111111111111011000
11111111111111111111111110110000
11111111111111111111111101100000
11111111111111111111111011000000
11111111111111111111110110000000
11111111111111111111101100000000
11111111111111111111011000000000
11111111111111111110110000000000
11111111111111111101100000000000
11111111111111111011000000000000
11111111111111110110000000000000
11111111111111101100000000000000
11111111111111011000000000000000
11111111111110110000000000000000
11111111111101100000000000000000
11111111111011000000000000000000
11111111110110000000000000000000
11111111101100000000000000000000
11111111011000000000000000000000
11111110110000000000000000000000
11111101100000000000000000000000
11111011000000000000000000000000
11110110000000000000000000000000
11101100000000000000000000000000
11011000000000000000000000000000
10110000000000000000000000000000
01100000000000000000000000000000
11000000000000000000000000000000
10000000000000000000000000000000
11111111111111111111111111111011
此外,根据上面的代码,我们还可以经过测试得出
- int 类型位移32位、64位还是它本身
- long 类型位移64位还是它本身
原码&反码&补码
看上面的输出可能会有疑问
整型正数5的二进制是00000000 00000000 00000000 00000101
整型负数5的二进制是10000000 00000000 00000000 00000101
那为什么上文中对于-5的二进制输出是11111111 11111111 11111111 11111011呢?
先公布一下答案:这里输出的都是补码,计算机是使用补码做计算的。
下面详细解释为什么使用补码
计算机中只计算加法
- 减法可以化为加法:比如
5-4转化为5+(-4) - 乘法可以转化为加法和位移算法
- 除法可以先转化为乘法再转化
只算加法简化了电路的设计
但是在二进制运算下,一个正数加上其相反数并不等于0,比如0000 0001 + 1000 0001 = -2
因此出现了反码,而数字本身我们叫做原码。
- 正数的反码是它本身
- 负数的反码是:符号位不变,其他位取反,比如
-5的反码是11111111 11111111 11111111 11111010
反码存在的问题:
- 比如
5 + (-5) = 0,二进制是00000000 00000101 + 11111111 11111010 = 11111111 11111111全1表示0(负0) - 而
0 + 0 = 0,二进制00000000 00000000全0也表示0(正0)
还有更好的方案吗?答案就是补码
- 正数的补码是本身
- 负数的补码是反码+1,例如
-5的补码是11111111 11111111 11111111 11111011上文提到过
补码只有全0表示0一种情况,相比反码又简化了电路的设计
参考下面的代码:
public void test02() {
int num = 5;
System.out.println("正数5的补码是原码本身");
print(num);
System.out.println("正数5取反就是其相反数-5的反码");
print(~num);
System.out.println("-5用补码表示,是反码+1");
print(-num);
}
输出:
正数5的补码是原码本身
00000000000000000000000000000101
正数5取反就是其相反数-5的反码
11111111111111111111111111111010
-5用补码表示,是反码+1
11111111111111111111111111111011
扩展:整型的最大值和最小值
@Test
public void test03() {
System.out.println("整型最大值是正 2的31次方-1 补码就是其本身");
print(Integer.MAX_VALUE);
System.out.println();
System.out.println("整型最小值的补码");
print(Integer.MIN_VALUE);
System.out.println("补码取反");
print(~Integer.MIN_VALUE);
System.out.println("补码取反+1 就是整型最小值的相反数 即2的31次方 因此整型最小值是负 2的31次方");
}
输出:
整型最大值是正 2的31次方-1 补码就是其本身
01111111111111111111111111111111
整型最小值的补码
10000000000000000000000000000000
补码取反
01111111111111111111111111111111
补码取反+1 就是整型最小值的相反数 即2的31次方 因此整型最小值是负 2的31次方
DAY001_二进制运算的更多相关文章
- 为什么位运算可以实现加法(1、 不考虑进位的情况下位运算符中的异或^可以表示+号)(2、 位运算符中的与运算符&和左移运算符<<可以模拟加法中的进位)(3、位运算不仅可以做加法,还可以做其它的乘法减法等:计算机本质是二进制运算)
为什么位运算可以实现加法(1. 不考虑进位的情况下位运算符中的异或^可以表示+号)(2. 位运算符中的与运算符&和左移运算符<<可以模拟加法中的进位)(3.位运算不仅可以做加法,还 ...
- JavaSE基础(九)--Java二进制运算
Java二进制运算 Java二进制表示法 首先了解下二进制,二进制是相对十进制而言的,当然还有八进制,十六进制等等,我们常用的都是十进制,计算机用的都是二进制,而符号表示常用十六进制. 二进制就是只有 ...
- P2114 [NOI2014]起床困难综合症【二进制运算+优化】
起床困难综合症[二进制运算+优化] 题目描述 21世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm一直坚持与起床困难综合症作斗争.通过 ...
- 【Java EE 学习 75 下】【数据采集系统第七天】【二进制运算实现权限管理】【使用反射初始化权限表】【权限捕获拦截器动态添加权限】
一.使用反射动态添加权限 在该系统中,我使用struts2的时候非常规范,访问的Action的形式都是"ActionClassName_MethodName.action?参数列表" ...
- 【Java EE 学习 75 上】【数据采集系统第七天】【二进制运算实现权限管理】【权限分析和设计】
一.权限计算相关分析 1.如何存储权限 首先说一下权限保存的问题,一个系统中最多有多少权限呢?一个大的系统中可能有成百上千个权限需要管理.怎么保存这么多的权限?首先,我们使用一个数字中的一位保存一种权 ...
- Java基础--二进制运算
1. System.out.println((byte)0x8f); 结果是? 2.System.out.println((byte)(0xc5>>1)); 结果是? 3.System.o ...
- java中的二进制运算简单理解
package test9; public class StreamTest { public static void main(String[] args) { int a = 15;// 0b11 ...
- Java中的二进制运算出错问题
问题: 最近在做Java web项目中需要计算金额总和,在这里出现了一个问题是我以前没有关注到的: System.out.println(2.0-1.1); 执行时候的console中打印输出的是 0 ...
- 【.net 深呼吸】细说CodeDom(2):表达式、语句
在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系. 在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下.严格上说,Emit并不是针对代 ...
- Core Java 总结(数据类型,表达式问题)
2016-10-18 整理 写一个程序判断整数的奇偶 public static boolean isOdd(int i){ return i % 2 == 1; } 百度百科定义:奇数(英文:odd ...
随机推荐
- redis内存突然暴增,排查思路是什么
1 这种暴增的应该还是上次一个群友说的,更多可能是外部因素导致的,应用新上线,定时任务这些,再有就是cat上查是哪些指令多,以及比对和之前的时间的差异 看是否有定时任务 或者 新上线的活动 ,在看下监 ...
- vue全家桶进阶之路16:自定义过滤器及开发插件
过渡 过渡(transition)是Vue提供的一种在元素在插入.更新或移除时,自动添加动画效果的方式.Vue提供了多种过渡效果,其中包括基于CSS动画的过渡,以及JavaScript过渡. 过渡可以 ...
- Netty实战(一)
目录 第一章 Java网络编程 1.1 Java NIO 1.2 选择器 第二章 Netty是什么 2.1 Netty简介 2.2 Netty的特性 2.2.1 设计 2.2.2 易于使用 2.2.3 ...
- vue对vue-giant-tree进行节点操作
vue 项目中使用到了vue-giant-tree这个使用ztree封装的树形插件,在对其节点进行操作时遇到了无法向传统的jquery那样获取到ztreeObj:而导致了无法控制节点dom:浪费了许多 ...
- 「GPT虚拟直播」实战篇|GPT接入虚拟人实现直播间弹幕回复
摘要 ChatGPT和元宇宙都是当前数字化领域中非常热门的技术和应用.结合两者的优势和特点,可以探索出更多的应用场景和商业模式.例如,在元宇宙中使用ChatGPT进行自然语言交互,可以为用户提供更加智 ...
- Python潮流周刊#3:PyPI 的安全问题
你好,我是豌豆花下猫.这里记录每周值得分享的 Python 及通用技术内容,部分为英文,已在小标题注明.(标题取自其中一则分享,不代表全部内容都是该主题,特此声明.) 文章&教程 1.掌握Py ...
- Microsoft R 和 Open Source R,哪一个才最适合你?
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. R 是一个开源统计软件,在分析领域普及的非常快. 在过去几年中,无论业务规模如何,很多公司都采 ...
- 基因 ID 匹配利器
一.背景 对于每个生物信息分析的人来说,ID 匹配(映射)是一项非常常见,但又很繁琐的任务.假设,我们有一个来自上游分析的 gene symbol 或报告的 ID 列表,然后我们的下一个分析却需要使用 ...
- 写一个Python简单的Socket网络通讯
完成需求 用Python完成一个简单的Socket通讯实例 1. 服务端 用于提供服务 源码: import socket s = socket.socket() # 创建服务器端套接字 # sk.s ...
- c++中vector容器的用法
C语言中const关键字是constant的缩写,通常翻译为常量.常数等,它可以修饰变量.数组.指针.函数参数. vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器.ve ...