了解到BigInteger类可以存入无限大小的值,从而可以用它进行大数值计算.问题:
BigInteger中的构造方法中的一个参数是没有可以直接接受int,double,等基本数据类型,一个参数是接受String类型.
但是,BigDecimal类是可以接受double,int,long,String类型的值.问题就由此出现了.
import java.math.BigDecimal;
public class BigDecimalDemo {
public static void main(String[] args) {
System.out.println(1.1+1.2101);
BigDecimal bd1 = new BigDecimal(1.1);
BigDecimal bd2 = new BigDecimal(1.2101);
System.out.println(bd1.add(bd2));
}
}
/*输出:
2.3101000000000003
2.3101000000000000422772927777259610593318939208984375
*/
BigDecimal(摘自Java SE8 API文档)
public BigDecimal(double val)Translates a double into a BigDecimal which is the exact decimal representation of the double’s binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer.?文档中说的很明白,对于Decimal中double构造器,该构造器的结果可能有些不可预料.这是因为0.1不能精确地表示为双精度(或者,就此而言,不能表示为任何有限长度的二进制分式)。因此,传递给构造函数的值并不完全等于0.1,尽管看起来是这样。
Notes:
??1.The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a 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 double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
??2.The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal(“0.1”) creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
??3.When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.
Parameters:
val - double value to be converted to BigDecimal.
Throws:
NumberFormatException - if val is infinite or NaN.
?推荐使用String构造器,它与所存的double类型的字符串所预料的是一样的.
?可以看看这篇文章:浮点数存储.
解决办法:
import java.math.BigDecimal;
public class BigDecimalDemo {
public static void main(String[] args) {
bd1 = new BigDecimal("1.1");
bd2 = new BigDecimal("1.2101");
System.out.println(bd1.add(bd2));
System.out.println(BigDecimal.valueOf(1.1).add(BigDecimal.valueOf(1.2101)));
}
}
/*输出:
2.3101
2.3101
*/
BigDecimal.valueOf(double val)源码:
- 使用
BigDecimal(String val)
构造器
- 先将double类型的值使用
public static BigDecimal valueOf(double val)
方法.
原理:将double类型的值先转换为String类型的值,在存储到BigDecimal对象中.
public static BigDecimal valueOf(double val) {
// Reminder: a zero double returns '0.0', so we cannot fastpath
// to use the constant ZERO.This might be important enough to
// justify a factory approach, a cache, or a few private
// constants, later.
return new BigDecimal(Double.toString(val));
}
API中0.1 (an unscaled value of 1, with a scale of 1)的理解
【#|BigDecimal类中的double类型值的加减问题-java】API文档中有一句(an unscaled value of 1, with a scale of 1)该如何理解呢?BigDecimal类中有
unscaledValue()
和scale()
方法.通过这两个方法来理解这句话吧.unscaledValue
public BigInteger unscaledValue()scale
Returns a BigInteger whose value is the unscaled value of this BigDecimal. (Computes (this * 10this.scale()).)
Returns:
the unscaled value of this BigDecimal.
Since:
1.2
public int scale()方法应用
Returns the scale of this BigDecimal. If zero or positive, the scale is the number of digits to the right of the decimal point. If negative, the unscaled value of the number is multiplied by ten to the power of the negation of the scale. For example, a scale of -3 means the unscaled value is multiplied by 1000.
Returns:
the scale of this BigDecimal.
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
public class FoctorialDemo {
public static void main(String[] args) {
BigDecimal bd = new BigDecimal("-1.2101");
System.out.println(bd.scale());
System.out.println(bd.unscaledValue());
}
}
/*输出:
4
-12101
*/
通过输出可以了解到0.1 (an unscaled value of 1, with a scale of 1)这句话也就好理解了.去掉小数点即为1; 小数点的数值范围为1.scale()方法
是返回该BigDecimal的值的小数位数.scale这个单词有数值范围的意思.
?????????unscaledValue()方法
是将BigInteger的值去除小数点.也就相当于
t h i s ? 1 0 t h i s . s c a l e ( ) this*10^{this.scale()} this?10this.scale()
推荐阅读
- 数据结构和算法|LeetCode 的正确使用方式
- #|7.分布式事务管理
- #|算法设计与分析(Java实现)——贪心算法(集合覆盖案例)
- #|算法设计与分析(Java实现)—— 动态规划 (0-1 背包问题)
- #|阿尔法点亮LED灯(一)汇编语言
- #|Multimedia
- #|ARM裸机开发(汇编LED灯实验(I.MX6UL芯片))
- 基础课|使用深度优先搜索(DFS)、广度优先搜索(BFS)、A* 搜索算法求解 (n^2 -1) 数码难题,耗时与内存占用(时空复杂度)对比(附((n^2 - 1) 数码问题控
- #|学习笔记 | Ch05 Pandas数据清洗 —— 缺失值、重复值、异常值
- win10|搏一搏 单车变摩托,是时候捣鼓一下家中的小米电视机啦。