java二进制相关基础

转载请注明原创出处,谢谢!

说在前面

之前在JVM菜鸟进阶高手之路十(基础知识开场白)的时候简单提到了二进制相关问题,最近在看RocketMQ的源码的时候,发现涉及二进制的内容蛮多,jdk源码里面也是有很多涉及到二进制相关的操作,今天这篇文章仅仅是扫盲篇,后续会介绍灵活运用篇。

说明

任何东西都有规范,提到JAVA就会提到2个规范,JAVA语言规范、JVM规范。JAVA语言规范主要定义JAVA的语法、变量、类型、文法等等,JVM规范主要定义Class文件类型、运行时数据、帧栈、虚拟机的启动、虚拟机的指令集等等。

  • JAVA语言规范主要定义什么是JAVA语言。
  • JVM规范主要定义JVM内部实现,二进制class文件和JVM指令集等。

规范中数字的内部表示和存储

JAVA八种基本数据类型:
整形:byte,short,int,long
浮点型:float,double
布尔型:boolean
字符型:char

数据类型 所占位数
int 32bit
short 16bit
long 64bit
byte 8bit
char 16bit
float 32bit
double 64bit
boolean 1bit

备注:1字节=8位(1 byte = 8bit)

整数的表示

  • 源码:第一位为符号位(0表示正数,1表示负数)。
  • 反码:符号位不动,原码取反。
  • 负数补码:符号位不动,反码加1。
  • 正数补码:和源码相同。

    备注:补码的好处:

    • 使用补码可以没有任何歧义的表示0。
    • 补码可以很好的参与二进制的运算,补码相加符号位参与运算,这样就简单很多了。

浮点数表示

在上图中,我们了解到Float与Double都是支持IEEE 754

我们以float来说明:

IEEE754单精度浮点格式共32位,包含三个构成字段:23位小数f,8位偏置指数e,1位符号s。将这些字段连续存放在一个32位字里,并对其进行编码。其中0:22位包含23位的小数f; 23:30位包含8位指数e;第31位包含符号s。

一个实数V在IEEE 754标准中可以用V=(-1)s×M×2E 的形式表示,说明如下:

  • 符号s(sign)决定实数是正数(s=0)还是负数(s=1),对数值0的符号位特殊处理。
  • 有效数字M(significand)是二进制小数,M的取值范围在1≤M<2或0≤M<1。
  • 指数E(exponent)是2的幂,它的作用是对浮点数加权。
符号位 指数位 小数位
1位 8位 23位

例如根据IEEE754,计算11000001000100000000000000000000的单精度浮点的值。

解题:

1 10000010 00100000000000000000000
符号位 指数 尾数由于指数不是全部为0 所以小数位附加1
1 10000010 1.00100000000000000000000
-1 2^(130-127) (2^0 + 2^-3)

结论:
-1 * (2^0 + 2^-3) * 2^(130-127) =-9

同样,你也可以验证一下十进制浮点数0.1的二进制形式是否正确,你会发现,0.1不能表示为有限个二进制位,因此在内存中的表示是舍入(rounding)以后的结果,即 0x3dcccccd, 十进制为0.100000001, 误差0.000000001由此产生了。

说到这里JVM菜鸟进阶高手之路十(基础知识开场白)的有些问题其实都解答了,所以涉及到钱的小数类型必须使用BigDecimal,禁止使用float和double。

进制的概念

我们常用的进制有二进制、八进制、十进制和十六进制,十进制是最主要的表达形式。

二进制是0和1;八进制是0-7;十进制是0-9;十六进制是0-9+A-F(大小写均可)。

位运算符

按位与(&)

两位全为1,结果才为1:

0&0=0;
0&1=0;
1&0=0;
1&1=1; 

用法:

  • 清零:如果想要一个单位清零,那么使其全部二进制为0,只要与一个各位都为零的数值想与,结果为零。
  • 取一个数中指定位:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。

