由于计算机在计算过程中的舍入关系,普通的计算和工程计算可能会出现计算不足够精确的情况,这种情况在这两种计算中也许是可以忍受的,但是在商务运算中就不可接受了,财务计算。
//import org.zym.arithutil.Arith;
public class FloatCalculation {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(0.05 + 0.01);
// System.out.println(Arith.add(0.05,0.01));
System.out.println(4.015 * 100);
// System.out.println(Arith.mul(4.015,100));
}
}
其计算结果:
0.060000000000000005
401.49999999999994
这显然是不能接受的。
下面给出一个算术类工具来解决这个问题,基本原则是使用java.math.BigDecimal类来进行加减乘除的运算封装。
package org.zym.arithutil;
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();
}
}
看下面的代码:
import org.zym.arithutil.Arith;
public class FloatCalculation {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(0.05 + 0.01);
System.out.println(Arith.add(0.05,0.01));
System.out.println(4.015 * 100);
System.out.println(Arith.mul(4.015,100));
}
}
对比计算结果如下: 写道
0.060000000000000005
0.06
401.49999999999994
401.5
得到了令人满意的效果,其他两种计算大家可以自己测试,这样就解决了一些要求精确的商务谁计算的问题,整理下,以方便大家和自己使用。
:-s
分享到:
相关推荐
面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性: 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多...
面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性: 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化...
一款网络时钟同步工具,能够通过国家标准技术局,属美国联邦政府商务部(National Institute of Standards and Technology)的原子钟服务器来同步本地计算机的时间,提供了较高精确度,误差仅小于0.5。它有漂亮的使用...
但是,为了能够使用本书中提到的所有样例,你必须得有一个浏览器,一个兼容ASP的Web服务器(例如Microsoft的Personal Web Server)并(作为运行Java程序的最小环境)安装Sun Java运行时环境(JRE)。
据源连接池机制,整个系统完全贯穿JAVA面向对象的概念,全面完整地实现了JAVA的封装性 ,继承性,多态性的三大特征,完全按照J2EE企业级网络应用程序的开发方案设计和开发, 所有的繁重的计算和处理都由服务器端处理...
从在线审查中共同提取意见目标和意见词在当今的电子商务世界中或竞争激烈的市场结构中,需要大量分析数据来改善服务,概率计算,预测,业务决策以及市场信誉摘要等。此分析是通过对客户反馈和产品的详细摘要获得的...
RIYAJ SHAMSUDEEN 专注于性能/数据恢复/电子商务的咨询公司OraInternals的首席数据库管理员和董事长。有近20年使用Oracle技术产品以及Oracle数据库管理员/Oracle数据库应用管理员的经验,是真正应用集群、性能...