浮点数

作者: SScience | 来源:发表于2017-10-27 11:50 被阅读23次

1,浮点数基本知识

Java 语言支持两种基本的浮点类型: float 和 double ,以及与它们对应的包装类 Float 和 Double 。它们都依据 IEEE 754 标准,该标准定义了32 位单精度和 64 位双精度两种浮点二进制小数标准。

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

  • 32位单精度浮点数float,用 1 位表示数字的符号,用 8 位表示指数,用 23 位表示尾数,即小数部分,如2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字。
  • 64位双精度浮点数double,用1 位表示数字的符号,用 11 位表示指数,用52 位表示尾数,即小数部分,如2^52 = 4503599627370496,一共16位,也即double的精度为15~16位。
  • 作为有符号整数的指数可以有正负之分,也即决定了浮点数的取值范围。小数部分用二进制(底数 2)小数来表示,这意味着最高位对应着值 ?(2 -1),第二位对应着 ?(2 -2),依此类推。

IEEE 浮点值的格式如图 1 所示:

图 1. IEEE 754 浮点数的格式

2,浮点数比较

在java中浮点型默认是double的,浮点数都要在计算机里转换进行二进制存储,这就涉及到数据精度。
例如,十进制小数0.9表示成二进制数为:1100100100100......后面部分将无限循环下去,很显然,小数的二进制表示有时是不可能精确的。比如double类型表示小数部分只有52位,当向后计算52位后基数还不为0,那后面的部分只能通过四舍五入得到一个近似值,此时就造成精度丢失。
所以,当浮点数进行比较时,由于浮点数的二进制表示本身就不准确,比较大小时就会出现错误。例如float f1 = 20014999f == float f2 = 20015000f。

因此,有个原则:

  • 程序中应尽量避免浮点数的比较
  • float、double类型的运算往往都不准确

3,BigDecimal

要想获得理想的结果,应该使用BigDecimal来获得更精确的计算。
在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal

BigDecimal够造方法的参数类型有4种,其中的两个用BigInteger构造,另一个是用double构造,还有一个使用String构造。应该避免使用double构造BigDecimal,因为:有些数字用double根本无法精确表示,传给BigDecimal构造方法时就已经不精确了。
比如,new BigDecimal(0.1)得到的值是0.1000000000000000055511151231257827021181583404541015625。使用new BigDecimal("0.1")得到的值是0.1。因此,如果需要精确计算,用String构造BigDecimal,避免用double构造。

BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,由于创建对象会引起开销,因此它们不适合于大量的数学运算,所以a.add(b);虽然做了加法操作,但是a并没有保存加操作后的值,正确的用法应该是a=a.add(b)。

4,小数点位数保留

  • String s=String.format("%.2f",d),表示保留小数点后任意两位小数,并且符合四舍五入的规则。
  • DecimalFormat df = new DecimalFormat("0.00"),不管传入的任何值,均保留两位小数。
  • DecimalFormat df = new DecimalFormat("#.##"),则保留小数点后面不为0的两位小数,这种写法不能保证保留2为小数,但能保证最后一位数不为0。
  • double d = 1.000;
    BigDecimal bd=new BigDecimal(d);
    double d1=bd.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
    System.out.println(d1);
    输出结果:1.0
    若double d=0,输出结果为0.0;
    若double d=1.999,输出结果为2.0;
    若double d=1.89,输出结果为1.89;
    这种写法若小数点后均为零,则保留一位小数,并且有四舍五入的规则。

参考:
https://www.ibm.com/developerworks/cn/java/j-jtp0114/index.html
http://blog.csdn.net/ccecwg/article/details/22286873
http://www.cnblogs.com/chenfei0801/p/3672177.html
http://www.ituring.com.cn/article/216160
http://swiftlet.net/archives/798
http://www.jianshu.com/p/00fff555986b

相关文章

  • PHP浮点数精度问题

    PHP常见的浮点数“bug” 浮点数的表示形式 浮点数的表示(IEEE 754): 浮点数, 以64位的长度(双精...

  • Python 入门演示

    简单的数学运算 整数相加,得到整数: 浮点数相加,得到浮点数: 整数和浮点数相加,得到浮点数: 变量赋值 Pyth...

  • 6-0. 混合类型数据格式化输入

    本题要求编写程序,顺序读入浮点数1、整数、字符、浮点数2,再按照字符、整数、浮点数1、浮点数2的顺序输出。 输入格...

  • 3_浮点数的秘密

    关键词:内存中的浮点数、浮点数存储示例、十进制浮点数的内存表示、 float类型的不精确示例 1. 内存中的浮点数...

  • python中的数据类型和变量

    浮点数 浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1....

  • Python基础知识点拾遗

    浮点数 系统浮点数信息 1.完整信息 显示结果为: 2.浮点数能表示的最大值 3.浮点数能表示的最近接0的值 4....

  • 1.2 浮点型运算

    在计算机中,浮点数虽然表示的范围大,但是,浮点数有个非常重要的特点,就是浮点数常常无法精确表示。浮点数在内存的表示...

  • 浮点数原理与精度损失问题

    写在前面 碰巧最近定义接口的时候碰到了浮点数精度的问题,稍微整理了浮点数的一些知识点: 浮点数的底层表示 浮点数的...

  • JavaScript 中的数字 Number 易于忽略点

    JavaScript 中的数字 Number 易于忽略点 一、浮点数 1. 浮点数的存储 保存浮点数值需要的内存空...

  • 高级综合工具StratusHLS学习笔记(4)

    HLS中使用浮点数 学习目标: 使用浮点数 换用自己的库进行高级综合 HLS中的浮点数 stratus HLS提供...

网友评论

      本文标题:浮点数

      本文链接:https://www.haomeiwen.com/subject/cbrtpxtx.html