美文网首页Java语言
java基础-浮点数陷阱

java基础-浮点数陷阱

作者: 李2牛 | 来源:发表于2018-02-19 21:20 被阅读26次

计算机的数值采用的是二进制形式存储。
根据IEEE754标准,
单精度浮点数为32位:

- sign exponent fraction
位数 1 bit 8 bit 23 bit
编号(右起) 31 30 ~ 23 22 ~ 0

双精度浮点数为64位:

- sign exponent fraction
位数 1 bit 11 bit 52 bit
编号 63 62 ~ 52 51 ~ 0

0.99用的有效数字部分(fraction):
        0.99 * 2 = 1+0.98 --> 1
        0.98 * 2 = 1+ 0.96 --> 1
        0.96 * 2 = 1+0.92 -- >1
        0.92 * 2 = 1+0.84 -- >1...............

所以计算机二进制无法精确表示浮点数,精度有损失。示例代码如下:

public class FloatTrap {
    public static void main(String[] args) {
        double a = 1;
        double b = 0.99;
        System.out.println(a - b);
    }
}//:output
//0.010000000000000009

java的浮点类型有double(双精度)和float(单精度)。对于精确的浮点数运算可以使用java.math.BigDecimal类,但是这样依然会有精度损失。最佳的方法是使用string转double或者float,这样是没有精度损失的。
使用BigDecimal类示例

import java.math.BigDecimal;

public class Main {

    public static void main(String[] args) {
        double a = 2.0;
        double b = 1.9;
        System.out.println(2.0 - 1.9);
        System.out.println(Main.round(Main.subtract(a,b)));
    }

    /*精确的浮点数计算*/

    private static double subtract(double m, double n){

        BigDecimal tm = new BigDecimal(Double.toString(m));
        BigDecimal tn = new BigDecimal(Double.toString(n));
        return tm.subtract(tn).doubleValue();

    }

    /*四舍五入保留*/
    private static double round(double target){
        BigDecimal tmp = new BigDecimal(Double.toString(target));
        BigDecimal one = new BigDecimal(Double.toString(1.0));

        return tmp.divide(one,BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    private static double div(double tm,double tn){
        BigDecimal tempM = new BigDecimal(Double.toString(tm));
        BigDecimal tempN = new BigDecimal(Double.toString(tn));
        return tempM.divide(tempN,10, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    private static double add(double tm, double tn){
        BigDecimal tempM = new BigDecimal(Double.toString(tm));
        BigDecimal tempN = new BigDecimal(Double.toString(tn));
        return tempM.add(tempN).doubleValue();

    }


}

相关文章

  • java基础-浮点数陷阱

    计算机的数值采用的是二进制形式存储。根据IEEE754标准,单精度浮点数为32位: 双精度浮点数为64位: 0.9...

  • Java基础知识陷阱

    Java浮点数精确运算陷阱 System.out.println(2.0 - 1.1); 以上结果为0.89999...

  • Awesome Java

    基础 Java 入门与实践 Java 语法清单 Java 8 系列之重新认识 HashMap Java 浮点数精确...

  • 浮点数陷阱

    演示代码 大家可以先猜想下结果。 结果 倒数第三行可以看到我强制退出了程序,否则会一直打印。为什么这样呢?0.1累...

  • 浮点数陷阱

    一旦我们越过了Acheron,我们就到达了第一层,这是一个善良的异教徒的家。这些人忽视浮点神,他们相信 是对的。他...

  • 精度解决

    抓住数据的小尾巴 - JS浮点数陷阱及解法[https://zhuanlan.zhihu.com/p/30703042]

  • 由浮点数精度问题引发的思考-BigDecimal与IEEE754

    在夯实Java基础知识,遇到了浮点数精度问题。总结一下。先看个例子: 输出是什么?0.07? 错!输出结果为: 0...

  • JavaScript之0.1+0.2=0.30000000000

    前言:在看了 JavaScript 浮点数陷阱及解法 和 探寻 JavaScript 精度问题 后,发现没有具体详...

  • 编程课周报

    这周编程时间颇多,,我们一般是看那个零基础学java视频学习,然后完成老师布置的作业,这周学的变量,赋值,浮点数还...

  • Java 基础

    Java 基础01Java开发入门 Java 基础02Java编程基础 Java 基础03面向对象 Java 基础...

网友评论

    本文标题:java基础-浮点数陷阱

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