码迷,mamicode.com
首页 > 其他好文 > 详细

建议22:用整数类型处理货币

时间:2014-12-08 15:40:01      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:用整数类型处理货币

  在日常生活中,最容易接触到的小数就是货币,比如你付给售货员10元钱购买一个9.6元的零食,售货员应该找你0.4元也就是4毛钱才对,我们来看下面的程序:

public class Client {
	public static void main(String[] args) {
		System.out.println(10.00-9.60);
	}
}
  我们期望的结果是0.4,也应该是这个数字,但是打印出来的却是0.40000000000000036,这是为什么呢?

  这是因为在计算机中浮点数有可能(注意是可能)是不准确的,它只能无限接近准确值,而不能完全精准。为什么会如此呢?这是有浮点数的存储规则所决定的,我们先来看0.4这个十进制小数如何转化为二进制,使用“乘2取整,顺序排列”法(不懂?这就没招了,太基础了),我们发现0.4不能使用二进制精确表示,在二进制数世界里他是一个无限循环的小数,也就是说,“展示”都不能“展示”,更别说在内存中存储了(浮点数的存储包括三部分:符号位、指数位、尾数,具体不再介绍),可以这样理解,在十进制的世界是没有办法准确表示1/3,那在二进制世界里当然也无法准确表示1/5(如果二进制也有分数的话倒是可以表示),在二进制的世界里1/5是无限循环小数。

   各位要说了,那我对结果取整不就对了吗?代码如下:

public class Client {
	public static void main(String[] args) {
		NumberFormat nf = new DecimalFormat("#.##");
		System.out.println(nf.format(10.00 - 9.60));
	}
}
打印出结果是0.4,看似解决了,但隐藏了一个很深的问题。我们来思考一下金融行业的计算方法,会计系统一般记录小数点后的四位小数但是在汇总、展现、报表中,则只记录小数点后的两位小数,如果使用浮点数来计算货币,想想看,在大批量的加减乘除后结果会有多大的差距(其中还涉及后面会讲到的四舍五入问题)!会计系统要的就是准确,但是却因计算机的缘故不准确了,那真是罪过了,要解决此问题有两种方法:

(1)使用BigDecimal

BigDecimal是专门为弥补浮点数无法准确计算的缺憾而设计的类,并且它本身也提供了加减乘除的常用数学算法。特别是与数据库Decimal类型的字段映射时,BigDecimal是最优的解决方案。

  (2)使用整型

    把参与运算的值扩大100倍,并转变为整型,然后在展现时再缩小100倍,这样处理的好处是计算简单、准确,一般在非金融行业(如零售行业)应用较多。此方法还会用于某些零售POS机,它们的输入和输出全部是整数,那运算就更简单。

==========================================

我按照作者的说法,浮点数减法运算的话我用bigdecimal类型,但是看不出来和double有什么区别?截图如下:

bubuko.com,布布扣

建议22:用整数类型处理货币

标签:用整数类型处理货币

原文地址:http://blog.csdn.net/zl544434558/article/details/41802149

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!