JavaSE-30 BigDecimal类的使用
问题
Java(其他编程语言也存在类似问题)中浮点数直接进行算术运算会导致精度丢失。
示例代码:
System.out.println("1.0 - 0.9 =" + (1.0 - 0.9));
System.out.println("0.1 + 0.02 =" + (0.1 + 0.02));
System.out.println("1.013 * 100 =" + (1.013 * 100));
System.out.println("123.3 / 100 =" + (123.3 / 100));
运行结果为:

解决方案
Java提供了BigDecimal类用来解决浮点数的运算。
BigDecimal提供了大量的构造方法用于生成一个BigDecimal对象,包括把基本类型、数字字符串、数字数组构造成BigDecimal对象。
这里以double类型数字转换为BigDecimal对象进行说明。常用有三种方式将double类型数字转换为BigDecimal对象。
- BigDecimal(double value):不推荐使用。生成的数值和value是一个近似数,不精确。
- BigDecimal(String value):推荐使用。
- BigDecimal.valueOf(double value):推荐使用。可以直接把一个double类型数值转换为精确的BigDecimal对象。
BigDecimal类型提供了相应方法实现算术运算,常用方法如下表所示,具体参数可以查询API文档。
| 方法 | 方法说明 |
| add() | 相加 |
| subtract() | 相减 |
| multiply() | 相乘 |
| devide() | 相除 |
| pow() | 幂运算 |
示例代码:
BigDecimal num1 = new BigDecimal("0.05");
BigDecimal num2 = new BigDecimal("0.01");
System.out.println("0.05 + 0.01 =" + (num1.add(num2)));
System.out.println("0.05 - 0.01 =" + (num1.subtract(num2)));
System.out.println("0.05 * 0.01 =" + (num1.multiply(num2)));
System.out.println("0.05 / 0.01 =" + (num1.divide(num2)));
运行结果:

