java中float与double精度问题

一、float与double介绍

我们使用数据的时候都是使用十进制的方式进行运算,然而在计算机中数据存储都是使用二进制的方式。 我们通过使用十进制进行小数点存储运算时,数据是可以精准展示,但是在进行二进制转换后得出的数据因精度问题就不能精确展示。

1、float与double的区别

  1. 在内存中占有的字节数不同 单精度浮点数在机内占4个字节,32位,首位表示符号,8位表示阶数k,剩下表示尾数部分。 双精度浮点数在机内占8个字节,64位,首位表示符号,11位表示阶数k,剩下表示尾数部分。
  2. 有效数字位数不同 单精度浮点数有效数字8位 双精度浮点数有效数字16位
  3. 所能表示数的范围不同 单精度浮点的表示范围:-(2-2-23) * 2127 到(2-2-23) * 2127 双精度浮点的表示范围:-(2-252)* 21024到(2-2-52) * 21024

2、float数据存储规则

  1. float共占四个字节,64bit,1bit为符号位,8bit为指数位,23bit为尾数位
  2. 第1个bit为符号位,0表示正数,1表示负数
  3. 第2-9个bit为指数位,表示范围为(0-255),使用补码需要减去127,取值范围为(-127到128),二进制全0与全1有特殊含义,最终取值范围为(-126到127)
  4. 第10到32bit为尾数,float类型的精度有此处决定,在规格化表示时,前导有个默认值1,因此可以表示24位
  5. 规格化表示:指数位数值为-126到127之间,数据范围为-2127到2127
  6. 非规格化表示:当指数部分全0而且小数部分不全0时表示的是非规格化的浮点数,因为这里默认没有前导1,而是0,指数全为0表示2-126,加上尾数可以表示最小的数为2-149
  7. 特殊情况: A、当指数部分和小数部分全为0时,表示0值,有+0和-0之分(符号位决定),0x00000000表示正0,0x80000000表示负0. B、指数部分全1,小数部分全0时,表示无穷大,有正无穷和负无穷,0x7f800000表示正无穷,0xff800000表示负无穷. C、指数部分全1,小数部分不全0时,表示NaN,分为QNaN和SNaN,Java中都是NaN

3、小数的十进制与二进制表示

十进制表示方式:4.567=4 * 100 + 5 * 10-1 + 6 * 10-2 + 7 * 10-3 二进制表示方式:10.5=1 * 23 + 1 * 21 + 1 * 2-1 float与double引起精度问题,考虑是不同进制下数据转化存在转化不完整导致,如果需要在商业系统中计算价钱,最好使用BigDecimal类

经验分享 程序员 微信小程序 职场和发展