System.out.println("Float.MAX_VALUE:"+Float.MAX_VALUE);
System.out.println("Integer.MAX_VALUE:"+Integer.MAX_VALUE);
System.out.println("Integer.MIN_VALUE:"+Integer.MIN_VALUE);


Float.MAX_VALUE:3.4028235E38
Integer.MAX_VALUE:2147483647
Integer.MIN_VALUE:-2147483648

java虚拟机规范中明确提到,int类型用4个字节32位表示,出去最高位符号位,剩下的都是数据本身

同样是32位,为什么float能表示的数据范围比int的大?_java

 如果float还用int类型一样的表示方式,那它不可能比int的范围更大,至少小数点还要占去一位呢。

同样是32位,为什么float能表示的数据范围比int的大?_java_02

书中提到,浮点类型与​IEEE二进制浮点数算术标准是一致的,我们去查阅一下IEEE 754

IEEE 754_百度百科IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。只有32位模式有强制要求,其他都是选择性的。大部分编程语言都有提供IEEE浮点数格式与算术,但有些将其列为非必需的。例如,IEEE 754问世之前就有的C语言,有包括IEEE算术,但不算作强制要求(C语言的float通常是指IEEE单精确度,而dohttps://baike.baidu.com/item/IEEE%20754/3869922?fr=aladdin

float的表示方法与int根本就不是一个套路,它其实是借鉴了科学计数法,将float的二级制表示为

同样是32位,为什么float能表示的数据范围比int的大?_浮点数_03

的形式,因为a 只能取1,所以可以节省一位,最终形式为

同样是32位,为什么float能表示的数据范围比int的大?_经验分享_04

然后稍作约定:

同样是32位,为什么float能表示的数据范围比int的大?_后端_05

 

同样是32位,为什么float能表示的数据范围比int的大?_java_06

同样是32位,为什么float能表示的数据范围比int的大?_经验分享_07

 最大的规约数:±1.11111(23个1)*2^127≈2^128,即3.4028235E38;

也就是最大值为3.4028235E38,最小值为-3.4028235E38。

注:java虚拟机规范注明,单精度浮点数指数范围在-126-127,双精度指数范围在-1022到1023 

同样是32位,为什么float能表示的数据范围比int的大?_浮点数_08

这里很多人会有疑惑,8个字节的能表示的范围是±2^7(最高位做符号位),也就是±128,为什么单精度浮点数的指数范围却是-126~127呢?

我是在《计算机组成原理》一书中解开迷惑的

同样是32位,为什么float能表示的数据范围比int的大?_浮点数_09

 按照IEEE754标准规定,浮点数的表示方式如下

同样是32位,为什么float能表示的数据范围比int的大?_后端_10

 中间的8位数阶码是无符号数,原本它的范围是0~2^8,即0~256

IEEE754规定只取1~254最为阶码的取值范围,255和0用于表示特殊值。

阶码与实际指数之间满足如下关系:阶码=127+实际指数值

所以实际指数的范围就是1-127~254-127,即-126~127

同样是32位,为什么float能表示的数据范围比int的大?_java_11

 阶码E取值 255和0时,解释如下

同样是32位,为什么float能表示的数据范围比int的大?_浮点数_12