一:简介

Java中的简单浮点数类型float和double不能够进行运算,或者运算会丢失精度,不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal

// 浮点型计算不准确示例@Testpublic void testDouble(){ // 0.060000000000000005 System.out.println(0.05+0.01); // 0.5800000000000001 System.out.println(1.0-0.42); // 401.49999999999994 System.out.println(4.015*100); // 1.2329999999999999 System.out.println(123.3/100); // 4.01 四舍五入保留两位 System.out.println(Math.round(4.015*100)/100.0);}

二:BigDecimal

BigDecimal有多种构造函数,常用的有2种,其中有一种不建议使用,就是double构造方式,建议使用String构造方式。

// 强制使用String的构造函数,double也有可能计算不太准确// 原则是使用BigDecimal并且一定要用String来够造。public BigDecimal(String val);public BigDecimal(double val);
BigDecimal也定义了几个常用的值,0、1、10,静态的,可以通过类名直接引用BigDecimal.ZEROpublic static final BigDecimal ZERO = zeroThroughTen[0]; /** * The value 1, with a scale of 0. * * @since 1.5 */ public static final BigDecimal ONE = zeroThroughTen[1]; /** * The value 10, with a scale of 0. * * @since 1.5 */ public static final BigDecimal TEN = zeroThroughTen[10];三:工具类

由于构造方法要用String对应的构造方法,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类来简化操作。

import java.math.BigDecimal;/** * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 * 确的浮点数运算,包括加减乘除和四舍五入。 */public class ArithUtil { //默认除法运算精度 private static final int DEF_DIV_SCALE = 10; /** * 提供精确的加法运算。 * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static double sub(double v1,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static double mul(double v1,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 * 小数点以后10位,以后的数字四舍五入。 * @param v1 被除数 * @param v2 除数 * @return 两个参数的商 */ public static double div(double v1,double v2){ return div(v1,v2,DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入。 * @param v1 被除数 * @param v2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1,double v2,int scale){ if(scale<0){ throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理。 * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v,int scale){ if(scale<0){ throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one,scale, BigDecimal.ROUND_HALF_UP).doubleValue(); }}

四:测试

@Testpublic void testBigDecimal(){ BigDecimal price = BigDecimal.ZERO; // 通常建议优先使用(String)构造函数 BigDecimal amount = new BigDecimal("6.66"); // 0.06 System.out.println(ArithUtil.add(0.05, 0.01)); // 0.58 System.out.println(ArithUtil.sub(1.0, 0.42)); // 401.5 System.out.println(ArithUtil.mul(4.015, 100)); // 1.233 System.out.println(ArithUtil.div(123.3, 100)); // 4.02 System.out.println(ArithUtil.round(4.015, 2)); // BigDecimal 比较大小使用compareTo方法 // public int compareTo(BigDecimal val);}

bigdecimal不保留小数_金钱要使用BigDecimal数据类型(使用double的已经被公司开除了)...相关推荐

  1. bigdecimal不保留小数_为什么 0.1 + 0.2 = 0.3,原来你不知道

    为什么这么设计(Why's THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点.对具体实现造成的影响 ...

  2. java保留小数_(转)Java保留小数位数的N中方法

    java保留两位小数问题: 方式一: 四舍五入 double   f   =   111231.5585; BigDecimal   b   =   new   BigDecimal(f); doub ...

  3. 使用bigdecimal来保留小数

    double和float精度已经非常高了,但对于一些更加精确的东西还是有所欠缺,所以也就有了精度更高的bigdecimal,只要计算机的内存更大,精确的就更准. import java.math.Bi ...

  4. sql sever avg保留小数_《数据库系统概念》笔记 (一)SQL

    SQL即结构化查询语言,这里主要介绍一下SQL的相关语法. 数据定义 SQL支持数据类型主要包括 char(n), 定长字符串 varchar(n), 可变长字符串,指定最大长度 int smalli ...

  5. java 截位法保留小数_【数量关系速算技巧】泡泡截位法专题

    资料分析都要找技巧,进行分析之类的,但是如果你对计算有所技巧的话,那么你的计算就相对简单,也会比别人快些,在节省做题时间以及做题时间的同时,还能够提高正确率. 截位法使用范围:除了加减法,其他的运算都 ...

  6. AndroidJava保留小数位数的几种写法

    1. 使用java.math.BigDecimal 2. 使用java.text.DecimalFormat 3. 使用java.text.NumberFormat 4. 使用java.util.Fo ...

  7. Java - 保留小数点后两位

    (1)使用BigDecimal ,保留小数点后两位 public static String format1(double value) {BigDecimal bd = new BigDecimal ...

  8. BigDecimal保留小数

    保留小数常见的六种方式: BigDecimal.ROUND_UP 舍入模式从零开始. 始终在非零丢弃分数之前增加数字. //12.15 向上去整,四舍五入 BigDecimal bigDecimal1 ...

  9. bigDecimal 返回前端保留小数点后两位

    详细用法 bigDecimal 返回前端保留小数点后两位问题解决 bigDecimal保留后两位小数 且 返回前端 不丢失小数点后的0 位数不够补零 通过@JsonFormat值把BigDecimal ...

最新文章

  1. metaq的简单封装dataChange解读
  2. LuoguP3183 [HAOI2016]食物链 记忆化搜索
  3. JavaScript高级程序设计-读书笔记(6)
  4. [仙吕·一半儿] 题画《翠林和鸣》
  5. Ubuntu中给eclipse和android studio添加桌面快捷图标
  6. m.2接口和nvme区别_透明款散热不好,那么ORICO 全铝NVMe固态硬盘盒了解一下?
  7. 【网络流】最大流问题(EK算法带模板,Dinic算法带模板及弧优化,ISAP算法带模板及弧优化)上下界网络流
  8. 国内APP乱象再现 京东金融APP被质疑窃取用户隐私
  9. ML for trading -cs7646-03
  10. .NET System.Web.HttpContext.Current.Request报索引超出数组界限。
  11. Manjaro下安装和美化i3wm,以及相关软件配置
  12. c标签判断true false jsp_JSP 标准标签库(JSTL) | 菜鸟教程
  13. matlab EOF程序
  14. wps excel 插入公式 整列
  15. Android 计时器
  16. 《吉他自学三月通》学习指导
  17. matlab零阶保持器的作用,MATLAB保持器的simulink仿真.ppt
  18. 【组件】Vue组件之间的通信父传子 | 子传父
  19. 思考型人格分析,思考型人格的职业发展方向
  20. 安卓期末大作业——售票APP源码和设计报告

热门文章

  1. Python基础教程:列表、字典、集合推导式
  2. Python带下划线的变量或函数命名详细介绍
  3. python 关于排序的问题
  4. Python 开发工具链全解
  5. Python教程:作用域与嵌套函数
  6. python中的及||
  7. python 将字节字符串转换成十六进制字符串
  8. python中,如何将多行进行输出,同时将行尾的换行符去掉
  9. java开放平台系统,java快速开发平台
  10. centos7 安装rabbitMq