java浮点数金额精确计算Word格式.docx
- 文档编号:14079095
- 上传时间:2022-10-18
- 格式:DOCX
- 页数:13
- 大小:18.96KB
java浮点数金额精确计算Word格式.docx
《java浮点数金额精确计算Word格式.docx》由会员分享,可在线阅读,更多相关《java浮点数金额精确计算Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
这个问题就非常严重了,如果你有123.3元要购买商品,而计算机却认为你只有123.29999999999999元,钱不够,计算机拒绝交易。
(2)、四舍五入
是否可以四舍五入呢?
当然可以,习惯上我们本能就会这样考虑,但四舍五入意味着误差,商业运算中可能意味着错误,同时Java中也没有提供保留指定位数的四舍五入方法,只提供了一个Math.round(doubled)和Math.round(floatf)的方法,分别返回长整型和整型值。
round方法不能设置保留几位小数,我们只能象这样(保留两位):
publicdoubleround(doublevalue){
returnMath.round(value*100)/100.0;
}
但非常不幸的是,上面的代码并不能正常工作,给这个方法传入4.015它将返回4.01而不是4.02,如我们在上面看到的
4.015*100=401.49999999999994
因此如果我们要做到精确的四舍五入,这种方法不能满足我们的要求。
还有一种方式是使用java.text.DecimalFormat,但也存在问题,format采用的舍入模式是ROUND_HALF_DOWN(舍入模式在下面有介绍),比如说4.025保留两位小数会是4.02,因为.025距离”nearestneighbor”(.02和.03)长度是相等,向下舍入就是.02,如果是4.0251那么保留两位小数就是4.03。
System.out.println(newjava.text.DecimalFormat("
0.00"
).format(4.025));
).format(4.0251));
输出是
4.02
4.03
(3)、浮点数输出(科学记数法)
Java浮点型数值在大于9999999.0就自动转化为科学记数法来表示,我们看下面的例子:
System.out.println(999999999.04);
System.out.println(99999999.04);
System.out.println(10000000.01);
System.out.println(9999999.04);
输出的结果如下:
9.9999999904E8
9.999999904E7
1.000000001E7
9999999.04
但有时我们可能不需要科学记数法的表示方法,需要转换为字符串,还不能直接用toString()等方法转换,很烦琐。
BigDecimal介绍
BigDecimal是Java提供的一个不变的、任意精度的有符号十进制数对象。
它提供了四个构造器,有两个是用BigInteger构造,在这里我们不关心,我们重点看用double和String构造的两个构造器(有关BigInteger详细介绍请查阅j2seAPI文档)。
BigDecimal(doubleval)
TranslatesadoubleintoaBigDecimal.
BigDecimal(Stringval)
TranslatestheStringrepresentationofaBigDecimalintoaBigDecimal.
BigDecimal(double)是把一个double类型十进制数构造为一个BigDecimal对象实例。
BigDecimal(String)是把一个以String表示的BigDecimal对象构造为BigDecimal对象实例。
习惯上,对于浮点数我们都会定义为double或float,但BigDecimalAPI文档中对于BigDecimal(double)有这么一段话:
Note:
theresultsofthisconstructorcanbesomewhatunpredictable.OnemightassumethatnewBigDecimal(.1)isexactlyequalto.1,butitisactuallyequalto.1000000000000000055511151231257827021181583404541015625.Thisissobecause.1cannotberepresentedexactlyasadouble(or,forthatmatter,asabinaryfractionofanyfinitelength).Thus,thelongvaluethatisbeingpassedintotheconstructorisnotexactlyequalto.1,appearancesnotwithstanding.
The(String)constructor,ontheotherhand,isperfectlypredictable:
newBigDecimal("
.1"
)isexactlyequalto.1,asonewouldexpect.Therefore,itisgenerallyrecommendedthatthe(String)constructorbeusedinpreferencetothisone
下面对这段话做简单解释:
注意:
这个构造器的结果可能会有不可预知的结果。
有人可能设想newBigDecimal(.1)等于.1是正确的,但它实际上是等于.1000000000000000055511151231257827021181583404541015625,这就是为什么.1不能用一个double精确表示的原因,因此,这个被放进构造器中的长值并不精确的等于.1,尽管外观看起来是相等的。
然而(String)构造器,则完全可预知的,newBigDecimal(“.1”)如同期望的那样精确的等于.1,因此,(String)构造器是被优先推荐使用的。
看下面的结果:
System.out.println(newBigDecimal(123456789.02).toString());
System.out.println(newBigDecimal("
123456789.02"
).toString());
输出为:
123456789.01999999582767486572265625
123456789.02
现在我们知道,如果需要精确计算,非要用String来够造BigDecimal不可!
实现方案
现在我们已经知道怎么解决这个问题了,原则上是使用BigDecimal(String)构造器,我们建议,在商业应用开发中,涉及金额等浮点数计算的数据,全部定义为String,数据库中可定义为字符型字段,在需要使用这些数据进行运算的时候,使用BigDecimal(String)构造BigDecimal对象进行运算,保证数据的精确计算。
同时避免了科学记数法的出现。
如果科学记数表示法在应用中不是一种负担的话,可以考虑定义为浮点类型。
这里我们提供了一个工具类,定义浮点数的加、减、乘、除和四舍五入等运算方法。
以供参考。
源文件MathExtend.java:
importjava.math.BigDecimal;
publicclassMathExtend
{
//默认除法运算精度
privatestaticfinalintDEFAULT_DIV_SCALE=10;
/**
*提供精确的加法运算。
*@paramv1
*@paramv2
*@return两个参数的和
*/
publicstaticdoubleadd(doublev1,doublev2)
{
BigDecimalb1=newBigDecimal(Double.toString(v1));
BigDecimalb2=newBigDecimal(Double.toString(v2));
returnb1.add(b2).doubleValue();
}
/**
*提供精确的加法运算
*@paramv1
*@return两个参数数学加和,以字符串格式返回
publicstaticStringadd(Stringv1,Stringv2)
BigDecimalb1=newBigDecimal(v1);
BigDecimalb2=newBigDecimal(v2);
returnb1.add(b2).toString();
*提供精确的减法运算。
*@return两个参数的差
publicstaticdoublesubtract(doublev1,doublev2)
returnb1.subtract(b2).doubleValue();
*提供精确的减法运算
*@return两个参数数学差,以字符串格式返回
publicstaticStringsubtract(Stringv1,Stringv2)
returnb1.subtract(b2).toString();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 浮点 金额 精确 计算
![提示](https://static.bdocx.com/images/bang_tan.gif)