BigDecimal和BigInteger


在看《阿里巴巴开发手册》里面提到浮点数之间的等值判断不要用 ==,而是指定误差范围或用BigDecimal,然后才记忆起备忘录里BigDecimal还没写呢,就这篇幅写了一星期,因为实习完全没有时间啊啊啊啊啊啊啊啊

1. BigDecimal介绍

背景

我们知道计算机都是以二进制的形式存储数据的,而我们日常则是使用十进制,那么我们的 数字 存进计算机则需一个进制转换的过程,这过程就会损失精度的,就导致浮点数不能用等值判断

原因

十进制的0.1转换 成二进制为 0.00011001...,是无限小数,计算机存不下只能截取。后面这截取的无限小数还原成十进制就会损失精度不准确,不能用等值判断了

救星

BigDecimal的横空出世是为了解决浮点数的精度问题,其全限定类名为 java.math.BigDecimal,BigDecimal是一个对象,代表着不变的,任意精度的带符号的十进制数字,我们要使用该对象的方法来进行加减乘除的操作

原理

既然十进制小数转成二进制会损失精度,那么把十进制小数扩大成整数再转成二进制则会保持精度了

2. BigDecimal基本使用

2.1 常见构造方法

方法

描述

BigDecimal(int val)

将int转换成BigDecimal

BigDecimal(int val, MathContext mc)

根据上下设置进行舍入

BigDecimal(long val)

将long转换成BigDecimal

BigDecimal(double)

将double转换成BigDecimal

BigDecimal(String)

将String转换成BigDecimal

MathContext(int setPrecision, RoundingMode setRoundingMode)

上下文取舍(精度,舍入模式)

阿里手册规约:禁止使用构造方法 BigDecimal(double)的方式把 double 值转化为 BigDecimal 对象

1BigDecimal num1 = new BigDecimal(0.1); 2BigDecimal num2 = new BigDecimal("0.1"); 3 4System.out.println(num1); // 0.1000000000000000055511151231257827021181583404541015625 5System.out.println(num2); // 0.1

因为浮点数并不是一个准确的值,而String类型的就确定

2.2 常用方法

方法

描述

abs()

返回一个绝对值BigDecimal对象

scale()

小数位数,包含末尾零。返回负数表示是一个正数,且有负数位0

stripTrailingZeros()

除去末尾的零,包含整数

add(BigDecimal augend)

被加数

add(BigDecimal augend, MathContext mc)

根据上下文取舍

subtract(BigDecimal subtrahend)

被减数

multiply(BigDecimal multiplicand)

被乘数

divide(BigDecima divisor, int roundingMode)

被除数,要指定上下文取舍,否则报错

divideAndRemainder(BigDecimal divisor)

求余

compareTo(BigDecimal val)

比较数值大小,equals要求scale()相同,且值相同

toString()

转成字符串

intValue()

转成整型

longValue()

转成长整型

1BigDecimal num1 = new BigDecimal("0.01234"); 2BigDecimal num2 = new BigDecimal("0.56789"); 3 4------------------------------------------------------------------- 5 6System.out.println(num1.add(num2)); 7System.out.println(num1.subtract(num2)); 8// 小数保留6位,四舍五入 9System.out.println(num1.multiply(num2,new MathContext(6, RoundingMode.HALF_UP))); 10// 小数保留4位,直接截取 11System.out.println(num1.divide(num2,new MathContext(4,RoundingMode.DOWN))); 12 13// 0.58023 14// -0.55555 15// 0.00700776 16// 0.02172 17 18------------------------------------------------------------------- 19 20BigDecimal num1 = new BigDecimal("0.123"); 21BigDecimal num2 = new BigDecimal("0.123000"); 22 23System.out.println(num1.equals(num2)); 24System.out.println(num1.compareTo(num2)); 25 26// false 27// 0

除法存在除不尽的情况,所以一定要使用上下文取舍器

BigDecimal比较用compareTo,而equals要求scale()即小数位数相同

ArithmeticException常见的算数异常

3. BigInteger

Java原生提供的最大整型是长整型,占8字节64位,范围是-9223372036854775808 ~ 9223372036854775807,如果超过了这个范围,那么可以用不可变的BigInteger对象,其原理是内部使用 int[] 数组来模拟大数

3.1 常见构造函数

函数

描述

BigInteger(byte[] val)

BigInteger(String) val)

3.2 常见方法

方法

描述

add(BigInteger) val)

加法

subtract(BigInteger val)

1BigInteger num1 = new BigInteger("1234567890"); 2System.out.println(num1.pow(5)); // 2867971860299718107233761438093672048294900000 3 4BigInteger num2 = new BigInteger("123456"); 5long num3 = num2.longValue(); 6System.out.println(num3); // 123456

我的博客即将同步至 OSCHINA 社区,这是我的 OSCHINA ID:osc_45632688,邀请大家一同入驻:https://www.oschina.net/sharing-plan/apply

本文分享 CNBlog - Howlet。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java.math.BigDecimal类的用法

在java中提供了大数字的操作类,即java.math.BinInteger类和java.math.BigDecimal类。这两个类用于高精度计算,其中BigInteger类是针对大整数的处理类,而BigDecimal类则是针对大小数的处理类。下边我们介绍BigDecimal类:BigDecimal的实现利用到了BigInteger,不同的是Big