BigDecimal初始化不要用double类型
在进行单价、总价相关的计算时,就会用到BigDecimal。
在初始化时,一个不小心,就可能给自己挖坑。
示例如下:
public class BigDecimalInitTest {
public static void main(String[] args) {
BigDecimal amount1=new BigDecimal("0.06");
BigDecimal amount2=new BigDecimal(0.06);
System.out.println(amount1);
System.out.println(amount2);
}
}
运行之后,结果为:
0.06
0.059999999999999997779553950749686919152736663818359375
源码注释
打开BigDecimal的构造方法,可以发现:
/**
* Translates a {@code double} into a {@code BigDecimal} which
* is the exact decimal representation of the {@code double}'s
* binary floating-point value. The scale of the returned
* {@code BigDecimal} is the smallest value such that
* <tt>(10<sup>scale</sup> × val)</tt> is an integer.
* <p>
* <b>Notes:</b>
* <ol>
* <li>
* The results of this constructor can be somewhat unpredictable.
* One might assume that writing {@code new BigDecimal(0.1)} in
* Java creates a {@code BigDecimal} which is exactly equal to
* 0.1 (an unscaled value of 1, with a scale of 1), but it is
* actually equal to
* 0.1000000000000000055511151231257827021181583404541015625.
* This is because 0.1 cannot be represented exactly as a
* {@code double} (or, for that matter, as a binary fraction of
* any finite length). Thus, the value that is being passed
* <i>in</i> to the constructor is not exactly equal to 0.1,
* appearances notwithstanding.
*
* <li>
* The {@code String} constructor, on the other hand, is
* perfectly predictable: writing {@code new BigDecimal("0.1")}
* creates a {@code BigDecimal} which is <i>exactly</i> equal to
* 0.1, as one would expect. Therefore, it is generally
* recommended that the {@linkplain #BigDecimal(String)
* <tt>String</tt> constructor} be used in preference to this one.
*
* <li>
* When a {@code double} must be used as a source for a
* {@code BigDecimal}, note that this constructor provides an
* exact conversion; it does not give the same result as
* converting the {@code double} to a {@code String} using the
* {@link Double#toString(double)} method and then using the
* {@link #BigDecimal(String)} constructor. To get that result,
* use the {@code static} {@link #valueOf(double)} method.
* </ol>
*
* @param val {@code double} value to be converted to
* {@code BigDecimal}.
* @throws NumberFormatException if {@code val} is infinite or NaN.
*/
public BigDecimal(double val) {
this(val,MathContext.UNLIMITED);
}
大体意思就是,BigDecimal(double val)这个构造方法有时是无法精确预料的,
传入0.1,有可能变成0.1000000000000000055511151231257827021181583404541015625。
因为double类型无法精确地存储0.1
IDEA编码提示
IDEA也会在编码时给出提示。

结论
通过double类型初始化的BigDecimal类型,是不精确的。
最好用String类型的数值字符串来初始化。
BigDecimal初始化不要用double类型的更多相关文章
- Java:利用BigDecimal类巧妙处理Double类型精度丢失
目录 本篇要点 经典问题:浮点数精度丢失 十进制整数如何转化为二进制整数? 十进制小数如何转化为二进制数? 如何用BigDecimal解决double精度问题? new BigDecimal(doub ...
- 关于BigDecimal 和 double 类型保存金钱,以及精度问题,银行家舍入法
1. BigDecimal 类型数据 的创建,构造函数 有 public BigDecimal(BigInteger intVal, long val, int scale, int prec); p ...
- java中如何使用BigDecimal使得Double类型保留两位有效数字
一.场景:从数据表中读出Decimal类型的数据直接塞给Double类型的对象时,并不会有什么异常. 如果要再此基础上计算,就会发生异常. 比如:读出数据为0.0092,将其乘以100,则变成了0.9 ...
- java 整型数据转换为小数类型 BigDecimal 装换为Double
A,B为String类型 ,A-B=C BigDecimal A=(BigDecimal) map.get("A"); BigDecimal B=(BigDecimal) map. ...
- 关于java中Double类型的运算精度问题
标题 在Java中实现浮点数的精确计算 AYellow(原作) 修改 关键字 Java 浮点数 精确计算 问题的提出:如果我们编译运行下面这个程序会看到什么?publi ...
- java double类型保留两位小数4种方法【转】
4种方法,都是四舍五入,例: import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberF ...
- Double 类型运算时的精度问题
double 类型运算时的 计算的精度不高,常常会出现0.999999999999999这种情况,那么就须要用BigDecimal 它是java提供的用来高精度计算的工具类 以下是对这个类的一个包 ...
- Java中double类型的数据精确到小数点后两位
Java中double类型的数据精确到小数点后两位 多余位四舍五入,四种方法 一: double f = 111231.5585;BigDecimal b = new BigDecimal(f); d ...
- 不要在精确计算中使用float和double类型
http://blog.csdn.net/androiddevelop/article/details/8478879 一 问题描述 float和double类型不能用于精确计算,其主要目的是为了科 ...
随机推荐
- 前端1-----A标签 (锚点)
Title 头部,顶端, 点击跳转到id='abc' 1 2 到百度这里,点击跳转百度 3 到这里了 4 alex1 5 6 根据id 从底部到头 根据id='a1' 到指定位置 ...
- kylin Build过程问题排查:17 Step Name: Build Cube In-Mem
Kylin Build执行到底17步时报错:17 Step Name: Build Cube In-Mem ,错误截图如下: 点左下角的MRJob图标,打开查看错误信息: 从MRJob中的描述中可见 ...
- 基于OpenGL的三维曲面动态显示实现
在使用Visual C++的MFC AppWizard建立应用程序框架后,生成了多个类,与OpenGL编程相关的类是视图类,主要的显示任务都在其中完成. 1.基于OpenGL绘图的基本设置 1.1 设 ...
- 关于DataX
1. 关于DataX 1.1. 前言 为什么写这篇文章,因为初出茅庐的时候,曾经遇到的一个面试官就是DataX的作者之一,而当时我还偏偏因为业务需求做了个数据库的同步工具,我当时不知道他做过这么专业的 ...
- Qt使用QPainter绘制矢量图并保存为svg文件
位图和矢量图: Bitmap: Usually a larger file size Cannot be enlarged into a higher resolution as the image ...
- java并发值多线程同步业务场景以及解决方案
1.20个人排队同时访问2个购票窗口,同时能购票的只有两个人,当其中一个人买票完成后,18个人中的其中一个在占用窗口进行购买. 20个人相当于20个线程,2相当于资源,当18个人等待的时候,相当于线程 ...
- iview 多选下拉列表选项回显问题
如,简单的多选Select, <Select v-model="model" filterable clearable transfer multiple > < ...
- Oracle数据库中 =:和 :=
=:应该相当于 a = :b 表明b是个绑定变量,需要执行时进行变量绑定. 变量绑定:变量绑定是指在sql语句的条件中使用变量而不是常量.比如shared pool里有两条sql语句,select * ...
- 基于TCP协议的大文件传输(粘包问题处理)
基于TCP的大文件上传服务端实现 # 服务端 # -*- coding: utf-8 -*- from socket import * import json, struct server = soc ...
- mysql免安装版配置和一些常见问题
博客原文点我 今天在Windows Server 2003下安装mysql,遇到不少问题.之前在另外两台服务器安装的时候也遇到了几个问题,最后找到不少文章解决了,记录一下. 所有版本都是免安装的32和 ...