Java -- BigDecimal类
2017-07-21 21:14
344 查看
1、概述
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。float和double只能用来做科学计算或者是工程计算,在商业计算中往往要求结果精确,此时就要用到java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。
2、简介
BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负scale 次幂,即 BigDecimal表示的数值是(unscaledValue × 10−scale)。
3、方法
① BigDecimal一共有4个常用构造方法
注:
参数类型为double的构造方法的结果有一定的不可预知性
如:newBigDecimal(0.1)所创建的BigDecimal实际上等于0.1000000000000000055511151231257827021181583404541015625。
如果要进行精确转换:
1) Double.toString(double)–>BigDecimal(String)构造方法
2) BigDecimal.valueOf(double val)
② BigDecimal 的运算方式 不支持 + - * / 这类的运算 它有自己的运算方法
BigDecimal 加减乘除运算并返回double类型数据范例
③ doubleValue()
将BigDecimal 类型转换为double类型
同理可得:
floatValue(): 将BigDecimal 类型转换为float类型
longValue(): 将BigDecimal类型转换为long类型
intVa
4000
lue(): 将BigDecimal 类型转换为int类型
注:
以上方法在向小精度的类型转换时均存在精度丢失问题
intValue() 将丢弃此 BigDecimal 的所有小数部分,并且如果生成的 ” BigInteger” 太大而不适合用 int 表示,则仅返回 32 位低位字节。注意,此转换会丢失关于此 BigDecimal 值的总大小和精度的信息,并返回带有相反符号的结果。
④ setScale(int newScale, int roundingMode)
返回一个保留指定小数位的BigDecimal类型的值
newScale 保留BigDecimal的位数
roundingMode 有以下几种处理模式:
1.setScale(1,BigDecimal.ROUND_UP):
进位处理,2.35变成2.4 。舍入远离零的舍入模式。在丢弃非零部分之前始终增加数字
2.setScale(1,BigDecimal.ROUND_DOWN):
直接删除多余的小数位,如2.35会变成2.3 。接近零的舍入模式。
3.setScale(1,BigDecimal.ROUND_CEILING)
接近正无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;如果为负,则舍入行为与 ROUND_DOWN 相同。接近负无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;如果为负,则舍入行为与 ROUND_UP 相同
4.setScale(1,BigDecimal.ROUND_HALF_UP):
向上四舍五入,2.35变成2.4
5.setScale(1,BigDecimal.ROUND_HALF_DOWN):
向下四舍五入,2.35变成2.3
6.setScaler(1,BigDecimal.ROUND_HALF_EVEN)
向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
7.setScaler(1,BigDecimal.ROUND_UNNECESSARY)
断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出 ArithmeticException。
⑤ BigDecimal 的比较
max(BigDecimal val) : 返回此 BigDecimal 和 val 的最大值。
min(BigDecimal val) : 返回此 BigDecimal 和 val 的最小值。
equals(Object x)
比较此 BigDecimal 与指定的 Object 的相等性。
很明显equals无法很好的比较两个BigDecimal,所以要用到compareTo()方法
compareTo(BigDecimal val)
将此 BigDecimal 与指定的 BigDecimal 比较。
当此 BigDecimal 在数字上小于、等于或大于 val 时,返回 -1、0 或 1。
一般我们都是在if语句中使用,如:
⑥ 常量
数字常量:
public static final BigDecimal ZERO
public static final BigDecimal ONE
public static final BigDecimal TEN
roundingMode 模式常量:
更多方法参见 java API手册 java.math–>BigDecimal
4、总结
参考:
http://blog.csdn.net/jackiehff/article/details/8582449
http://www.cnblogs.com/chenssy/archive/2012/09/09/2677279.html
另外可参考:http://zhangyinhu8680.iteye.com/blog/1536397
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。float和double只能用来做科学计算或者是工程计算,在商业计算中往往要求结果精确,此时就要用到java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。
2、简介
BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负scale 次幂,即 BigDecimal表示的数值是(unscaledValue × 10−scale)。
3、方法
① BigDecimal一共有4个常用构造方法
BigDecimal(int) 创建一个具有参数所指定整数值的对象。 BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 BigDecimal(long) 创建一个具有参数所指定长整数值的对象。 BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
注:
参数类型为double的构造方法的结果有一定的不可预知性
如:newBigDecimal(0.1)所创建的BigDecimal实际上等于0.1000000000000000055511151231257827021181583404541015625。
如果要进行精确转换:
1) Double.toString(double)–>BigDecimal(String)构造方法
2) BigDecimal.valueOf(double val)
② BigDecimal 的运算方式 不支持 + - * / 这类的运算 它有自己的运算方法
BigDecimal add(BigDecimal augend) 加法运算 BigDecimal subtract(BigDecimal subtrahend) 减法运算 BigDecimal multiply(BigDecimal multiplicand) 乘法运算 BigDecimal divide(BigDecimal divisor) 除法运算
BigDecimal 加减乘除运算并返回double类型数据范例
public class Arith { /** * 提供精确加法计算的add方法 * @param value1 被加数 * @param value2 加数 * @return 两个参数的和 */ public static double add(double value1,double value2){ BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.add(b2).doubleValue(); } /** * 提供精确减法运算的sub方法 * @param value1 被减数 * @param value2 减数 * @return 两个参数的差 */ public static double sub(double value1,double value2){ BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确乘法运算的mul方法 * @param value1 被乘数 * @param value2 乘数 * @return 两个参数的积 */ public static double mul(double value1,double value2){ BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.multiply(b2).doubleValue(); } /** * 提供精确的除法运算方法div * @param value1 被除数 * @param value2 除数 * @param scale 精确范围 * @return 两个参数的商 * @throws IllegalAccessException */ public static double div(double value1,double value2,int scale) throws IllegalAccessException{ //如果精确范围小于0,抛出异常信息 if(scale<0){ throw new IllegalAccessException("精确度不能小于0"); } BigDecimal b1 = new BigDecimal(Double.valueOf(value1)); BigDecimal b2 = new BigDecimal(Double.valueOf(value2)); return b1.divide(b2, scale).doubleValue(); } }
③ doubleValue()
将BigDecimal 类型转换为double类型
同理可得:
floatValue(): 将BigDecimal 类型转换为float类型
longValue(): 将BigDecimal类型转换为long类型
intVa
4000
lue(): 将BigDecimal 类型转换为int类型
注:
以上方法在向小精度的类型转换时均存在精度丢失问题
intValue() 将丢弃此 BigDecimal 的所有小数部分,并且如果生成的 ” BigInteger” 太大而不适合用 int 表示,则仅返回 32 位低位字节。注意,此转换会丢失关于此 BigDecimal 值的总大小和精度的信息,并返回带有相反符号的结果。
④ setScale(int newScale, int roundingMode)
返回一个保留指定小数位的BigDecimal类型的值
newScale 保留BigDecimal的位数
roundingMode 有以下几种处理模式:
1.setScale(1,BigDecimal.ROUND_UP):
进位处理,2.35变成2.4 。舍入远离零的舍入模式。在丢弃非零部分之前始终增加数字
2.setScale(1,BigDecimal.ROUND_DOWN):
直接删除多余的小数位,如2.35会变成2.3 。接近零的舍入模式。
3.setScale(1,BigDecimal.ROUND_CEILING)
接近正无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;如果为负,则舍入行为与 ROUND_DOWN 相同。接近负无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;如果为负,则舍入行为与 ROUND_UP 相同
4.setScale(1,BigDecimal.ROUND_HALF_UP):
向上四舍五入,2.35变成2.4
5.setScale(1,BigDecimal.ROUND_HALF_DOWN):
向下四舍五入,2.35变成2.3
6.setScaler(1,BigDecimal.ROUND_HALF_EVEN)
向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
7.setScaler(1,BigDecimal.ROUND_UNNECESSARY)
断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出 ArithmeticException。
BigDecimal b1 = new BigDecimal("23.4567"); System.out.println(b1.setScale(2,BigDecimal.ROUND_HALF_UP)); // 23.46 System.out.println(b1.setScale(0,BigDecimal.ROUND_HALF_DOWN)); // 23
⑤ BigDecimal 的比较
max(BigDecimal val) : 返回此 BigDecimal 和 val 的最大值。
min(BigDecimal val) : 返回此 BigDecimal 和 val 的最小值。
BigDecimal b1 = new BigDecimal("23.7"); BigDecimal b2 = new BigDecimal("28.7"); System.out.println(b1.max(b2)); // 28.7 System.out.println(b1.min(b2)); // 23.7
equals(Object x)
比较此 BigDecimal 与指定的 Object 的相等性。
BigDecimal b1 = new BigDecimal("23"); BigDecimal b2 = new BigDecimal("23.0"); BigDecimal b3 = new BigDecimal("23.000"); System.out.println(b1.equals(b2)); // false System.out.println(b1.equals(b3)); // false
很明显equals无法很好的比较两个BigDecimal,所以要用到compareTo()方法
compareTo(BigDecimal val)
将此 BigDecimal 与指定的 BigDecimal 比较。
当此 BigDecimal 在数字上小于、等于或大于 val 时,返回 -1、0 或 1。
BigDecimal b1 = new BigDecimal("23"); BigDecimal b2 = new BigDecimal("23.0"); BigDecimal b3 = new BigDecimal("23.000"); System.out.println(b1.compareTo(b2)); // true System.out.println(b1.compareTo(b3)); // true
一般我们都是在if语句中使用,如:
if(b1.compareTo(b2) == -1) { // b1<b2情况 } if(b1.compareTo(b2) == 0) { // b1=b2情况 } if(b1.compareTo(b2) == 1) { // b1>b2情况 }
⑥ 常量
数字常量:
public static final BigDecimal ZERO
public static final BigDecimal ONE
public static final BigDecimal TEN
roundingMode 模式常量:
public final static int ROUND_UP = 0; public final static int ROUND_DOWN = 1; public final static int ROUND_CEILING = 2; public final static int ROUND_FLOOR = 3; public final static int ROUND_HALF_UP = 4; public final static int ROUND_HALF_DOWN = 5; public final static int ROUND_HALF_EVEN = 6; public final static int ROUND_UNNECESSARY = 7;
更多方法参见 java API手册 java.math–>BigDecimal
4、总结
(1)商业计算使用BigDecimal。 (2)尽量使用参数类型为String的构造函数。 (3) BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。 (4)我们往往容易忽略JDK底层的一些实现细节,导致出现错误,需要多加注意。
参考:
http://blog.csdn.net/jackiehff/article/details/8582449
http://www.cnblogs.com/chenssy/archive/2012/09/09/2677279.html
另外可参考:http://zhangyinhu8680.iteye.com/blog/1536397
相关文章推荐
- java.math.BigDecimal类的用法
- 关于四舍五入:java.math.BigDecimal类的用法
- java.math BigDecimal类
- 转:java.math.BigDecimal类的用法
- java.math.BigDecimal类
- Java-BigDecimal类,BigInteger类
- java.math.BigDecimal类的用法
- java学习之BigInteger类、BigDecimal类
- JAVA基础再回首(十三)——BigInteger类、BigDecimal类、Date类、DateFormat类、Calendar类
- java中小数的处理:高精度运算用bigDecimal类,精度保留方法,即舍入方式的指定
- 如何应用Java的BigDecimal类 推荐
- Java API —— BigDecimal类
- Java BigDecimal类的使用和注意事项
- java.math.BigDecimal类的用法
- JAVA BigInteger类和BigDecimal类
- Java做高精度计算(BigDecimal类)
- JAVA基础知识--BigDecimal类
- Java中BigInteger类、BigDecimal类、Date/DateFormat类和Calendar类的概述
- java基础(1)--java.math.BigDecimal类的用法
- java之BigDecimal类