新足迹

 找回密码
 注册

精华好帖回顾

· 美食接龙:蒜泥甜豆,鱼子豆腐煲,烤鸡腿。。。next: gandu 鱼子?哈哈 (2008-8-26) 黑山老妖 · 更新完毕 2018 圣诞日本之轻井泽-长野-小布施-松本-镰仓-东京 (2019-1-16) ailsalu
· 煮夫手记三十八 酿辣椒与酿茄子 (2011-11-20) amon54 · 【金融危机征文】:CUT COST - 从我做起 (2008-11-13) leeshine
Advertisement
Advertisement
查看: 1939|回复: 2

java 小陷阱之: Float to BigDecimal [复制链接]

发表于 2011-3-30 20:06 |显示全部楼层
此文章由 ala 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 ala 所有!转贴必须注明作者、出处和本声明,并保持内容完整
前几天做了一个汇率换算的相关项目,汇率从已有的Service读取,类型是Float。

啥也没想,直接转换为BigDecimal,换算,rounding,commit...呵呵

过了一会,Tester说,汇率换算不对,有bug,rounding不对!

在Java中,如果直接用BigDecimal.valueOf(0.5f),JDK会自动把Float转换为Double,
问题来了,为了保持精度,你所得到的Double并不是你想象中的那样,比如:

double a = (double)0.5f, 这个时侯a是0.5

double b = (double)0.00005f, 这个时侯b是0.00004999999873689376 或者 4.999999873689376E-5

如果这时,你想换算VND to USD, BigDecimal.valueOf(0.00005f).multiply(BigDecimal.valueOf(10000000000L))
rounding以后,你得到的是499999.987

问题就在float to BigDecimal 的时侯JDK自动帮你转换为Double

How to fix?
根据JDK文档,

BigDecimal exchangeRate = new BigDecimal(Float.toString(0.00005f));
exchangeRate.multiply(BigDecimal.valueOf(10000000000L))
这是,你得到的值就是500000

[ 本帖最后由 ala 于 2011-3-30 21:08 编辑 ]
Advertisement
Advertisement

发表于 2011-3-31 08:07 |显示全部楼层
此文章由 greentree 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 greentree 所有!转贴必须注明作者、出处和本声明,并保持内容完整


Thanks

发表于 2011-4-1 09:06 |显示全部楼层
此文章由 greed 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 greed 所有!转贴必须注明作者、出处和本声明,并保持内容完整
java 浮点的确很烦。所以对金额等敏感数据还得走字符或者直接BigDecimal之类。

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部