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 对象

BigDecimal num1 = new BigDecimal(0.1);
BigDecimal num2 = new BigDecimal("0.1");

System.out.println(num1);	// 0.1000000000000000055511151231257827021181583404541015625
System.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()

转成长整型

BigDecimal num1 = new BigDecimal("0.01234");
BigDecimal num2 = new BigDecimal("0.56789");

-------------------------------------------------------------------

System.out.println(num1.add(num2));
System.out.println(num1.subtract(num2));
// 小数保留6位,四舍五入
System.out.println(num1.multiply(num2,new MathContext(6, RoundingMode.HALF_UP)));
// 小数保留4位,直接截取
System.out.println(num1.divide(num2,new MathContext(4,RoundingMode.DOWN)));

// 0.58023
// -0.55555
// 0.00700776
// 0.02172
    
-------------------------------------------------------------------    
    
BigDecimal num1 = new BigDecimal("0.123");
BigDecimal num2 = new BigDecimal("0.123000");

System.out.println(num1.equals(num2));
System.out.println(num1.compareTo(num2));

// false
// 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)

BigInteger num1 = new BigInteger("1234567890");
System.out.println(num1.pow(5));	// 2867971860299718107233761438093672048294900000

BigInteger num2 = new BigInteger("123456");
long num3 = num2.longValue();
System.out.println(num3);	// 123456

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 单点登录

    单点登录(Single Sign On),在多个互相信任的Web站点中,只要登录过其中一个,那么其他的站点都可以直接访问而不用登录。举个栗子:淘宝和天猫是两个W...

    晚上没宵夜
  • Maven

    用着maven自动化构建没什么感觉,当要自己构建稍微复杂点的项目结构时就发现知识储备不足了

    晚上没宵夜
  • Docker

    以前我们开发项目有专门的开发环境,做测试时有测试环境,而产品上线就会有生产环境,这个过程经常要迁移项目,不同的环境配置可能导致不可预估的错误,要经常性的改动

    晚上没宵夜
  • Java中的BigDecimal类你了解多少?

    可以看到在Java中进行浮点数运算的时候,会出现丢失精度的问题。那么我们如果在进行商品价格计算的时候,就会出现问题。很有可能造成我们手中有0.06元,却无法购买...

    用户1516716
  • 【答疑解惑】Java中的高精度数字

    前几天网友在群里有问BigDecimal能直接赋值吗?就像使用基本数据类型那样,答案是不能。 Java中的基本数据类型有的时候是不能满足实际编程需要的,特别是在...

    程序员互动联盟
  • Java开发中商业计算请务必使用BigDecimal来进行计算!

    今天群里一个初级开发者问为什么测试人员测出来他写的价格计算模块有计算偏差的问题,他检查了半天也没找出问题。这里小胖哥要提醒你,商业计算请务必使用`BigDeci...

    码农小胖哥
  • 金钱要使用BigDecimal数据类型(使用double的已经被公司开除了)

    可以看到在Java中进行浮点数运算的时候,会出现丢失精度的问题。那么我们如果在进行商品价格计算的时候,就会出现问题。很有可能造成我们手中有0.06元,却无法购买...

    全栈自学社区
  • 为什么阿里巴巴禁止使用BigDecimal的equals方法做等值比较?

    BigDecimal,相信对于很多人来说都不陌生,很多人都知道他的用法,这是一种java.math包中提供的一种可以用来进行精确运算的类型。

    敖丙
  • BigDecimal大小判断

    equals源码: public boolean equals(Object anObject) {//name2传入equals方法,anObject指向n...

    居士
  • BigDecimal,BigInteger 学习以及简单示例

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

扫码关注云+社区

领取腾讯云代金券