首页 > 其他分享 >BigInteger和BigDecimal18

BigInteger和BigDecimal18

时间:2023-03-20 14:33:38浏览次数:36  
标签:BigDecimal18 BigInteger scale BigDecimal println new out

BigInteger

在Java中,由CPU原生提供的整型最大范围是64位​​long​​型整数。使用​​long​​型整数可以直接通过CPU指令进行计算,速度非常快。

如果我们使用的整数范围超过了​​long​​型怎么办?这个时候,就只能用软件来模拟一个大整数。​​java.math.BigInteger​​就是用来表示任意大小的整数。​​BigInteger​​内部用一个​​int[]​​数组来模拟一个非常大的整数:

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

对​​BigInteger​​做运算的时候,只能使用实例方法,例如,加法运算:

BigInteger i1 = new BigInteger("1234567890");
BigInteger i2 = new BigInteger("12345678901234567890");
BigInteger sum = i1.add(i2); // 12345678902469135780

和​​long​​型整数运算比,​​BigInteger​​不会有范围限制,但缺点是速度比较慢。

也可以把​​BigInteger​​转换成​​long​​型:

BigInteger i = new BigInteger("123456789000");
System.out.println(i.longValue()); // 123456789000
System.out.println(i.multiply(i).longValueExact()); // java.lang.ArithmeticException: BigInteger out of long range

使用​​longValueExact()​​方法时,如果超出了​​long​​型的范围,会抛出​​ArithmeticException​​。

​BigInteger​​和​​Integer​​、​​Long​​一样,也是不可变类,并且也继承自​​Number​​类。因为​​Number​​定义了转换为基本类型的几个方法:

  • 转换为​​byte​​:​​byteValue()​
  • 转换为​​short​​:​​shortValue()​
  • 转换为​​int​​:​​intValue()​
  • 转换为​​long​​:​​longValue()​
  • 转换为​​float​​:​​floatValue()​
  • 转换为​​double​​:​​doubleValue()​

因此,通过上述方法,可以把​​BigInteger​​转换成基本类型。如果​​BigInteger​​表示的范围超过了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的。如果需要准确地转换成基本类型,可以使用​​intValueExact()​​、​​longValueExact()​​等方法,在转换时如果超出范围,将直接抛出​​ArithmeticException​​异常。

如果​​BigInteger​​的值甚至超过了​​float​​的最大范围(3.4x1038),那么返回的float是什么呢?

// BigInteger to float
import java.math.BigInteger;

 Run

小结

​BigInteger​​用于表示任意大小的整数;

​BigInteger​​是不变类,并且继承自​​Number​​;

将​​BigInteger​​​转换成基本类型时可使用​​longValueExact()​​等方法保证结果准确。

和​​BigInteger​​​类似,​​BigDecimal​​可以表示一个任意大小且精度完全准确的浮点数。

BigDecimal bd = new BigDecimal("123.4567");
System.out.println(bd.multiply(bd)); // 15241.55677489

​BigDecimal​​用​​scale()​​表示小数位数,例如:

BigDecimal d1 = new BigDecimal("123.45");
BigDecimal d2 = new BigDecimal("123.4500");
BigDecimal d3 = new BigDecimal("1234500");
System.out.println(d1.scale()); // 2,两位小数
System.out.println(d2.scale()); // 4
System.out.println(d3.scale()); // 0

通过​​BigDecimal​​的​​stripTrailingZeros()​​方法,可以将一个​​BigDecimal​​格式化为一个相等的,但去掉了末尾0的​​BigDecimal​​:

BigDecimal d1 = new BigDecimal("123.4500");
BigDecimal d2 = d1.stripTrailingZeros();
System.out.println(d1.scale()); // 4
System.out.println(d2.scale()); // 2,因为去掉了00

BigDecimal d3 = new BigDecimal("1234500");
BigDecimal d4 = d3.stripTrailingZeros();
System.out.println(d3.scale()); // 0
System.out.println(d4.scale()); // -2

如果一个​​BigDecimal​​的​​scale()​​返回负数,例如,​​-2​​,表示这个数是个整数,并且末尾有2个0。

可以对一个​​BigDecimal​​设置它的​​scale​​,如果精度比原始值低,那么按照指定的方法进行四舍五入或者直接截断:

import java.math.BigDecimal;
import java.math.RoundingMode;

 Run

对​​BigDecimal​​做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断:

BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("23.456789");
BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP); // 保留10位小数并四舍五入
BigDecimal d4 = d1.divide(d2); // 报错:ArithmeticException,因为除不尽

