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

不能使用 float 和 double 来表示金额等精确的值的更多相关文章

  1. decimal,float和double的区别

    http://www.cnblogs.com/yellowapplemylove/archive/2011/08/23/2150316.html 一直很奇怪C#的预定义数据类型中为什么加了一个deci ...

  2. C#中对于float,double,decimal的误解(转载)

    浮点型 Name CTS Type Description Significant Figures Range (approximate) float System.Single 32-bit sin ...

  3. decimal与float和double的区别

    一直很奇怪C#的预定义数据类型中为什么加了一个decimal,有float和double不就够了吗?今天来挖一挖. 浮点型 Name CTS Type De script ion Significan ...

  4. 精确计算java中float和double的精度

    [本文相关的代码放在github上.地址为:https://github.com/VigourJiang/StructuredFloat] Java中double类型的格式基本遵循IEEE 754标准 ...

  5. Sql的decimal、float、double类型的区别

    三者的区别介绍 float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E ...

  6. float和double精度问题

    System.out.println(new BigDecimal(253.90).doubleValue() * 100);25390.0精度正确 System.out.println(new Bi ...

  7. 【转载】 C#中float、double以及decimal类型有何不同

    在C#语言中,float.double以及decimal类型都可以用来表示小数,但三者还是有一定的不同,有效数字为相比的话,decimal类型的有效数字最大,float类型最小.计算浮点类型的运算,如 ...

  8. float和double的精度

    作者: jillzhang 联系方式:jillzhang@126.com 原网址:http://blog.csdn.net/wuna66320/article/details/1691734 1 范围 ...

  9. float和double在内存中的存储方式

    本文转载于:http://wenku.baidu.com/link?url=ARfMiXVHCwCZJcqfA1gfeVkMOj9RkLlR9fIexbgs9gDdV8rIS48A1_xe1y6YgX ...

随机推荐

  1. IntelliJ IDEA入门之常用配置以及问题解决(持续更新中)

    软件版本: IntelliJ IDEA 2019.1.1(Ultimate Edition) 运行环境: JDK1.8, Tomcat8.0, Maven3.6 我们在学习新的无论是jar包, 框架, ...

  2. k8s 工具集

    Volcano 资源调度器 apollo 配置中心 spinnaker 持续部署系统 jaeger 分布式跟踪系统.它用于监视和诊断基于微服务的分布式系统,包括: 分布式上下文传播 分布式交易监控 根 ...

  3. cisco上配置 pppoe拨号

    r1(config)#vpdnenable                      开启虚拟拨号VPDN r1(config)#vpdn-groupoffice                定义组 ...

  4. C学习笔记-运算符

    一些基本概念 数据对象:泛指数据在内存的存储区域 左值:表示可以被更改的数据对象 右值:能赋给左值的量 算数运算符 运算符 描述 实例 + 把两个操作数相加 a + b - 从第一个操作数中减去第二个 ...

  5. 【转帖】Office的光荣历史(1)

    Office的光荣历史(1) https://www.sohu.com/a/201410882_657550 微软的第一版本的office 竟然是 给Mac OS 提供的.. 2017-10-31 1 ...

  6. SQL中的DATENAME()函数

    SQL从时间字段值中获取年份使用DATENAME()函数. DATENAME()函数语法:DATENAME(param,date) date是时间字段名 或一个时间值 param是指定要返回日期部分的 ...

  7. Kudu建表语句

    --建表CREATE TABLE kudu_testdb.perf_test_t1( id string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY, int ...

  8. 搞懂ZooKeeper到底是做啥的

    一.ZooKeeper是啥 ZooKeeper概念 ZooKeeper是一个开源的分布式协调服务(a service for coordinating processes of distributed ...

  9. CF 666C & 牛客 36D

    给定字符串S, 求有多少长为$n$的字符串T, 使得S为T的子序列. 可以得到转移矩阵为 $\begin{equation}A=\begin{bmatrix}25 & 0 & 0 &a ...

  10. .net下载文件的方法

    最近做项目遇到文件下载的问题,原本采用的是直接用一个href链接到需要下载的文件来处理这个问题,后来发现,如果文件是一个图片,浏览器会自动打开图片而不是下载,需要用户右击另存为才可以下载,很不友好,后 ...