浮点数的存储结构

浮点数的存储结构

 

1、floatdouble 的区别

  • 在 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)₁₀ 在内存中的存储为:

  1. 首先,将十进制数 (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

  2. 再将二进制数 (10001.101)₂的小数点进行左移,换算成科学计数法形式为:

    1.0001101 * 2⁴ (注意,此处为二进制的科学计数法)

    此时,底数、指数就显而易见

    符号:因为是正数,所以符号位取0

    底数:因为小数点前必为1,所以IEEE规定只记录小数点后的就好。所以,此处的底数为:0001101

    指数:实际为4,必须加上127(转出的时候,减去127),所以为131。转换成二进制数也就是10000011

  3. 综上所述,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 );

  }
}

 

posted on 2020-05-15 15:58  晓晓的明星  阅读(1262)  评论(0)    收藏  举报

导航