浮点数的存储结构
1、float 和 double 的区别
-
在 Java 语言中,
float类型数字在计算机中用4个字节【32 bit】来存储,而double类型数字则占用8个字节【64 bit】 -
从存储结构和算法上来讲,double和float是一样的,不一样的地方仅仅是float是32位的,double是64位的,所以double能存储更高的精度
2、浮点数表示法
按照IEEE制定的浮点数表示法来进行float,double运算,这种结构是一种科学计数法:
-
用符号、指数和尾数来表示
-
指数可正可负,所以,IEEE规定,此处算出的次方必须减去127才是真正的指数
-
底数定为2,即把一个浮点数表示为尾数乘以2的指数次方再添上符号
具体表示规则:
| 类型 | 符号位 | 指数 | 尾数 | 长度 |
|---|---|---|---|---|
| float | 1 | 8 | 23 | 32 |
| double | 1 | 11 | 52 | 64 |
单位:bit
以 float 进行说明,因为指数需要减去127,所以 float 类型的指数可从 -126~128
运用科学计数法,格式为:
S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM
其中,S表示浮点数的正负,E表示指数加上127的值后转化得到的二进制数据,M表示尾数,最高位固定为1
3.14是double型,3.14f是float型
3、简单举例
十进制数 (17.625)₁₀ 在内存中的存储为:
-
首先,将十进制数 (17.625)₁₀ 换算成二进制数 (10001.101)₂
换算步骤:将 17.62拆分成两部分:整数部分和小数部分。
-
整数部分:利用模2取余法,即除以2,直到商为0,余数反转
17 % 2 = 8 ---------> 余1 (低位)
8 % 2 = 4 ----------> 余0
4 % 2 = 2 -----------> 余0
2 % 2 = 1 -----------> 余0
1 % 2 = 0 ------------> 余1 (高位)
即:整数部分为 10001
-
小数部分:利用乘2取整法,即乘以2,直到乘位为0,进位顺序取
0.625 * 2 = 1.25 ------> 取整为1 (低位)
0.25 * 2 = 0.5 -----> 取整为0
0.5 * 2 = 1.0 -----> 取整为1
0.0 * 2 = 0.0 -----> 取整为0 (高位)
即:小数部分为 0.101
注意,小数的高位是指离小数点近的位置,反之小数的低位则是离小数点远的位置
因此,整数部分 + 小数部分 = 10001 + 0.101 = 10001.101
-
-
再将二进制数 (10001.101)₂的小数点进行左移,换算成科学计数法形式为:
1.0001101 * 2⁴ (注意,此处为二进制的科学计数法)
此时,底数、指数就显而易见
符号:因为是正数,所以符号位取0
底数:因为小数点前必为1,所以IEEE规定只记录小数点后的就好。所以,此处的底数为:0001101
指数:实际为4,必须加上127(转出的时候,减去127),所以为131。转换成二进制数也就是10000011
-
综上所述,17.625 在内存中的存储格式是:0 10000011 00011010000000000000000
4、在java强制转换中的运用
public class Test4 {
public static void main( String[] args ) {
// 输出为 12345678(float为单精度浮点数,精度为8位有效数字)
float first = 12345678 ;
System.out.println( first );
// 输出为 1234567.89(double为双精度类型,精度为16位有效数字)
double second =1234567.89 ;
System.out.println( second );
// 输出为 1234567(double -----> int 保留整数部分,舍弃小数部分)
int third = (int) second ;
System.out.println( third );
// 输出为 -10617 (double -----> short 是 64bit 转换成 16bit)
// 1234567.89(十进制) ----> 1001_0110_1011_0100_0011_1.111_0001_1110_1011_1000_0101_0001_11101(64bit二进制)
// 转换时舍弃小数部分,整数部分从右往左数第16位是1,符号位是1则对应负数,所以确定转换后为负数
// 根据整数强制类型转换舍弃高位、留下低位的原则,转换后即为 -10617
short fourth = (short) second ;
System.out.println( fourth );
}
}
浙公网安备 33010602011771号