提高你的Java代码质量吧:用整数类型处理货币

原创 2013年12月04日 17:12:26


一、分析 

在计算机中,使用二进制表示数据,浮点数有可能是不准确的,它只能无限接近准确值,而不是完全精确。

如:0.4这个十进制小数,使用“乘2取整,顺序排列”法:

0.4*2=0.8   --->   取整是0

0.8*2=1.6   --->   取整是1

0.6*2=1.2   --->   取整是1

0.2*2=0.4   --->   取整是0

 

0.4*2=0.8   --->   取整是0

0.8*2=1.6   --->   取整是1

.......

发现0.4不能使用二进制准确表示,它是一个无限循环的小数:0.0110 0110 0110....

二、场景 

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

 

  1. public class Client{
  2.     pubilc static void main(String[] args){
  3.         System.out.println(10.00 - 9.60);
  4.     }
  5. }

我们期望的结果是0.4,但是打印出来的却是040000000000000036。

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

  1. public class Client{
  2.     pubilc static void main(String[] args){
  3.         NumberFormat f = new DecialFormat("#.##");
  4.         System.out.println(f.format(10.00-9.60));
  5.     }
  6. }

打印出来的结果是0.4,看似解决了,但是隐藏了一个很深的问题。在金融行业的计算方法,会统计一般记录小数点的后4位小数,但是在汇总、展现、报表中,则只记录小数点最后的2位小数,如果使用浮点型来计算货币,在大批量的加减乘除后结果会有多大的差距。

三、建议

要解决此问题的两种方法:

1.使用BigDecimal

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

2.使用整形

把参与运算的值扩大100倍,并转换成整形,然后在展现时在缩小100倍,这样处理的好处就是计算简单、准确,一般在非金融行业应用比较多。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

提高你的Java代码质量吧:用整数类型处理货币

一、分析  在计算机中,使用二进制表示数据,浮点数有可能是不准确的,它只能无限接近准确值,而不是完全精确。  如:0.4这个十进制小数,使用“乘2取整,顺序排列”法:  0.4*2=0.8  ...

提高你的Java代码质量吧:三元操作符的类型陷阱

一、分析  当你使用三元运算符,两边的操作数的类型不一致的时候,这就涉及到三元操作符的转换规则:  1.若果两个操作数不可转换,则不做转换,返回值为Object类型。  2.若两个操作数是明确...

提高你的Java代码质量吧:谨慎包装类型的比较

一、分析  基本类型可以比较大小,其所对应的包装类型都实现了Comparable接口此问题。   二、场景  代码如下:  public class Client{ publ...

提高你的Java代码质量吧:不要让类型默默转换

一、分析  在Java运算中的类型转换,是先运算在进行类型转换的。具体场景如下。 二、场景  在如下程序中:  public class Client{ public sta...

提高你的Java代码质量吧:避免基本类型数组转换列表陷阱(Arrays.asList())

一、分析  我们在开发的过程中经常会使用Arrays和Collections这两个工具类在数组和列表之间转换。  Arrays.asList()方法:输入一个变长参数,返回一个固定长度的列表。看...

提高你的Java代码质量吧:提防包装类型的null值

一、分析  Java引入包装类型(Wrapper Types)是为了解决基本类型的实例化问题,以便一个基本类型也能参与到面向对象的编程世界中。   而在Java5中泛型更是对基本类型说了“不”,...

提高你的Java代码质量吧:注意@ Override不同版本的区别

一、分析  @Override注解用于方法的覆写上,它在编译期有效,也就是Java编译器在编译时会根据该注解检查是否真的是覆写,如果不是就报错,拒绝编译。  该注解很大程度解决我们的误写问...

提高你的Java代码质量吧:使用valueof前必须进行校验

一、分析  每个枚举都是java.lang.Enum的子类,都可以访问Enum类提供的方法,比如hashCode、name、valueOf等,其中valueOf方法会把一个String类型的名称...

提高你的Java代码质量吧:小心switch带来的空值异常

一、分析  使用枚举定义常量时,会有伴有大量的switch语句判断,目的是为每个枚举解释其行为。  我们知道,目前的Java的switch语句只能判断byte、short、char、int类型...

提高Java代码质量的Eclipse插件之Checkstyle的使用详解

CheckStyle是SourceForge下的一个项目,提供了一个帮助JAVA开发人员遵守某些编码规范的工具。它能够自动化代码规范检查过程,从而使得开发人员从这项重要但是枯燥的任务中解脱出来。 ...
  • jjr520
  • jjr520
  • 2014年12月20日 19:51
  • 294
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:提高你的Java代码质量吧:用整数类型处理货币
举报原因:
原因补充:

(最多只允许输入30个字)