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

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

编号 方法 类型 描述
1 public BigDecimal(double val)   构造 将double表示形式转化为BigDecimal
2 public BigDecimal(int val)  构造 将int表示形式转化为BigDecimal
3 public BigDecimal(String val)   方法 将字符串表示形式转化为BigDecimal
4 public BigDecimal add(BigDecimal augend)   方法 加法
5 public BigDecimal subtract(BigDecimal subtrahend)   方法 减法
6 public BigDecimal multiply(BigDecimal multiplicand)   方法 乘法
7 public 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也不靠谱,参见第二行

时间: 2024-10-12 03:25:18

货币金额的计算 - Java中的BigDecimal的相关文章

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

[本文相关的代码放在github上,地址为:https://github.com/VigourJiang/StructuredFloat] Java中double类型的格式是遵循IEEE 754标准的.尽管数学意义上的小数是连续的,但double仅仅能表示其中的一些离散点,把这些离散点组成的集合记为S,S的大小还是有限的.如果要保存的小数P刚好在集合S内,那么double类型就能精确的表示P:否则double类型只能从集合S中找一个与P最近的离散点P'代替P. 以上表述对于float也成立.IE

货币金额-Java中的BigDecimal

对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作. float和double只能用来做科学计算或者是工程计算,在商业计算中金额我们要用 java.math.BigDecimal. 表11-15 BigDecimal类的常用方法 序号 方    法 类型 描    述 1 public BigDecimal(double val) 构造 将double表示形式转换

Java 中浮点数---------BigDecimal和double(初探)

为什么要使用 bigdecimal? 借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合.但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦. BigDecimal简介 BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale

Java中的BigDecimal类用法介绍

Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算. 其中 BigInteger 类是针对大整数的处理类,而 BigDecimal 类则是针对大小数的处理类. BigDecimal 类的实现用到了 BigInteger类,不同的是 BigDecimal 加入了小数的概念. float和Double只能用来做科学计算或者是工程计算;在商业计算中,对数字精度要求较高,必须使用 BigIn

Java中关于 BigDecimal 的一个导致double精度损失的&quot;bug&quot;

背景 在博客 恶心的0.5四舍五入问题 一文中看到一个关于 0.5 不能正确的四舍五入的问题.主要说的是 double 转换到 BigDecimal 后,进行四舍五入得不到正确的结果: public class BigDecimalTest { public static void main(String[] args){ double d = 301353.05; BigDecimal decimal = new BigDecimal(d); System.out.println(decima

Java中的Bigdecimal类型运算

双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行运算和处理.Java在java.math包中提 供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.表5.7中列出了BigDecimal类的主要构造器和方法. 构造器  描 述 BigDecimal(int)创建一个具有参数所指定整数值的对象. BigDecimal(double)创建一个具有参数所指定双精度值的对象. BigDecimal(long)创建一个具有参数所指定长整数值的

java中的BigDecimal和String的相互转换

1 /*由数字字符串构造BigDecimal的方法 2 02.*设置BigDecimal的小数位数的方法 3 03.*/ 4 04.import java.math.BigDecimal; 5 05.//数字字符串 6 06.String StrBd="1048576.1024"; 7 07.//构造以字符串内容为值的BigDecimal类型的变量bd 8 08.BigDecimal bd=new BigDecimal(StrBd); 9 09.//设置小数位数,第一个变量是小数位数,

Java中new BigDecimal()的坑

先看一段代码示例: System.out.println(new BigDecimal(0.99)); System.out.println(new BigDecimal("0.99")); System.out.println(BigDecimal.valueOf(0.99)); System.out.println(new BigDecimal(Double.valueOf(0.99))); System.out.println(new BigDecimal(Double.valu

mysql对应java中常用的字段

varchar 不定长字符串 字符串或是没有合适类型时,可以选择它作为字段类型 对应Java中的String int bigint 数值 一般以int作为数字的默认选择,数值很大时使用bigint 对应Java中的Long char 定长字符串 适用于盐.md5加密后的密码等情况 对应Java中的String float double 浮点数 适用于各种小数,除非金额等情况,小数推荐使用double 各自对应Java中的Float,Double decimal 精确浮点数 适用于金额 对应Jav