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:不可变 ...
随机推荐
- Ubuntu中右击出现终端
1 root用户 $sudo apt-get install nautilus-open-terminal 2重启 3ok
- linux mplayer 播放yuv格式 (转载)
转自:http://blog.csdn.net/ly0303521/article/details/38713791 在mplayer中查看YUV格式的图片或视频,可使用如下命令: mplayer - ...
- nodejs实现百度实时推送
想要加快百度收录,肯定免不了链接提交吧,当然链接提交的方式有很多种,今天来说一下百度的实时推送.. 第一次看到这post请求确实有点萌逼,我自己是做前端的对后台接触确实不多,见到的前端发送post请求 ...
- Codeforces - 1114B - Yet Another Array Partitioning Task - 构造 - 排序
https://codeforces.com/contest/1114/problem/B 一开始叫我做,我是不会做的,我没发现这个性质. 其实应该很好想才对,至少要选m个元素,其中m个作为最大值,从 ...
- thrift配置——windows客户端与linux服务端通信(C++)
windows客户端: 1.首先要安装boost库 下载源文件 2.安装boost之前先要安装python-3.4.0.amd64,很多地方没有说,弄了很久 3.运行bootstrap.bat 生成b ...
- 【Nginx】解决Post请求变Get的问题
默认情况下Nginx会把post请求做一次重定向操作,然后后端收到的就成了Get请求,还会导致一些参数的遗漏. 日志如下: 172.16.1.108 - - [11/Jan/2019:18:27:09 ...
- 跟我一起玩Win32开发(25):监视剪贴板
自从郭大侠和蓉儿离开桃花岛后,最近岛比较寂静,有一种“门前冷落鞍马稀”的感觉.于是,老邪就拿出<九阴真经>认真阅读,同时用迅雷下载经典大剧<汉武大帝>晚上睡觉前看上几集,老邪一 ...
- Codeforces 1107E(区间dp)
用solve(l, r, prefix)代表区间l开始r结束.带了prefix个前缀str[l](即l前面的串化简完压缩成prefix-1个str[l],加上str[l]共有prefix个)的最大值. ...
- 洛谷 P1199 三国游戏
参考:Solution_ID:17 题解 更新时间: 2016-11-13 21:01 这道题要求最后得到的两方的默契值最大的武将,小涵的默契值大于计算机,首先,我们这个解法获胜的思路是,每个武将对应 ...
- BFS Codeforces Round #297 (Div. 2) D. Arthur and Walls
题目传送门 /* 题意:问最少替换'*'为'.',使得'.'连通的都是矩形 BFS:搜索想法很奇妙,先把'.'的入队,然后对于每个'.'八个方向寻找 在2*2的方格里,若只有一个是'*',那么它一定要 ...