java double float_java Float和Double类型详解

一、小数是如何在计算机中存储的?

Java 有四种整数类型,int,byte,short,long,小数有两种类型,float,double,那小数是怎么表示的呢?

78.375 的整数部分:

()

小数部分:

所以,78.375的二进制形式就是1001110.011

然后,使用二进制科学记数法,有

()()

注意,转换后用二进制科学记数法表示的这个数,有底有指数有小数部分,这个就叫做浮点数

二、浮点数在计算机中的存储

按照 IEEE 制定的浮点数表示法来进行 float,double 运算。这种结构是一种科学计数法:用符号、指数和尾数来表示。指数可正可负,所以,IEEE 规定,此处算出的次方必须减去 127 才是真正的指数。底数定为 2,即把一个浮点数表示为尾数乘以 2 的指数次方再添上符号。

在计算机中,保存这个数使用的是浮点表示法,分为三大部分:

第一部分用来存储符号位(sign),用来区分正负数,这里是 0,表示正数

第二部分用来存储指数(exponent),这里的指数是十进制的 6

第三部分用来存储小数(fraction),这里的小数部分是 001110011

a33f4c1449d54d1554e8bcab866b31dd.pngfloat位格式

cef0531c0aa765675fbf4996efec5498.pngdouble位格式

对应格式如下:

类型

符号位

指数

尾数

长度

float

1

8

23

32

double

1

11

52

64

以 float 为例:

格式:

SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM

S表示浮点数正负

E表示指数加上 127 的值后得到的二进制数据

M表示尾数,最高位固定为 1

举例:

78.375 在内存中的存储为:

上面我们已经算出,二进制表示为:1.001110011*26

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

指数:一共 6 位,所以指数为 6+127,所以为 133,二进制为:1000 0101

底数:因为小数点前必为 1,所以 IEEE 规定只记录小数点后的就好。所以,此处的底数为:001110011,不足部分补 0

所以内存中 78.385 表示为:

0100 0010 1001 1100 1100 0000 0000 0000

三、浮点型为啥不精确?

be5f6e1516e95092a6b4a0c2b96ee8b2.png

从图中可以看到,对于二进制小数,小数点右边能表达的值是 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 … 1/(2^n)

现在问题来了, 计算机只能用这些个 1/(2^n) 之和来表达十进制的小数。

按照上面说的 float 的格式,我们来表示一下十进制的 0.2 呢

0.01 = 1/4 = 0.25 ,太大

0.001 =1/8 = 0.125 , 又太小

0.0011 = 1/8 + 1/16 = 0.1875 , 逼近 0.2 了

0.00111 = 1/8 + 1/16 + 1/32 = 0.21875 , 又大了

0.001101 = 1/8+ 1/16 + 1/64 = 0.203125 还是大

0.0011001 = 1/8 + 1/16 + 1/128 = 0.1953125 这结果不错

0.00110011 = 1/8+1/16+1/128+1/256 = 0.19921875

精度(有效数字)主要看尾数位:

float 的尾数位是 23bit,对应 7~8 位十进制数,所以有效数字有的编译器是 7 位,也有的是 8 位

float 为 4 个字节,表示为:一个符号位,8 个指数位,23 个尾数,所以有效位数由尾数来决定,即 2^23=8388608 为 7 位,指数的范围是 2^(-127~127)

参考资料

[1]

https://blog.csdn.net/tianmd_Eric/article/details/79729827: https://blog.csdn.net/tianmd_Eric/article/details/79729827

[2]

https://www.cnblogs.com/Java-Script/p/11123897.html: https://www.cnblogs.com/Java-Script/p/11123897.html

[3]

https://blog.csdn.net/zhuxuyue/article/details/90293299: https://blog.csdn.net/zhuxuyue/article/details/90293299

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值