货币金额的计算 - Java中的BigDecimal

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了货币金额的计算 - Java中的BigDecimal相关的知识,希望对你有一定的参考价值。

float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。,而且使用BigDecimal类也可以进行大数的操作。具体参见API

编号方法类型描述
1public BigDecimal(double val)  构造将double表示形式转化为BigDecimal
2public BigDecimal(int val) 构造将int表示形式转化为BigDecimal
3public BigDecimal(String val)  方法将字符串表示形式转化为BigDecimal
4public BigDecimal add(BigDecimal augend)  方法加法
5public BigDecimal subtract(BigDecimal subtrahend)  方法减法
6public BigDecimal multiply(BigDecimal multiplicand)  方法乘法
7public BigDecimal divide(BigDecimal divisor)  方法除法

一、BigDecimal的计算

double d1 = 9.45;
		double d2 = 3.14;
		//使用BigDecimal(String val)构造方法
		BigDecimal b1 = new BigDecimal(Double.toString(d1));
		BigDecimal b2 = new BigDecimal(Double.toString(d2));
		//b1:9.45	——b2:3.14
		System.out.println("b1:"+b1+"\t——b2:"+b2);
		
		//加法
		BigDecimal add = b1.add(b2);
		//加法:12.59
		System.out.println("加法:"+add);
		
		//减法
		BigDecimal sub = b1.subtract(b2);
		//减法:6.31
		System.out.println("减法:"+sub);
		
		//乘法
		BigDecimal mul = b1.multiply(b2);
		//乘法:29.6730
		System.out.println("乘法:"+mul);
		//除法
		int scale = 20;//保留20位小数
		BigDecimal div1 = b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP);
		//除法:3.0095541401273884
		System.out.println("除法:"+div1.doubleValue());
		//格式化
		double foo = 2334233.1415956;
		
		//获取常规数值格式
		NumberFormat number = NumberFormat.getNumberInstance();
		String str1 = number.format(foo);
		//获取常规数值格式:2,334,233.142
		System.out.println("获取常规数值格式:"+str1);
		
		//获取整数数值格式——返回当前缺省语言环境的通用数值格式
		NumberFormat integer = NumberFormat.getIntegerInstance();
		String inte1 = integer.format(foo);//如果带小数会四舍五入到整数12,343,172
		//获取整数数值格式:2,334,233
		System.out.println("获取整数数值格式:"+inte1);
		
		//获取货币数值格式——返回当前缺省语言环境的通用格式
		String curr = NumberFormat.getCurrencyInstance().format(foo);
		//获取货币数值格式:¥2,334,233.14
		System.out.println("获取货币数值格式:"+curr);
		
		//获取显示百分比的格式——返回当前缺省语言环境的百分比格式
		String percent = NumberFormat.getPercentInstance().format(foo);
		//获取显示百分比的格式:233,423,314%
		System.out.println("获取显示百分比的格式:"+percent);

double的计算不精确,会有类似0.0000000000000002的误差,正确的方法是使用BigDecimal或者用整型 9  * 整型地方法适合于货币精度已知的情况,比如22.11+2.10转成2211+210计算,最后再/100,损失精度


二、常见问题

double d3 = 0.1;
		//0.1000000000000000055511151231257827021181583404541015625
		System.out.println(new BigDecimal(d3).toString());
		//0.1
		System.out.println(new BigDecimal(d3+"").toString());
		//0.1
		System.out.println(new BigDecimal(Double.toString(d3)).toString());
		//0.1
		System.out.println(new BigDecimal(Double.toString(0.1000000000000000055511151231257827021181583404541015625)).toString());

第一个:事实上,由于二进制无法精确地表示十进制小数0.1,但是编译器读到字符串"0.1"之后,必须把它转成8个字节的double值,因 此,编译器只能用一个最接近的值来代替0.1了


第二个:BigDecimal能够正确地把字符串转化成真正精确的浮点数。

第三个:问题在于Double.toString会使用一定的精度来四舍五入double,然后再输出

第四个:等价于第三行


结论:

1.如果希望精确的表示希望的数值,一定使用字符串来表示

2.使用Double.toString也不靠谱,参见第二行

本文出自 “IT菜鸟” 博客,请务必保留此出处http://mazongfei.blog.51cto.com/3174958/1898963

以上是关于货币金额的计算 - Java中的BigDecimal的主要内容,如果未能解决你的问题,请参考以下文章

java怎么取实数中的小数部分

使用状态变量更新计算属性

华为OD机试用java实现 -货币单位换算

华为OD机试真题 Java 实现货币单位换算2022.11 Q4 新题

数据库中的货币建模

拼手气红包算法,保证金额不会随前后顺序进入而变化,微信的红包生成算法改编