Java浮点数为什么精度会丢失

发表于:2010-7-21 11:06

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

#
java

  由于对float或double 的使用不当,可能会出现精度丢失的问题。问题大概情况可以通过如下代码理解:

  Java代码

public class FloatDoubleTest {
  public static void main(String[] args) {
    float f = 20014999;
    double d = f;
    double d2 = 20014999;
    System.out.println("f=" + f);
    System.out.println("d=" + d);
    System.out.println("d2=" + d2);
  }
}

  得到的结果如下:

  f=2.0015E7
  d=2.0015E7
  d2=2.0014999E7

  从输出结果可以看出double 可以正确的表示20014999 ,而float 没有办法表示20014999 ,得到的只是一个近似值。这样的结果很让人讶异。20014999 这么小的数字在float下没办法表示。带着这个问题,一起学习一下浮点数,做个简单分享,希望有助于大家对java 浮点数的理解。

  1.关于 java 的 float 和 double 的表示法

  Java 语言支持两种基本的浮点类型: float 和 double。java 的浮点类型都依据 IEEE 754 标准。IEEE 754 定义了32 位和 64 位双精度两种浮点二进制小数标准。

  IEEE 754 用科学记数法以底数为 2 的小数来表示浮点数。

  对于32 位浮点数float用 第1 位表示数字的符号,用第2至9位来表示指数,用 最后23 位来表示尾数,即小数部分。

  float(32位):

  对于64 位双精度浮点数,用 第1 位表示数字的符号,用 11 位表示指数,52 位表示尾数。

  double(64位):

  都是分为三个部分:

  (1) 一个单独的符号位s 直接编码符号s 。
  (2)k 位的幂指数E ,移码表示 。
  (3)n 位的小数,原码表示 。

  2. 什么时候会出现无法表示?

  任何一个数字,在java底层表示都必须转换成这种科学计数法来表示,那么我们来想想看什么时候这个数字会无法表示呢?那么只有两种情形:

  1.幂数不够表示了:这种情况往往出现在数字太大了,超过幂数所能承受的范围,那么这个数字就无法表示了。如幂数最大只能是10,但是这个数字用科学计数法表示时,幂数一定会超过10,就没办法了。

  2.尾数不够表示了:这种情况往往出现在数字精度太长了,如1.3434343233332这样的数字,虽然很小,还不超过2,这种情况下幂数完全满足要求,但是尾数已经不能表示出来了这么长的精度。

  3.  20014999 为什么用 float 没有办法正确表示?

  通过以上分析,应该已经知道,这个数字不大,转换成IEEE754科学计数法之后幂数一定是满足要求的,只是尾数不能表示这么精确的数字了。

  结合 float和double的表示方法,通过分析 20014999 的二进制表示就可以知道答案了。

  以下程序可以得出 20014999 在 double 和 float 下的二进制表示方式。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号