Java大数类BigDecimal及八种舍入模式的介绍
BigDecimal的引入
在利用Java编程语言开发银行、金融类等需要对数值进行高精度计算的软件时,我们经常使用BigDecimal和BigInteger这两个大数据类,而不是常见的int、long、float、double类型,特别是在处理浮点型数据。
我们先看一下使用基础数据类型double进行计算并打印结果的一个代码演示:
public class MainClass {
public static void main(String[] args) {
System.out.println(0.02+0.01);
System.out.println(0.05+0.01);
}
}
结果如下:
0.03
0.060000000000000005
问题来了,为什么会出现第二种结果的数据呢?根本原因还是我们的计算机是由二进制的,而二进制是没办法来精确表示一个浮点数,CPU采用“尾数和指数”的方式(科学计数法)表达浮点数的时候存在一定的误差。所以,当对数据精度要求比较高的时候,还是需要采用BigDecimal类,尽管计算速度上稍微慢了一些。
BigDecimal的使用
创建一个BigDecimal对象有构造函数和公有静态方法(BigDecimal.valueOf)两种方式,需要注意两点:
构造函数包含使用基本数据类型和字符串作为参数的两种形式,推荐使用后者,如:
new BigDecimal(Double.valueOf(0.09))。大家可以尝试一下,System.out.println(new BigDecimal(0.06).toString());语句的输出结果是:0.059999999999999997779553950749686919152736663818359375Decimal打印日志或向基本数据类型转换时,尽量使用它提供的公有方法xxxValue(),比如doubleValue(),而不是简单粗暴的一个toString()。
BigDecimal舍入模式
尽管数据库存储的是一个高精度的浮点数,但是通常在应用中展示的时候往往需要限制一下小数点的位数,比如两到三位小数即可,这时就需要使用到setScale(int newScale, int roundingMode)函数,作为BigDecimal的公有静态变量,舍入模式(Rounding Mode)的运算规则比较多,公有八种,这里作个说明,官方文档也有介绍。
ROUND_UP
向远离零的方向舍入。舍弃非零部分,并将非零舍弃部分相邻的一位数字加一。ROUND_DOWN
向接近零的方向舍入。舍弃非零部分,同时不会非零舍弃部分相邻的一位数字加一,采取截取行为。ROUND_CEILING
向正无穷的方向舍入。如果为正数,舍入结果同ROUND_UP一致;如果为负数,舍入结果同ROUND_DOWN一致。注意:此模式不会减少数值大小。ROUND_FLOOR
向负无穷的方向舍入。如果为正数,舍入结果同ROUND_DOWN一致;如果为负数,舍入结果同ROUND_UP一致。注意:此模式不会增加数值大小。ROUND_HALF_UP
向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。如果舍弃部分>= 0.5,则舍入行为与ROUND_UP相同;否则舍入行为与ROUND_DOWN相同。这种模式也就是我们常说的我们的“四舍五入”。ROUND_HALF_DOWN
向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则为向下舍入的舍入模式。如果舍弃部分> 0.5,则舍入行为与ROUND_UP相同;否则舍入行为与ROUND_DOWN相同。这种模式也就是我们常说的我们的“五舍六入”。ROUND_HALF_EVEN
向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则相邻的偶数舍入。如果舍弃部分左边的数字奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意:在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况,如果前一位为奇数,则入位,否则舍去。ROUND_UNNECESSARY
断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。
下面,举个例子说明一下不同舍入模式下的数值计算结果,保留一位小数:
| INPUT_NUM | UP | DOWN | CEILING | FLOOR | HALF_UP | HALF_DOWN | HALF_EVEN | UNNECESSARY |
|---|---|---|---|---|---|---|---|---|
| 5.5 | 6 | 5 | 6 | 5 | 6 | 5 | 6 | Exception |
| 2.5 | 3 | 2 | 3 | 2 | 3 | 2 | 2 | Exception |
| 1.6 | 2 | 1 | 2 | 1 | 2 | 2 | 2 | Exception |
| 1.1 | 2 | 1 | 2 | 1 | 1 | 1 | 1 | Exception |
| 1.0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | Exception |
| -1.0 | -1 | -1 | -1 | -1 | -1 | -1 | -1 | Exception |
| -1.1 | -2 | -1 | -1 | -2 | -1 | -1 | -1 | Exception |
| -1.6 | -2 | -1 | -1 | -2 | -2 | -2 | -2 | Exception |
| -2.5 | -3 | -2 | -2 | -3 | -3 | -2 | -2 | Exception |
| -5.5 | -6 | -5 | -5 | -6 | -6 | -5 | -6 | Exception |
原文地址:https://blog.csdn.net/growing_tree/article/details/51888689
Java大数类BigDecimal及八种舍入模式的介绍的更多相关文章
- Java中BigDecimal的8种舍入模式是怎样的
Java中BigDecimal的8种舍入模式是怎样的?下面长沙欧柏泰克软件学院和大家一起来学习下吧: java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecima ...
- Java中BigDecimal的8种舍入模式
java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecimal 由任意精度的整数非标度值和32位的整数标度(scale)组成. 如果为零或正数,则标度是小数点后的位 ...
- Java常用类之【八种基本数据类型】
一.装箱和拆箱 装箱:将基本数据类型包装为对应的包装类对象 拆箱:将包装类对象转换成对应的基本数据类型 JDK5.0中为基本数据类型提供了自动装箱(boxing).拆箱(unboxing)功能 二.八 ...
- JAVA大数类
JAVA大数类api http://man.ddvip.com/program/java_api_zh/java/math/BigInteger.html#method_summary 不仅仅只能查J ...
- ZOJ3477&JAVA大数类
转:http://blog.csdn.net/sunkun2013/article/details/11822927 import java.util.*; import java.math.BigI ...
- c++ 类的默认八种函数
c++ 类的默认八种函数 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #incl ...
- ST MCU_GPIO的八种工作模式详解。
补充: N.P型的区别,就是一个为正电压启动(NMOS),一个为负电压启动(PMOS) GPIO的八种工作模式详解 浮空输入_IN_FLOATING带上拉输入_IPU带下拉输入_IPD模拟输入_AIN ...
- Java 设计模式系列(十八)备忘录模式(Memento)
Java 设计模式系列(十八)备忘录模式(Memento) 备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式.备忘录对象是一个用来存储另外一个对象内部状态 ...
- Java大数类介绍
java能处理大数的类有两个高精度大整数BigInteger 和高精度浮点数BigDecimal,这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math. ...
随机推荐
- JavaSE_05_反射
1.什么是反射? Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性.对于任何一个对象,我们都能够对它的方法和属性进行调用.我们把这种动态获取对象信息和调用对象方法的 ...
- 【DM8168学习笔记5】EZSDK目录结构
EZSDK5.02的目录结构与之前的版本不同,之前的版本各个组件都放在/ezsdk目录下,5.02做了整合. 之前版本:(图片摘自:3.DM816x_1-day_Workshop-Getting_St ...
- OpenCV2.4和OpenCV3之间函数的转变
OpenCV3里面没有自带opencv-contrib,需要自己手动安装,也很简单,直接在命令行里面打:pip install opencv-contrib-python 就能安装好了 OpenCV3 ...
- LA3905 Meteor
https://vjudge.net/problem/UVALive-3905 计算出每个点在相框中的时间段,扫描线做即可 关键在如何快速计算每个点在相框中的时间段.对每个点进行运动分解,进入的时间L ...
- [转]web计时机制——performance对象
页面性能一直都是Web开发人员比较关注的领域.但在实际应用中,度量页面性能的指标,是javascript的Date对象.Web Timing API改变了这个局面,让开发人员通过javascript就 ...
- 多机MySQL一主双从详细安装主从复制
多机MySQL一主双从详细安装 一.复制的工作原理 要想实现AB复制,那么前提是master上必须要开启二进制日志 1.首先master将数据更新记录到二进制日志文件 2.从slave start开始 ...
- html转换成pdf
指定html转换成pdf 安装插件: npm install --save html2canvas npm install jspdf --save 引入 plugins/ htmlToPdf.js ...
- linux 关于网络接口及配置工具说明
在Linux操作系统中配置网络接口,一般是通过网络配置工具实现的,但最终目的还是通过网络配置工具来达到修改与网络相关的配置文件而起作用的.由此说来,我们配置网络可以直接修改配置文件. 比如网络网络接口 ...
- 门诊叫号系统系列-1.语音叫号 .net c#
最近收到一个需求,朋友诊室需要做到门诊叫号,流程如下:病人选择医生-刷身份证排队-医生点击病人姓名叫号. 经过团队的努力,一个简易的门诊叫号系统已经完成.现在把各个功能记录下来,方便以后查看. 1.语 ...
- 低价替代Vector CANoe CAN总线适配解决方案支持所有USBCAN(周立功CAN、PCAN、Kvaser、ValueCAN、NI CAN)
在汽车通信领域CAN总线使用非常广泛,最强大的工具有Vector Case(10WRMB).Pcan(2KRMB),ZLGCAN(1.5KRMB),KVASER(2KRMB).ValueCAN(4KR ...