还可以对​​BigDecimal​​做除法的同时求余数:

import java.math.BigDecimal;

 Run

调用​​divideAndRemainder()​​方法时,返回的数组包含两个​​BigDecimal​​,分别是商和余数,其中商总是整数,余数不会大于除数。我们可以利用这个方法判断两个​​BigDecimal​​是否是整数倍数:

BigDecimal n = new BigDecimal("12.75");
BigDecimal m = new BigDecimal("0.15");
BigDecimal[] dr = n.divideAndRemainder(m);
if (dr[1].signum() == 0) {
// n是m的整数倍
}

比较BigDecimal

在比较两个​​BigDecimal​​的值是否相等时,要特别注意,使用​​equals()​​方法不但要求两个​​BigDecimal​​的值相等,还要求它们的​​scale()​​相等:

BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("123.45600");
System.out.println(d1.equals(d2)); // false,因为scale不同
System.out.println(d1.equals(d2.stripTrailingZeros())); // true,因为d2去除尾部0后scale变为2
System.out.println(d1.compareTo(d2)); // 0

必须使用​​compareTo()​​方法来比较,它根据两个值的大小分别返回负数、正数和​​0​​,分别表示小于、大于和等于。

 总是使用compareTo()比较两个BigDecimal的值,不要使用equals()!

如果查看​​BigDecimal​​的源码,可以发现,实际上一个​​BigDecimal​​是通过一个​​BigInteger​​和一个​​scale​​来表示的,即​​BigInteger​​表示一个完整的整数,而​​scale​​表示小数位数:

public class BigDecimal extends Number implements Comparable<BigDecimal> {
private final BigInteger intVal;
private final int scale;
}

​BigDecimal​​也是从​​Number​​继承的,也是不可变对象。

小结

​BigDecimal​​用于表示精确的小数,常用于财务计算;

比较​​BigDecimal​​的值是否相等,必须使用​​compareTo()​​而不能使用​​equals()​​。

标签:BigDecimal18,BigInteger,scale,BigDecimal,println,new,out
From: https://blog.51cto.com/u_15692628/6132757

相关文章

  • 大数运算(BigInteger)与进制转换
    1前言Java提供了BigInteger(大整数)类和BigDecimal(大浮点数)类用于大数运算,这两个类都继承自Number类(抽象类)。由于BigInteger在大数运算中更常见,本博客只介绍BigInt......
  • API(BigInteger,BigDecimal)
    BigInteger的对象一旦创建,内部的值不会发生改变,如果参与运算,则会产生一个新的BigIneger对象来接收如果BigInteger的值没有超过long的范围,可以用静态方法获取//静态方法......
  • 棋盘放麦子 --------- 大整数(BigInteger详解)
    BigInteger类用java.math包中的BigInteger类的对象,可以使用构造方法publicBigInteger(Stringval)构造一个十进制的BigInteger对象。该构造方法可以发生NumberFormat......
  • Java大数字运算(BigInteger类和BigDecimal类)
    要使用BigInteger类,首先要创建一个BigInteger对象。BigInteger类提供了很多种构造方法,其中最直接的一种是参数以字符串形式代表要处理的数字。这个方法语法格式如下:......
  • 第十一章《Java实战常用类》第2节:BigInteger类和BigDecimal类
    ​编写Java代码的过程中总是要和数字打交道。通常情况下,程序员使用Java语言所提供的int、long、float、double这些基础数据类型的变量就能存储数字。但有的时候程序中会使用......
  • 大数处理-BigInteger 和 BigDecimal 类
    1.BigInteger和BigDecimal类应用场景BigInteger适合保存比较大的整型;BigDecimal适合保存精度更高的浮点型(小数);2.BigInteger和BigDecimal常见方法publi......
  • java.sql.SQLException: java.lang.ClassCastException:java.math.BigInteger cannot
    错误原因:由于在IDEA中导入的驱动包的版本和数据库的版本不匹配解决方案:​​数据库官网中下载与数据库配套的Jar包,重新导入就可以了​官网:​​https://dev.mysql.com/downloa......
  • BigInteger,BigDecimal
    BigInteger方法名说明publicBigInteger(intnum,Randomrnd)获取随机大整数,范围:[0~2的num次方-1]publicBigInteger(Stringval)获取指定的大整数......
  • BigInteger精讲
    BigInteger初识在java的整数类型里面,byte为8位,short为16位,int为32位,long为64位。正因为这些数值的二进制位数已经固定,所以它们能表示的数值大小就有一定的范围限制。如......