提高你的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  ...
  • p106786860
  • p106786860
  • 2013年07月16日 11:15
  • 3125

Java NumberFormat数字、货币值和百分数等的格式化处理

Java数字、货币值和百分数等的格式化处理 博客分类: JAVA JAVA数字格式化DecimalFormat  如果我们用下列语句输出一个数 System.out.println(1234...
  • qq_26869449
  • qq_26869449
  • 2016年06月06日 09:31
  • 13472

iOS开发中高精度数值(货币)计算

对知识的深入,很大程度上取决于需求。最近在做一个P2P金融理财类的APP,其中对数值精度的要求很高,使用浮点型和双精度型表示,不能达到规定的精度要求。于是,从网上搜索相关能使Objective-C表示...
  • TQWei00001
  • TQWei00001
  • 2016年11月18日 17:16
  • 1380

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

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

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

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

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

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

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

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

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

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

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

一、分析  在Java运算中的类型转换,是先运算在进行类型转换的。具体场景如下。 二、场景  在如下程序中:  public class Client{ public sta...
  • p106786860
  • p106786860
  • 2013年07月17日 09:44
  • 2602

提高你的Java代码质量吧:提倡异常封装

一、分析  Java语言的异常处理机制可以确保程序的健壮性,提高系统的开发效率,但是Java API提供的异常都是比较低级(这里的低级指的是“低级别的异常”),只有开发人员才能看的懂,才明白发生了...
  • AlbenXie
  • AlbenXie
  • 2017年04月17日 18:33
  • 335
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:提高你的Java代码质量吧:用整数类型处理货币
举报原因:
原因补充:

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