zoukankan      html  css  js  c++  java
  • 不能使用 float 和 double 来表示金额等精确的值

    不能使用 float 和 double 来表示金额等精确的值

    关于面试,金额用什么数据类型?

    不是 doube,更不是 float ,而是用 BigDecimal。对于金融项目,对于金额,误差是不能容忍的。那么用什么数据类型才能精确的表示金额?JDK 提供了一个 java.math.BigDecimal 的类,这个类可以表示任意精度的数字。

    Java 中 float 的精度为 6-7 位有效数字。double 的精度为 15-16 位,BigDecimal 用来对超过16位有效位的数进行精确的运算

    更多:百度百科 | BigDecimal

    关于 float 和 double 的精度

    float:2^23 = 8388608,一共七位尾数,这意味着最多能有 7 位有效数字,但绝对能保证的为6位,也即 float 的精度为 6~7 位有效数字;

    double:2^52 = 4503599627370496,一共 16 位,同理,double 的精度为15~16位。

    顺带看另一个问题:
    float 不是 4 个字节 32 位吗?为啥最大值是 2128-1(3.40E+38)呢?

    这和计算机数据存储有关,浮点数在计算机中是按科学计数法来存储的,其中 1 位符号位,8 位指数,23 位尾数。

    问题一、出现的计算金额不准确,丢失精度:

    看:

    public class Test {
    
        public static void main(String[] args) {
    
            double d1 = 11000;
            double d2 = 0.35;
            // 错误的:3849.9999999999995
            System.out.println("错误的:" + d1 * d2);
    
            BigDecimal bigDecimal1 = new BigDecimal(11000);
            BigDecimal bigDecimal2 = BigDecimal.valueOf(0.35);
            // multiply 乘法;正确的:3850.00
            System.out.println("正确的:" + bigDecimal1.multiply(bigDecimal2));
            
        }
    }
    

    问题二、数据类型转换时会有问题

    public class Test {
    
        public static void main(String[] args) {
            long longMaxVal = Long.MAX_VALUE;
            double doubleVal = longMaxVal / 1.0;
            double clone = doubleVal;
    
            // 参考 Alibaba 《码出高效》, 两浮点数之差小于 diff 任务相等比较改进
            float diff = 1e-6f;
    
            System.out.println(doubleVal);
            clone += 1000;
            System.out.println(clone);
    
            if (Math.abs(clone - doubleVal) < diff) {
                // do
                System.out.println("两数相等");
            } else {
                System.out.println("两数不相等");
            }
        }
    }
    
    
  • 相关阅读:
    tensorboard的log查看方法
    liunx系统中安装lua以及torch
    maven安装问题解决
    使用git将代码上传到GitHub
    解决引入keras后出现的Using TensorFlow backend的错误
    ubuntu下 pycharm使用andcoda下的tensorflow
    HTTP概览
    c++容器
    C++注意
    Strint类成员
  • 原文地址:https://www.cnblogs.com/xpwi/p/11367890.html
Copyright © 2011-2022 走看看