Java 浮点数是如何存储的?

看一个面试题,   考察面试者对浮点数存储格式的理解 :

 

public class Float_Double {

	public static void main(String[] args) {

		float f_v1 = 20;  
		float f_v2 = 20.3f;  
		float f_v3 = 20.5f;  
		      
		double d_v1 = 20;  
		double d_v2 = 20.3;  
		double d_v3 = 20.5;
		
		System.out.println((f_v1 == d_v1)?"true":"false"); 
		System.out.println(f_v2 == d_v2?"true":"false");  
		System.out.println(f_v3 == d_v3?"true":"false");
		
	}
}

运行结果会是怎样的呢?, 解释运行结果的原因

这里涉及到浮点数是如何存储的.

1. 如何将十进制转换成二进制浮点数呢,  先介绍一下十进制的浮点数 转换二进制的浮点数

分为两部分:

1. 先将整数部分转换为二进制,

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

以 20.5 转换为例,

20转换后变为  10100

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

如果等于0, 就取前面不为0的部分. 

0.5 * 2  = 1.0 (取1)

0 * 2 = 0   (0)

所以,  转换后 0.5 = 0.1,

所以 20.5 转换二进制后, 20.5 = 10100.1(二进制)

--------------------------------

再看一个浮点数 20.3

 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.  如果要把十进制浮点数,存储到内存空间中,也就是4个字节中,首先要把浮点数转换成二进制的浮点数, 然后再转换成科学计数法.

这里 20.5 = 10100.1(二进制)  = 1.01001E4(十进制科学计数) = 1.01001E100(二进制科学计数),   这里E100指2的100次方

在java中,float 类型 数,占4个字节, 存储结构如下

                 符号位:   1

                 指数位:   8

                 尾数位:   23,  如下图所示

               double 类型数,  占8个字节, 存储结构如下

                 符号位:1

                 指数位:11

                 尾数位: 52

存储数据是一个萝卜一个坑, 首先存储符号位, 然后是 指数,最后尾数

比如20.5 = 1.01001E100(二进制)

这里使用到移位存储, 对于float 数值来说, 指数位要加上127, 即0111111(二进制)

    00000100

+  01111111

-----------------

    1000 0011

对于double 数值来说, 指数位要加上1023, 即0111 111 1111(二进制)

    0000 000 0100

+  0111 111 1111

------------------------

    1000 000 0011

所以20.5 存储的数值 是 (float):  0-10000011-01001 00000 00000 00000 000

                                      (double):0-10000000011-01001+(47个0)

                                                                                          这里尾数位需要52位

现在看到20.5 转换为float, double 的二进制数, 指数和尾数是不同的,  注意,比较指数时  float 型会-127, double型 会-1023,因此

float 型又变成了00000100

double型又变成0000000100          ,这时候比较,因为两个指数的位数不同,一个8位,一个10位,8位的数会在前面自动补0

比较尾数时,float型数会自动在后面补0直至与double 型相同的52位

同理20.3 存储的数值 是: (float) 0-10000011-01001 10010 10011 00101 001

                                        (double)0-1000000011-01001(后面循环1001,  直至尾数为52位)

 

与20.5的比较相似, 20.3的float型二进制和double型二进制,符号位与指数位都相同,  但是尾数位不相同,float型到了23位之后都是0, double型一直1001循环到52位. 这就是float型与double型比较之后不相等的原因

如果要将三个比较结果  都为true, 需在d_v2加上 (float), 也就是将double强制转为float型

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值