Java BigDecimal和double示例及相关问题解析
BigDecimal类 对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作。BigDecimal类的常用方法如表1所示。 表1 BigDecimal类的常用方法
范例:进行四舍五入的四则运算 package org.lxh.demo11.numberdemo; import java.math.BigDecimal; class MyMath { public static double add(double d1,double d2) { // 进行加法运算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.add(b2).doubleValue(); } public static double sub(double d1,double d2) { // 进行减法运算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.subtract(b2).doubleValue(); } public static double mul(double d1,double d2) { // 进行乘法运算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.multiply(b2).doubleValue(); } public static double div(double d1,double d2,int len) {// 进行除法运算 BigDecimal b1 = new BigDecimal(d1); BigDecimal b2 = new BigDecimal(d2); return b1.divide(b2,len,BigDecimal. ROUND_HALF_UP).doubleValue(); } public static double round(double d,int len) { // 进行四舍五入 操作 BigDecimal b1 = new BigDecimal(d); BigDecimal b2 = new BigDecimal(1); // 任何一个数字除以1都是原数字 // ROUND_HALF_UP是BigDecimal的一个常量, 表示进行四舍五入的操作 return b1.divide(b2,BigDecimal. ROUND_HALF_UP).doubleValue(); } } public class BigDecimalDemo01 { public static void main(String[] args) { System.out.println("加法运算:" + MyMath.round(MyMath.add(10.345,3.333),1)); System.out.println("乘法运算:" + MyMath.round(MyMath.mul(10.345,3)); System.out.println("除法运算:" + MyMath.div(10.345,3.333,3)); System.out.println("减法运算:" + MyMath.round(MyMath.sub(10.345,3)); } } BigDecimal是Java中用来表示任意精确浮点数运算的类,在BigDecimal中,使用unscaledValue×10-scale来表示一个浮点数。其中,unscaledValue是一个BigInteger,scale是一个int。从这个表示方法来看,BigDecimal只能标识有限小数,不过可以表示的数据范围远远大于double,在实际应用中基本足够了。 下面提一下两个精度问题 问题一:BigDecimal的精度问题(StackOverflow上有个家伙问了相关的问题) System.out.println(new BigDecimal(0.1).toString()); // 0.1000000000000000055511151231257827021181583404541015625 System.out.println(new BigDecimal("0.1").toString()); // 0.1 System.out.println(new BigDecimal( Double.toString(0.1000000000000000055511151231257827021181583404541015625)).toString());// 0.1 System.out.println(new BigDecimal(Double.toString(0.1)).toString()); // 0.1 分析一下上面代码的问题(注释的内容表示此语句的输出) 第一行:事实上,由于二进制无法精确地表示十进制小数0.1,但是编译器读到字符串"0.1"之后,必须把它转成8个字节的double值,因此,编译器只能用一个最接近的值来代替0.1了,即0.1000000000000000055511151231257827021181583404541015625。因此,在运行时,传给BigDecimal构造函数的真正的数值是0.1000000000000000055511151231257827021181583404541015625。 小结: 1.如果你希望BigDecimal能够精确地表示你希望的数值,那么一定要使用字符串来表示小数,并传递给BigDecimal的构造函数。 问题二:把double强制转化成int,难道不是扔掉小数部分吗?
原因还是在于二进制无法精确地表示某些十进制小数,因此1023.99999999999999在编译之后的double值变成了1024。 所以,把double强制转化成int确实是扔掉小数部分,但是你写在代码中的值,并不一定是编译器生成的真正的double值。 验证代码:
前面提过BigDecimal可以精确地把double表示出来还记得吧。 我们也可以直接打印出d的二进制形式,根据IEEE 754的规定,我们可以算出0x4090000000000000=(1024)。 下面再分享一个double转BigDecimal的实例,代码: public static void main(String[] args) { double d = 1.1; BigDecimal bd1 = new BigDecimal(d); //(1) BigDecimal bd2 = BigDecimal.valueOf(d);//(2) BigDecimal bd3 = new BigDecimal("1.1");//(3) System.out.println(bd1);//打印1.100000000000000088817841970012523233890533447265625 System.out.println(bd2);//打印1.1 System.out.println(bd3);//打印1.1 System.out.println(bd1.compareTo(bd2));//打印1 System.out.println(bd1.compareTo(bd3));//打印1 System.out.println(bd2.compareTo(bd3));//打印0 } 数变大了。 用(1)方法传double直接new BigDecimal,数会变大,(2)(3)不会,建议不要用(1)! 下面分享一个小笑话: “等我敲完这行代码,就和你离婚!” 总结 以上就是本文关于Java BigDecimal和double示例及相关问题解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站: Java编程BigDecimal用法实例分享 Java大数字运算之BigInteger 如有不足之处,欢迎留言指出。感谢朋友们对本站的支持! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |