"Big"数据类助力大型数据运算 | 带你学《Java语言高级特性》之二十一

简介: 随着科技的发展,计算机对运算的要求变得越来越高,传统的float甚至double已经无法满足。为了解决这类问题,出现了BigInteger、BigDecimal两个操作大数字的类,本节将对这两个类进行具体介绍。

上一篇:Math、Random类为你展现数学之美 | 带你学《Java语言高级特性》之二十

随着科技的发展,计算机对运算的要求变得越来越高,传统的float甚至double已经无法满足。为了解决这类问题,出现了BigInteger、BigDecimal两个操作大数字的类,本节将对这两个类进行具体介绍。

【本节目标】
通过阅读本节内容,你将了解到BigInteger、BigDecimal两个类的相关内容,学会其兑现的简单创建与方法调用,并能够自行开发一些方法完成大数字运算时的性能调优。

大数字操作类

在进行数学计算的过程里面还有一个大数字的操作类,可以实现海量数字的计算(能提供的也只是基础计算),现在假设一个数字很大,超过了double的范围,那么这个时候并没有任何一种数据类型可以保存下此类的内容,最早的时候只能通过String保存。

String strA="120";
String strB="230";

如果现在想要进行加法计算,那么就需要逐位拆分,每一位自己计算,而后自己独立控制进位处理,那么这样的开发难度是非常高的,所以为了解决这类问题,提供有两个大数字的操作类:BigInteger、BigDecimal。

image.png
大数字类

之前分析了,当数字很大的时候只能利用字符串描述数字操作,所以这一点可以观察两个大数字操作类的构造方法:

  • BigInteger类构造:public BigInteger​(String val);
  • BigDecimal类构造: public BigDecimal​(String val);

范例:使用BigInteger实现四则运算

public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        BigInteger bigA=new BigInteger("234234234234234234");
        BigInteger bigB=new BigInteger("23423423");
        System.out.println("加法操作:"+bigA.add(bigB));    //234234234257657657
        System.out.println("减法操作:"+bigA.subtract(bigB));    //234234234210810811
        System.out.println("乘法操作:"+bigA.multiply(bigB));  //5486567549549549544062982
        System.out.println("除法操作:"+bigA.divide(bigB));      //10000000180
        
    }
}

需要注意的是,虽然提供有大数字操作类,但是整体的操作之中还是需要考虑到一个性能问题。
范例:观察性能问题

public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        BigInteger bigA=new BigInteger("234234234234234234");
        System.out.println(bigA.pow(Integer.MAX_VALUE));
    }
}

image.png
cpu处理

此时的计算过程是非常缓慢的,所以任何的电脑是有极限的。
既然在进行数学除法的时候有可能无法进行整除处理,那么就可以使用其他的除法计算来求出余数:

  • 求余:public BigInteger[] divideAndRemainder​(BigInteger val);数组第一个元素为商,第二个为余数;

范例:求余除法

public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        BigInteger bigA = new BigInteger("234234234234234234");
        BigInteger bigB = new BigInteger("23423423");
        BigInteger[] result = bigA.divideAndRemainder(bigB);
        System.out.println("商:" + result[0] + "、余数:" + result[1]);//商:100000000180、余数:18018094
    }
}

如果在开发中真进行计算的时候,该计算没有超过基本数据类型所包含的位数强烈不建议使用大数字类,因为这种计算性能很差。

BigDecimal操作形式和BigInteger是非常类似的,都有基础的数学支持。
范例:使用BigDecimal计算

public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        BigDecimal bigA = new BigDecimal("32890234890");
        BigDecimal bigB = new BigDecimal("1892039");
        System.out.println("加法计算:"+bigA.add(bigB));   //32892126929
        BigDecimal result[] = bigA.divideAndRemainder(bigB);
        System.out.println("除法计算:商:" + result[0] + "、余数:" + result[1]);//商:17383、余数:920953
    }
}

但是在使用BigDecimal的时候有一个数据进位的问题,在这个类里面定义有如下的除法计算:

  • 除法计算:public BigDecimal divide​(BigDecimal divisor, int scale, RoundingMode roundingMode);

范例:使用BigDecimal实现四舍五入处理

class MathUtil {
    private MathUtil() {}
    /**
     * 实现数据的四舍五入操作
     *
     * @param num   要进行四舍五入操作的是数字
     * @param scale 四舍五入保留的小数位数
     * @return 四舍五入处理后的结果
     */
    public static double round(double num, int scale) {
        return new BigDecimal(num).divide(new BigDecimal(1.0), scale, RoundingMode.HALF_UP).doubleValue();
    }
}
public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        System.out.println(MathUtil.round(19.6352, 2));  //19.64
    }
}

Math的处理由于使用的都是基本数据类型,所以性能一定要高于大数字处理类。

想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:一文教你掌握日期操作 | 带你学《Java语言高级特性》之二十二
更多Java面向对象编程文章查看此处

相关文章
|
7月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
284 4
|
7月前
|
Java
Java语言实现字母大小写转换的方法
Java提供了多种灵活的方法来处理字符串中的字母大小写转换。根据具体需求,可以选择适合的方法来实现。在大多数情况下,使用 String类或 Character类的方法已经足够。但是,在需要更复杂的逻辑或处理非常规字符集时,可以通过字符流或手动遍历字符串来实现更精细的控制。
447 18
|
7月前
|
IDE JavaScript Java
在Java 11中,如何处理被弃用的类或接口?
在Java 11中,如何处理被弃用的类或接口?
336 5
|
7月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
350 2
|
7月前
|
Java Go 开发工具
【Java】(8)正则表达式的使用与常用类分享
正则表达式定义了字符串的模式。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
477 1
|
7月前
|
存储 Java 程序员
【Java】(6)全方面带你了解Java里的日期与时间内容,介绍 Calendar、GregorianCalendar、Date类
java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用当前日期和时间来初始化对象。Date( )第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
304 0
|
7月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
343 2
|
Java 开发者 Windows
Java 数据类型划分(字符型)|学习笔记
快速学习 Java 数据类型划分(字符型)
244 0
|
Java 开发者
Java 数据类型划分(整型类型)|学习笔记
快速学习 Java 数据类型划分(整型类型)
188 0
|
Java 开发者
Java 数据类型划分(初见 String 类)|学习笔记
快速学习 Java 数据类型划分(初见 String 类)
196 0