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)

java二进制相关基础

java二进制相关基础

整数的表示

源码:第一位为符号位(0表示正数,1表示负数)。

反码:符号位不动,原码取反。

负数补码:符号位不动,反码加1。

正数补码:和源码相同。

备注:补码的好处:

使用补码可以没有任何歧义的表示0。

补码可以很好的参与二进制的运算,补码相加符号位参与运算,这样就简单很多了。

浮点数表示

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

我们以float来说明:

java二进制相关基础

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

java二进制相关基础

一个实数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=00&1=01&0=01&1=1

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwyzy.html