java实现double的精确计算和四舍五入

Posted on

java实现double的精确计算和四舍五入

遗忘的角落

#

*

用户操作[留言] [发消息] [加为好友] 订阅我的博客XML聚合 FeedSky订阅到鲜果订阅到Google订阅到抓虾[编辑]a9529lty的公告我的QQ是297453997欢迎大家加我一起讨论问题[编辑]文章分类* (RSS)Ajax


Java中的简单浮点数类型float和double不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上面的错误。现在终于理解为什么要有BCD码了。 这个问题相当严重,如果你有9.999999999999元,你的计算机是不会认为你可以购买10元的商品的。 在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。现在让我们看看如何解决这个问题。 四舍五入 我们的第一个反应是做四舍五入。Math类中的round方法不能设置保留几位小数,我们只能象这样(保留两位): public double round(double value){ return Math.round(value/100)/100.0; } 非常不幸,上面的代码并不能正常工作,给这个方法传入4.015它将返回4.01而不是4.02,如我们在上面看到的 4.015/100=401.49999999999994 因此如果我们要做到精确的四舍五入,不能利用简单类型做任何运算 java.text.DecimalFormat也不能解决这个问题: System.out.println(new java.text.DecimalFormat("0.00").format(4.025)); 输出是4.02 **java 代码

import java.math.BigDecimal; public class Arith { private static final int DEF_DIV_SCALE = 10; private Arith() { } /// / 提供精确的加法运算。 / @param v1 被加数 / @param v2 加数 / @return 两个参数的和 // public static double add(double v1,double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /// / 提供精确的减法运算。 / @param v1 被减数 / @param v2 减数 / @return 两个参数的差 // public static double sub(double v1,double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /// / 提供精确的乘法运算。 / @param v1 被乘数 / @param v2 乘数 / @return 两个参数的积 // public static double mul(double v1,double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /// / 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 / 小数点以后10位,以后的数字四舍五入。 / @param v1 被除数 / @param v2 除数 / @return 两个参数的商 // public static double div(double v1,double v2) { return div(v1,v2,DEF_DIV_SCALE); } /// / 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 / 定精度,以后的数字四舍五入。 / @param v1 被除数 / @param v2 除数 / @param scale 表示表示需要精确到小数点以后几位。 / @return 两个参数的商 // public static double div(double v1,double v2,int scale) { if(scale<0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } /// / 提供精确的小数位四舍五入处理。 / @param v 需要四舍五入的数字 / @param scale 小数点后保留几位 / @return 四舍五入后的结果 // public static double round(double v,int scale){ if(scale<0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } } *

发表于 @ 2009年05月18日 23:07:00 | 评论( loading... )| 编辑| 举报| 收藏

旧一篇:淘宝生成预览图片 | 新一篇:Oracle层次查询和分析函数

Copyright © a9529ltyPowered by CSDN Blog

希望本站内容对您有点用处,有什么疑问或建议请在后面留言评论
转载请注明作者(RobinChia)和出处 It so life ,请勿用于任何商业用途