如何理解IEEE 754标准对Java中float值和double值的规定
Posted chang4
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何理解IEEE 754标准对Java中float值和double值的规定相关的知识,希望对你有一定的参考价值。
在Java语言中,我们可以使用float和double这两种基本数据类型来表示特定的数据。
这两种数据类型,本质上是浮点数(floating-point number),浮点是一种对于实数的近似值数值表现法,由一个有效数字加上幂数来表示。
之所以使用浮点数,是因为计算机在使用二进制运算的过程中,无法将所有的十进制小数准确的换算为二进制,只能使用近似值来表示。
使用浮点数表示数值的方法很多,在Java中,和C语言一样,float和double都采用了使用最为广泛的IEEE 754标准。
IEEE 754标准的全称为IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985),其中ANSI是美国国家标准学会(American National Standards Institute)的缩写,IEEE是电器电子工程师学会(Institute of Electrical and Electronics Engineers)的缩写,754是该标准的编号,1985则是该标准发布的年份。
IEEE 754规定,一个二进制浮点数在存储中由三部分组成:
其中第一部分为符号位(sign bit),第二部分为指数偏移值(exponent bias)用于存储浮点数的指数部分,第三部分为分数(fraction)用于存储浮点数的有效数的小数部分。
以一个具体的float值为例,Java中的float值采用的是IEEE754中的单精度标准,使用32个比特进行存储。例如:
0100 0100 1010 0110 1001 1110 0000 0000
其中:
0100 0100 1010 0110 1001 1110 0111 0100
第一位的0为符号位,它表示这个数的正负值为正,相应的,若第一位为1则表示这是一个负数;
0100 0100 1010 0110 1001 1110 0000 0000
第2~9的8个比特存储的是指数偏移值,用于记录该float值的指数部分,取值范围为-126~+127再加上偏移值127(2的7次方减1),结果就是1~254(0和255留作特殊值)。在本例中,1000 1001在十进制中的值为137,但是137是进行偏移后的结果,减去偏移值127后,其实际代表的指数值就是10。
0100 0100 1010 0110 1001 1110 0000 0000
第10~32的23个比特存储的是该float值的分数/小数部分。010 0110 1001 1110 0000 0000实际上表示的就是二进制的0.010 0110 1001 1110 0000 0000再加上1,也就是1.010 0110 1001 111。这实际上就是二进制的1010 0110 1001 111右移十四位的结果。1010 0110 1001 111在十进制中的值为21327,所以1.010 0110 1001 111也就等于21327*2^(-14)。
综上,例子中的:
0100 0100 1010 0110 1001 1110 0000 0000
实际上也就等于:
+ 21327*2^(-14) * 2^10 = 1332.9375
第一位符号位表示 第10~32的分数位表示 第2~9的指数位表示
反之,例如我们想知道某个float a = 1000在内存中的形式,那么则需要如下操作:
首先,1000是个整数,所以第一个比特位存储的是0。
十进制的100在二进制中为11 1110 1000,这实际上就是1.111101左移9位的结果,
那么实际上指数位存储的结果就应该是9 + 127 = 136也就是1000 1000
分数位存储的则是1.111101减去1的部分,补齐23位,也就是111 1010 0000 0000 0000 0000
综上float a = 1000在内存中的存储为:
0100 0100 0111 1010 0000 0000 0000 0000
另外,前面提到过的,指数偏移值为0或255的时候代表特殊值:
当指数值为0,即0000 0000时,若小数部分为0,则这个数为±0(正负由符号位决定);
当指数值为255,即1111 1111时,若小数部分为零,则这个数为±∞(正负由符号位决定);
当指数值为255,即1111 1111时,若小数部分非零,则这个数表示为不是一个数(Not a Number)。
以上就是float的部分,double同理,只不过double采用IEEE 754双精度标准,使用64个比特存储,其中2~12的11位为指数位,13~64的52位为小数位。
References:
IEEE 754 - wiki
https://zh.wikipedia.org/zh-cn/IEEE_754
浮点数 - wiki
https://zh.wikipedia.org/zh-cn/%E6%B5%AE%E7%82%B9%E6%95%B0
以上是关于如何理解IEEE 754标准对Java中float值和double值的规定的主要内容,如果未能解决你的问题,请参考以下文章