<转载>JAVA浮点数二进制详解

作者: zengdongwu

转载地址: http://www.zengdongwu.com/article1.html

十进制科学记数法

98765 = 9.8765 * 104
              尾数        基数指数

二进制科学记数法

1)1010 1011 = 1010 1011. * 20

2)1010 1011 = 1010 101.1 * 21

3)1010 1011 = 1010 10.11 * 210

4)1010 1011 = 1010 1.011 * 211

4)……

5)1010 1011 = 1.010 1011 * 2111

                           尾数              基数指数

小数点二进制科学记数法

101.0 1011(2) = 1.010 1011 * 210(2) = 5.34375(10)

二进制小数转十进制方法:

22 + 20 + 2-2 + 2-4 + 2-5 = 5.34375

十进制小数转二进制方法:

1)5.34375整数位为5,转二进制为101;

2)小数位0.34375 * 2 = 0.6875,整数位为0,结果101.0;

3)继续0.6875 * 2 = 1.375,整数位为1,结果101.01;

4)去掉整数继续乘2,0.375 * 2 = 0.75,结果101.010;

5)循环到没有小数为止……;

6)最终结果:101.01011。

float(32bit)二进制存储结构

0 1000 0001 0101 0110 0000 0000 0000 000
符号位 指数(8bit) 尾数(23bit)

原理说明:

1)第1位为符号位,0为整数,1为负数;

2)第2-9位为指数位,共8位,不足8位前面补0,由于指数没有符号位,不能表示负数,只能通过将结果减127来得到负数,所以指数位存储的结果是原指数加127,即指数2存储后指数为 2+127 = 129(10) = 1000 0001(2);

3)第10-32位为尾数位,共23位,不足23位后面补0,尾数位包含隐藏的1.X,即1.010 1011只存储0101 011,然后后面补0,最终结果为0101 0110 0000 0000 0000 000。

float转十进制方法:

1)符号位0为正数;

2)指数转十进制,1000 0001为129,需要减127,所以指数为129-127=2;

3)尾数去掉后面的0,结果为0101 011;

4)尾数前面加1. 即:1.010 1011;

5)指数为2,小数点往后移2位,即:101.0 1011;

6)转十进制22 + 20 + 2-2 + 2-4 + 2-5 = 5.34375。

代码验证:

  float f = 5.34375f;
  System.out.println(Integer.toBinaryString(Float.floatToIntBits(f)));

采用double(64bit)二进制表示方式

0 0010 0000
001
0101 0110 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000
0000
符号位 指数(11bit) 尾数(52bit)

原理说明:

1)第1位为符号位,0为整数,1为负数;

2)第2-12位为指数位,共11位,不足11位前面补0,由于指数没有符号位,不能表示负数,只能通过将结果减1023来得到负数,所以指数位存储的结果是原指数加1023,即指数2存储后指数为 2+1023 = 1025(10) = 10000000 1(2);

3)第13-64位为尾数位,共52位,不足23位后面补0,尾数位包含隐藏的1.X,即1.0101011只存储0101011,然后后面补0,最终结果为0101 0110 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000。

double转十进制方法:

1)符号位0为正数;

2)指数转十进制,1000 0000 001为1025,需要减1023,所以指数为1025-1023=2;

3)尾数去掉后面的0,结果为0101 011;

4)尾数前面加1. 即:1.010 1011;

5)指数为2,小数点往后移2位,即:101.0 1011;

6)转十进制22 + 20 + 2-2 + 2-4 + 2-5 = 5.34375。

代码验证:

  double d = 5.34375;
  System.out.println(Long.toBinaryString(Double.doubleToLongBits(d)));

PS:double转换方法与float一致,区别在指数位算法有所差异,且尾数大小远远超过了float,因此精度也大大提高,正常情况下浮点数均采用double。

猜你喜欢

转载自200cc.iteye.com/blog/2205487