Java中浮点数的表示方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/endlessseaofcrow/article/details/81269079

Java中浮点数的表示方法

1.计算机中的表示方法

w8TRi.png

对于float来说,4个字节,32位,0-22位表示尾数,23-30(8位)表示指数,31位表示符号位。

对于double来说,8个字节,64位,0-51表示尾数,52-62(11位)表示指数,63位最高位表示符号位。

2.具体分析表示方法

以一道例题开始

public static void main(String[] args) {
    float f1=20f;
    float f2=20.3f;
    float f3=20.5f;

    double d1=20;
    double d2=20.3;
    double d3=20.5;

    System.out.println(f1==d1);
    System.out.println(f2==d2);
    System.out.println(f3==d3);
}
true
false
true

20:

表示如下:注意,指数位要移位存储,即float+127(2^7-1),double+1023(2^10-1)

f:0|1000 0011|0100 0000 0000 0000 0000 000
d:0|100 0000 0011|0100 0000(01后面50个0)

比较的时候是以符号位,指数位,小数位分别比较的,不足的地方以0补齐,所以相等,

符号位均为0;

指数位float减去127,并在前面补0,double减去1023;

尾数位,float末尾补0

所以相等。

20.3

1.十进制数转化为二进制数

如何将十进制转换成二进制浮点数呢, 先介绍一下十进制的浮点数 转换二进制的浮点数,分为两部分:

  1. 先将整数部分转换为二进制,
  2. 将小数部分转换为二进制, 然后将整数部分与小数部分相加。

以 20.3 转换为例,

20转换后变为 10100

0.3 要转换二进制,需要乘2, 乘完之后 取整数部分,然后用乘的结果减去整数部分, 然后 接着乘2, 直至最后没有小数或者小数出现循环, 即乘完.

20 = 10100 (二进制)

0.3 * 2= 0.6 (0)

0.6 * 2 = 1.2 (1)

0.2 * 2= 0.4 (0)

0.4 * 2 = 0.8 (0)

0.8 *2 = 1.6 (1)

计算到这里, 将再出现0.6,进入循环了,所以,结果

0.3 = 0.010011001…1001

所以20.3 = 10100.010011001…1001 (二进制).

2.二进制数转化为科学计数法

20.3 = 10100.010011001…1001 (二进制)=1.01000100110011E10…..(十进制科学计数)=1.01000100110011E100…..(二进制科学计数)

这里使用移位存储,对于float来说,指数位加上127,double位加上1023(这里指的是存储,在比较的时候要分别减去127和1023)

小结

  1. 同时要注意一点,以float为例,最高位表示的是整个数的符号位,指数位一共8位,最高位表示的是指数位的正负,因为有可能是E-100这样的情况,所以虽然有8位,最高位只是符号位,剩下7位才是表示真正的数值,这也是使用移位存储的原因。

  2. 对于一个数字,只要不超过和float的范围,同时小数部分不是无限小数,就可以和对应的double类型相等。

3.移位存储

移位存储本质上是为了保证+0和-0的一致性。

以float指数部分的这8位来分析,

那么这8位组成的新的字节,我们来用下面的一串数字表示:0000 0000

首先,我们假设不使用移位存储技术,而是单单看看这个 8位组成的新字节,到底能表示多少个数: 0000 0000 -1111 1111 即0-255,一共256个数。

但是我们知道这8位数既要表示正数也要表示负数

所以将左边第一位拿出来表示正负的符号:

第一个区间:

0 000 0000-0 111 1111 
即+0 到127

第二个区间:

1 000 0000-1 111 1111
即 -0到-127

这就是问题的所在:怎么会有两个0,一个正零,一个负零。

这时候使用移位存储:float使用127(0011 1111)

  • 表示0 0+127=127 即 0000 0000 +0111 1111=0111 1111
  • 表示1 1+127=128 即 0000 0001 +0111 1111=0111 1111
  • 表示128 128+127=255 即 1000 0000+0111 1111=1111 1111

最大的正数,再大就要溢出了。

  • 表示-1 -1+127=126=127-1 即 0111 1111-0000 0001=0111 1110
  • 表示-1 -2+127=125=127-2 即 0111 1111-0000 0010=0111 1101
  • 表示-127 -127+127=0 即0111 1111-0111 1111=0000 0000

最小的负数,在校就溢出了。

小结

由上面的 6个例子,我们可以得出规律,采用移位存储技术,我们可以使用 8位二进制来表示从 -127~128 共计 127个负数+零(0)+128个正数总共 256个数,看来使用移位存储即没有+0和-0的问题,又充分的使用这个新生成的 8位二进制数来最大限度的表示单精度浮点数,是非常合理的,只是这里大家需要注意,在使用移位存储技术时,得到的两个区间:

0 000000 0~ 0 111111 1

这里不严谨的称之为 0区间,在0区间内表示 -127~0 ,0包含在此区间。

0 000000 0表示的是 -127 而不是0,

0 111 111 1表示的是0 而不是 +127,

1 000000 0~ 1 111111 1

这里我们称之为 1区间,在1区间内表示的是 1~128

猜你喜欢

转载自blog.csdn.net/endlessseaofcrow/article/details/81269079