自定义浮点数计算类
项目中如果要频繁进行浮点数计算,可以自定义一个浮点数计算类。
在进行除法运算过程中,如果需要进行精度控制,可以使用divide(BigDecimal divisor, int scale, int roundingMode)方法进行精度控制。sacale表示精度,roundingMode表示舍入方式。
示例代码:
public class MyArith {
/** 定义除法运算精度 */
private static final int DEFAULT_DIV_SCALE = 10;
/** 单例模式 */
private MyArith() {
}
/** 精确加法运算 */
public static double add(double value1, double value2) {
BigDecimal b1 = BigDecimal.valueOf(value1);
BigDecimal b2 = BigDecimal.valueOf(value2);
return b1.add(b2).doubleValue();
}
/** 精确加法运算 */
public static double sub(double value1, double value2) {
BigDecimal b1 = BigDecimal.valueOf(value1);
BigDecimal b2 = BigDecimal.valueOf(value2);
return b1.subtract(b2).doubleValue();
}
/** 精确乘法运算 */
public static double mul(double value1, double value2) {
BigDecimal b1 = BigDecimal.valueOf(value1);
BigDecimal b2 = BigDecimal.valueOf(value2);
return b1.multiply(b2).doubleValue();
}
/** 精确除法运算 */
public static double div(double value1, double value2) {
BigDecimal b1 = BigDecimal.valueOf(value1);
BigDecimal b2 = BigDecimal.valueOf(value2);
// 精确到小数点后10位,四舍五入
return b1.divide(b2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/** 测试方法 */
public static void main(String[] args) {
System.out.println("0.05 + 0.01 = " + MyArith.add(0.05, 0.01));
System.out.println("1.0 + 0.42 = " + MyArith.sub(1.0, 0.42));
System.out.println("4.015 * 100 = " + MyArith.mul(4.015, 100));
System.out.println("123.3 / 99 = " + MyArith.div(123.3, 99));
}
}
运行结果:

JavaSE-30 BigDecimal类的使用的更多相关文章
- BIgInteger类和BigDecimal类的理解
第一部分: 这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math.BigInteger;和import java.math.BigDecimal; Bi ...
- Java学习——BigInteger类和BigDecimal类
Java学习——BigInteger类和BigDecimal类 摘要:本文主要学习了用于大数字运算的BigInteger类和BigDecimal类. 部分内容来自以下博客: https://www.c ...
- Java匹马行天下之JavaSE核心技术——工具类
Java匹马行天之JavaSE核心技术——工具类 一.Object类 java.lang.ObjectObject类是所有类直接或间接的父类 常用的方法: toString():以字符串形式返回对象的 ...
- JAVA集合类简要笔记 - 内部类 包装类 Object类 String类 BigDecimal类 system类
常用类 内部类 成员内部类.静态内部类.局部内部类.匿名内部类 概念:在一个类的内部再定义一个完整的类 特点: 编译之后可生成独立的字节码文件 内部类可直接访问外部类私有成员,而不破坏封装 可为外部类 ...
- BigDecimal类
如果需要精确的计算结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作. //========================================== ...
- Java大数处理类:BigInteger类和BigDecimal类
当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线 ...
- Java API —— BigDecimal类
1.BigDecimal类概述 由于在运算的时候,float类型和double很容易丢失精度,演示案例.所以,为了能精确的表示.计算浮点数,Java提供了BigDecimal 不可变的.任意精度的有 ...
- 用BigDecimal类实现Fibonacci算法
Fibonacci(N)=Fibonacii(N-1)+Fibonacci(N-2) 其中 Fibonacci(0)=0;Fibonacci(1)=1 用循环或则递归实现Fibonacci算法很简单, ...
- java.math.BigDecimal类
BigDecimal类用于高精度计算.一般的float型和Double型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到java.math.BigDecima ...
- Java基础知识强化88:BigDecimal类之BigDecimal类引入和概述 以及 BigDecimal的使用(加减乘除)
1. BigDecimal类概述: 由于在运算的时候,float类型和double很容易丢失精度.所以为了能够精确的表达.计算浮点数,Java提供了BigDecimal. BigDecimal:不可变 ...
随机推荐
- perceptron and ANN
%% Perceptron Regression close all clear %%load data x = load('ex4x.dat'); y = load('ex4y.dat'); x=o ...
- pythonchallenge 2
pythonchallenge是一个很有意思的学习python的网站,通过用程序解开一个谜,可以进入到下一个level,总共有几十个level,网址是http://www.pythonchallen ...
- linux中目录操作<1>
一.目录的权限 (1)目录文件的访问权限分为三组,分别为所有者,用户,其他.每个权限组的权限位有3个,分别为读.写.执行. 注意:可以使用stat函数得到目录文件的状态信息.权限为在stat结构中st ...
- /proc/interrupts 和 /proc/stat 查看中断的情况 (转载)
转自:http://blog.csdn.net/richardysteven/article/details/6064717 在/proc文件系统下,又两个文件提供了中断的信息. /proc/inte ...
- 洛谷 - P1004 - 方格取数 - 简单dp
https://www.luogu.org/problemnew/show/P1004 这道题分类到简单dp但是感觉一点都不简单……这种做两次的dp真的不是很懂怎么写.假如是贪心做两次,感觉又不能证明 ...
- (12)用css设计电子相册 {下}
本篇学习资料讲解: 延续上一篇的学习资料,仍然介绍 使用css对电子相册进行排版 和 侧面强调“盒子模型.标准流.浮动和定位”的重要性. 上篇学习资料介绍的“阵列模式电子相册”,如果也能 ...
- Linux下的录屏软件Kazam
发现Ubuntu下一个很好用的录屏软件kazam,Ubuntu官方源中就有. 1.安装 $ sudo apt-get install kazam 2.使用 使用很简单,除了截图,还可以录制屏幕视频.既 ...
- 日志系统:一条sql更新语句是如何执行的?--Mysql45讲笔记记录 打卡day2
下面是一个表的创建语句,这个表有一个主键id和一个整型字段c: create table t(id int primary key,c int); 如果要将 id = 2 这一行的值加 1,sql语句 ...
- SpringAOP和Spring事物管理
Spring AOP : Pointcut表达式: designators-指示器 wildcards-通配符 operators-操作符 wildcards: * -- 匹配任意数量的字符 + -- ...
- hdu1102 Constructing Roads 基础最小生成树
//克鲁斯卡尔(最小生成树) #include<cstdio> #include<iostream> #include<algorithm> using names ...