Java中的浮点数

浮点数是采用科学计数法来表示的,由符合位、有效数字位、指数三部分组成。

科学计数法

-3.14*105,- 是符号位,3.14是有效数字,5是指数。科学计数法来的有效数字为从第1个非零数字开始的全部数字,指数决定小数点的位置,符号表示该数的正负。

浮点数表示

IEEE754标准规定了4种浮点数类型:单精度、双精度、延伸单精度、延伸双精度。这里主要讲解单精度和双精度。
在这里插入图片描述这里需要注意,浮点数无法精确表示0值,所以取值范围有正负两个区间。下面以单精度为例,占4字节,共32位,具体格式如下:
在这里插入图片描述指数称为“阶码”,有效数字称为“尾数”,用于存储符号、阶码、尾数的二进制位分别称为符号位、阶码位、尾数位。

  1. 符号位
      在最高二进制位上分配1位表示浮点数的符号,0表示正数,1表示负数。
  2. 阶码位
      在符号位右侧分配8位用来存储指数,IEEE754标准规定阶码位存储的是指数对应的移码,即[x]=x+(2n-1-1)(n为x的二进制位数,含符号位)。移码的几何意义是把真值映射到一个正数域,其特点是可以直观地反应两个真值的大小,移码大的真值也大,这样计算机比较阶码大小就更加简单。
      为什么偏移值是(2n-1-1)呢,因为8位二进制数表示的取值范围是[-128,127],将阶码偏移128(27)变为移码后,范围区间为[0,255],但由于计算机规定阶码全为0或全为1是特殊值(全0被认为是机器零,全1被认为是无穷大),除去这两个值,移码范围变为[1,254]。根据[x]=x+128,则x(阶码)范围[-127,126],阶码最大只能取到126,这样就会缩小浮点数表示范围。所以偏移值再多减1,即[x]=x+128-1,阶码表示范围[-126,127],最大值能取到127,表示范围变大。所以IEEE754标准规定单精度的阶码偏移量为(2n-1-1)。
  3. 尾数位
      最右侧分配连续23位用来存储有效数字,IEEE754标准规定尾数以原码表示。我们知道有效数字是一个在[1,10)的范围,所以在二进制表示中,有效数字第一位一定是1,也就是说,二进制规格化尾数形式为1.xxxxxx。为了节约存储空间,将符合规格化尾数的首个1省略,所以23位尾数实际表示的是24位二进制数。
    在这里插入图片描述

加减运算

浮点数加减运算5大步骤。

  1. 零值检测。
    检查参加运算的浮点数中是否存在0(0在浮点数中是一种规定,即阶码和尾数全为0),因为浮点数运算比较复杂,如果其中一个数为0,可以直接得出结果。
  2. 对阶操作。
    通过比较阶码大小判断小数点位置是否对齐。阶码不等时,则小数点没有对齐,需要通过移动尾数改变阶码大小使二者相等,这便是对阶。尾数右移1位,则阶码值加1,反之减1。如果左移,则高位被移出,造成的误差更大,所以IEEE754规定对阶的移动方向为向右。这里可以看出,采用移码能方便的比较阶码大小。
  3. 尾数求和。
    对阶完成后,直接按位相加即可完成求和(负数则先转为补码再进行运算)。
  4. 结果规格化。
    如果运算结果满足规格化形式则无需处理,否则需要通过尾数位的向左或向右移动来调整。尾数右移称为右规,反之左规。
  5. 结果舍入。
    在对阶或右规时,尾数需要右移,最右端被移出的位会被丢弃,从而导致结果精度的损失。为了减少这种精度损失,先将移出的这部分数据保存起来,称为保护位,等规格化后再根据保护位进行舍入处理。

浮点数使用

在使用浮点数时推荐使用双精度,使用单精度由于存储位数限制导致计算时有微小差异。Java中浮点数默认是double型。

float f1 = 0.9f;
double d1 = 0.9;
System.out.println(f1/1.0);
System.out.println(d1/1.0);

结果:
在这里插入图片描述
所以在要求精度表示的业务场景下,比如金融行业的货币表示,推荐使用整型存储其最小单位的值。在要求精确表示小数点n位的业务场景下,比如圆周率要求存储小数点后1000位数字,用双精度浮点数也无法做到,所以这时用整型数组保存小数部分。在比较浮点数时,由于存在误差,往往会出现意外情况,所以不要用浮点数比较是否相等来控制代码流程。在数据库中保存小数时,推荐使用decimal类型,不要用float和double。因为后两者存储时存在精度损失问题。
总结:在使用浮点数时,需要慎重考虑,因为某些数不能用浮点数精确表示。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值