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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://icode.blog.csdn.net/article/details/99687726

不能使用 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("两数不相等");
        }
    }
}

展开阅读全文

sql server 2005 float字段不能精确表示

05-20

现用vb, sql server 2005 开发一应用程序rn sql server中 表1的重量字段 类型是 float,有时候不能精确显示rn例如计算的结果是:11.2 实际上数据库中显示的是 11。1999999999999999999999999rnrn程序逻辑如下:rn  1.界面输入重量rn 2.在重量文本框内按下回车,进行重量调整计算,并将计算结果显示到重量文本框中。(重量调整计算是:输入重量保留到小数后两位,即小数三位以后的舍弃)rn 3.重量文本框的值保存到zhongliang变量中(zhongliang变量是string型),将zhongliang的值加到表1的重量字段上。rn sql: " update 表1 set 重量=重量+"& zhongliang rn例如数据库本来重量字段是10,界面输入1.2,计算结果是11.2,但更新过的数据库中显示11。9999999999999rnrn以前在第2步,小数保留两位的计算中,有过类似的错误。rn是string类型的zhongliang用cdbl做类型转换是,出现的,修改成转换为cdec就可以,具体如下rndim zhongliang as string=Me.zhongliang.TextrnMe.zhongliang.Text = CStr(Fix(CDbl(zhongliang) * 100) / 100)rn->rn Me.zhongliang.Text = CStr(Fix(CDec(zhongliang) * 100) / 100)rn现在可以保证第3步中zhongliang=11.2,但是计算后数据库中显示却不对rnrn想请教的是:rn  1.是因为sql语句中,进行加算的zhongliang是string而出错吗?改为decmail型就可以吗?rn 2.是因为sql server 2005 中float类型的字段不能精确表示吗?即使计算结果正确,也有可能发生这种近似表示的例子。这样的话如何修改?rn 3.或许是其他的什么原因?rn请多指教rnrn 论坛

没有更多推荐了,返回首页