例如:设X=1010 1110,取X的低4位,用X & 0000 1111 = 0000 1110 就可以得到。

按位或(|)

只要有一个为1,结果就为1:

0|0=0;
0|1=1;
1|0=1;
1|1=1;

用法:常用来对一个数据的某些位置1;找到一个数,对应X要置1的位,该数的对应位为1,其余位为零。此数与X相或可使X中的某些位置1。

例如:将X=1010 0000 的低四位置1,用X | 0000 1111 =1010 1111 就可以得到。

异或运算(^)

两个相应位为“异”(值不同),则该位结果为1,否则为0:

0^0=0;
0^1=1;
1^0=1;
1^1=0;

用法:

  • 使特定位翻转:找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或就可以得到;
    例如:X=1010 1110,使X低4位翻转,用X ^ 0000 1111 = 1010 0001就可以得到
  • 与0相异或,保留原值
    例如:X ^ 0000 0000 = 1010 1110
  • 两个变量交换值的方法:
    1、借助第三个变量来实现: C=A; A=B; B=C;
    2、 利用加减法实现两个变量的交换:A=A+B; B=A-B;A=A-B;
    3、用位异或运算来实现:利用一个数异或本身等于0和异或运算符合交换律
    例如:A = A ^ B; B = A ^ B; A = A ^ B;

取反运算(~)

对于一个二进制数按位取反,即将0变1,1变0: ~1=0; ~0=1;

左移运算(<<)

  • 将一个运算对象的各二进制位全部左移若干位(左边的二进制丢弃,右边补零)
    2<<1 = 4 : 10 <<1 =100=4
  • 若左移时舍弃的高位不包括1,则每左移一位,相当于该数乘以2。
    -14(二进制:1111 0010)<< 2= (1100 1000) (高位包括1,不符合规则)

右移运算(>>)

将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。操作数每右移一位,相当于该数除以2.

左补0 or 补1 得看被移数是正还是负。
例:4 >> 2 = 1
例:-14(1111 0010) >> 2 = -4 (1111 1100 )

无符号右移运算(>>>)

各个位向右移指定的位数。右移后左边突出的位用零来填充。移出右边的位被丢弃
各个位向右移指定的位数。右移后左边突出的位用零来填充。移出右边的位被丢弃
例如: -14>>>2
即-14(1111 1111 1111 1111 1111 1111 1111 0010)>>> 2
=(0011 1111 1111 1111 1111 1111 1111 1100)
= 1073741820

Java打印整数的二进制表示

int a = 1120429670;
for (int i = 0; i < 32; i++) {
    int t = (a & 0x80000000 >>> i) >>> (31 - i);
    System.out.print(t);
}

说明:

  • 0x80000000是数的十六进制表示,转成二进制表示为10000000000000000000000000000000
  • 运算的优先级,移位运算高于逻辑运算,>>>高于&
  • 位逻辑与运算 1&1 = 1 ,0&1 = 0
  • >>>无符号右移,移出部分舍弃,左边位补0;

欢迎积极留言讨论关于你在实际运用中了解到二进制的一些优秀实践,期待你的留言!!!

如果读完觉得有收获的话,欢迎点赞、关注、加公众号【匠心零度】。



个人公众号,欢迎关注,查阅更多精彩历史!!!

时间: 2024-09-30 22:08:25

java二进制相关基础的相关文章

java 的相关基础 Day 01

Day 01 how to learn the lession learn self control .type by urself Unite 1 语言:交流的工具 计算机语言:人与计算机交流的工具 CPU 执行命令.是别的只有指令.指令就是指能被CPU 识别的二进制语言. 二进制:什么都可以用二进制表示.图片,电影,难怪二进制要写很多 语言发展历史:机器语言 进化 汇编语言 : 进化 高级语言:更加符合人类的思维习惯和语法,隐藏底层实现.that means ,底层语言越机器化 c ,c++

