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也不靠谱,参见第二行
本文出自 “IT菜鸟” 博客,请务必保留此出处http://mazongfei.blog.51cto.com/3174958/1898963
原文:http://mazongfei.blog.51cto.com/3174958/1898963