BigDecimal,金融货币计算中的关键技术

 

1) 在设计数据库的时候用floatdouble作为货币的数据类型。会发现当数据的小数位比较多时,算出的结果和计算器的结果并不一致而且当数据非常大时(>9999999.0) 就自动转化为科学记数法来表示。如System.out.println(999999999.1);输出结果为9.999999991E8。因此float型根本无法胜任有关货币的计算并且会产生致命的错误。

2) Sql Server联机帮助中这样写道:在 Transact-SQL 中,numeric decimal 数据类型在功能上等效。当数据值一定要按照指定精确存储时,可以用带有小数的 decimal 数据类型来存储数字。

Decimal2个参数(ps)

p(精度)

指定小数点左边和右边可以存储的十进制数字的最大个数。精度必须是从 1 到最大精度之间的值。最大精度为 38

s(小数位数)

指定小数点右边可以存储的十进制数字的最大个数。小数位数必须是从 0 p 之间的值。默认小数位数是 0,因而 0 <= s <= p。最大存储大小基于精度而变化。

当结果精度大于 38 时,相应的小数位数会减少,以避免结果的整数部分被截断。

因此我们选用decimal为货币的数据类型。

3) 在《Effective Java》这本书中提到这个原则,floatdouble只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal

 

因此在货币等对精度要求很高的计算中我们用BigDecimalBigDecimal4个构造函数,我们只关心其中的两个:

BigDecimal(double val)

Translates a double into a BigDecimal

BigDecimal(String val)

Translates the String repre sentation of a BigDecimal into a BigDecimal.

在使用这两个构造函数的时候要特别注意,下面请看一个例子:

System.out.println(new java.math.BigDecimal(1.1));

System.out.println(new java.math.BigDecimal(String.valueOf(1.1)));

执行结果为:

1.100000000000000088817841970012523233890533447265625

1.1

由此可见,若需要非常精确的计算结果,必须使用String来构造BigDecimal

下面用实例代码演示如何使用BigDecimal:

Connection con=DataBaseConnection.getConnection();

PreparedStatement pstmt=con.prepareStatement("insert inout (cjfpId,scqyName,cpName,guige,dw,inNumber,inCome,inAmount) values(?,?,?,?,?,?,?,?)");

   pstmt.setString(1,cjfpId[i]);

   pstmt.setString(2,trans(scqyName[i]));

   pstmt.setString(3,trans(cpName[i]));

   pstmt.setString(4,trans(guige[i]));

   pstmt.setString(5,trans(dw[i]));

   pstmt.setBigDecimal(6,new BigDecimal(String.valueOf(inNumber[i])));

   pstmt.setBigDecimal(7,new BigDecimal(String.valueOf(inCome[i])));

   pstmt.setBigDecimal(8,new BigDecimal(String.valueOf(inAmount)));

   pstmt.executeUpdate();

4) 有时用BigDecimal也会遇到一些奇怪的问题,比如下面代码:

System.out.println(new java.math.BigDecimal(String.valueOf(0)).multiply(new

java.math.BigDecimal(String.valueOf(2.32))));

System.out.println(new ava.math.BigDecimal(String.valueOf(0.0)).multiply(new

java.math.BigDecimal(String.valueOf(2.32))));

执行结果为:

0.00

0.000

此时,若要比较两结果的值时若用equals()会认为两个值是相等的,此时可有两个方法来处理:compareTo()或者用if(a.doubleValue()==0.0)比较。

 

在涉及金融货币计算中需要特别精确。浮点数不是精确值,使用它们会导致计算结果和他们原来的计算结果不一致。因此,使用浮点数来试图表示象货币量这样的精确数量是不可行的。使用浮点数来进行金融计算会得到灾难性的后果。无任在C++还是Java等一些程序设计语言中浮点数计算都不怎么精确,因此浮点数不可表示货币类计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值