java中float和double底层存储原理

  |   6 评论   |   1,025 浏览

​ 我们都知道,在java中,浮点数类型有两个,floatdouble,他们的长度分别是32bit64bit,那么他们在底层存储方式是怎样的呢

​ 查了一些相关文章,了解到大部分语言存储浮点数都是根据IEEE标准,Java也不例外,根据标准,存储位数是由符号指数尾数组成

长度 符号(0正1负) 指数 尾数 指数偏移
float(单精度) 32bit 1bit 8bit 23bit 127
double(双精度) 64bit 1bit 11bit 52bit 1023

假设我们现在存储一个小数6.25,先要把6.25转为二进制小数

  • 整数部分转换:模2取余法

    6%2=0

    3%2=1

    1%2=1

    110

  • 小数部分转换:乘2取整法

    0.25*2=0.5 取0

    0.5*2=1.0 取1

    01

最后转换后为110.01

然后转化为科学计数法:1.1001*2²,即小数点左移2位,因为所有的小数转化后开头都是1(即1.xxxx),所以1为隐藏位,无需存储,最后尾数为1001,指数为2

假设我们用的是float类型,指数需变为129,需要加上127的指数偏移量,最终转化为2进制为10000001,那么最终存储的结果为:01000000 11001000 00000000 00000000

double类型同理,只是位数不同

蓝色为符号,因为是正数所以是0,绿色为指数,红色为尾数

补充:

在我们计算尾数的时候,如果碰到乘2取整法最后乘不尽,那么算到最后一位就停止,剩下的不会存储,这也就是臭名昭著的浮点数精度问题,所以在使用的时候一定要注意,如果对结果有精确要求的还是要使用BigDecimal


作者:wenbo

评论

发表评论


取消