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