java web 相关基础概念的汇总

省去一些废话,反正是记录自学过程的,便于自己理清思路,自知自己资质欠佳,若有不对的地方还请不吝赐教. Java:是一种可以撰写跨平台应用软件的面向对象的程序设计语言.是由Sun公司1995年5月推出的Java程序设计语言和Java平台(SE/EE/ME). Java语言的特性:1.简单性. 2.面向对象:面向对象编程(Object Oriented Programming,OOP,即面向对象程序设计)是一种计算机编程架构.基本原则是计算机程序由单个能够起到子程序作用的单元或对象组合而成.为了实现

Java JVM 相关基础知识

1.JMM Java内存模型 每条线程都有自己的工作内存[Working Memory] 线程的工作内存保存了被该线程使用的变量的主内存副本拷贝 线程对变量的所有线程之间也无法直接访问对方工作内存的变量,线程间变量值的传递均需要通过主内存来完成. 2.java的堆和栈 1)堆 heap:可动态申请的内存空间(其记录空闲内存空间的链表由操作系统维护): 其中的内存在不需要时可以回收,以分配给新的内存请求,其内存中的数据是无序的: 一般由使用者自由分配,malloc 分配的就是堆,需要手动释放: 被

关于Java的相关基础信息

Java EE API: JMS (Java Message Service) 高性能异步消息服务,实现Java EE 应用程序与非Java程序的透明-通信 JMX(Java Management Extendsions)在程序运行时对其进行交互式监控和管理的机制 JTA(Java Transaction API): 允许应用程序在自身的一个或者多个组件中平滑地处理错误的机制 JavaMail: 通过工业标准的POP/SNTP/IMAP协议发送和接收邮件的机制 JAVA SE API: JNDI

Java Reflection 相关及示例

Java Reflection 相关及示例 前言: 代码有点长.贴出github地址:https://github.com/andyChenHuaYing/scattered-items/tree/master/items-java-reflection 测试目标类:TargetClass.自定义的辅助类比较多.在这里不贴了.篇幅有限.并且测试也简单.因此测试类也没有提及. 一:简介 Java Reflection是针对Class也就是我们平常说的类而言的.用于操作Java中的Class.在Ja

黑马程序员——Java I/O基础知识之I/O流

I/O流基础知识--字节流和字符流 文件存储在硬盘中,是以二进制表示的,只有内存中才能形成字符.数据的来源可以有硬盘,内存,控制台,网络,Java把数据从一个地方转到另一个地方的现象称为流,用InputStream和OutputStream接口来表示,这两个流里面的都是以字节为单位的,后来加入了Reader和Writer,里面操作的是字符,是两个字节为单位的. 字节流 字节流将数据写入文件 try { File file =new File("d:" +File .separator+

Java 技术体系基础概念

Java 技术体系基础概念 =============================================================================== 概述: =============================================================================== 编程语言: [百度百科解释] 编程语言俗称"计算机语言",种类非常的多,总的来说可以分成机器语言.汇编语言.高级语言三大类.电脑每做的

Java网络编程和NIO详解开篇:Java网络编程基础

Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为我们拥有网络.网络是一个神奇的东西,它改变了你和我的生活方式,改变了整个世界. 然而,网络的无标度和小世界特性使得它又是复杂的,无所不在,无所不能,以致于我们无法区分甚至无法描述. 对于一个码农而言,了解网络的基础知识可能还是从了解定义开始,认识OSI的七层协议模型,深入Socket内部,进而熟练地

Java集合相关面试问题和答案

Java集合相关面试问题和答案 面试试题 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用,Java1.2提出了囊括所有集合接口.实现和算法的集合框架.在保证线程安全的情况下使用泛型和并发集合类,Java已经经历了很久.它还包括在Java并发包中,阻塞接口以及它们的实现.集合框架的部分优点如下: (1)使用核心集合类降低开发成本,而非实现我们自己的集合类.