Java大数BigInteger的原理

Java BigInteger类、BigDecimal类 例如,当创建一个BigDecimal对象时,如果传入的字符串是"123.4567",那么在内部,BigDecimal会将其转换成一个整数数组,数组中的元素分别对应于'1','2','3','4','5','6','7'这些数字,并且记录下小数点后有四位数字。这个数组是按照从最低位到最高位的顺序存储的,即数组的第一个元素存储的是大整数的最低位,而最后一个元素存储的是大整数的最高位。需要注意的是,在使用BigDecimal时,需要注意其精度和舍入控制问题,以确保计算结果的准确性。的高1位为n-1)。 阅读详情

引言

在java中,整型分为Integer(4 bytes 32位)和Long(8 bytes 64位)两种类型,因此java中一个整数最多只能占64个bits,并且java中不存在无符号数,无论是Integer类型还是Long类型都是有符号数。当我们需要表示一个超过64 bits的数时,就需要用到BigInteger类型,BigInteger是java包提供的一个大数类型,它的原理就是将大数拆分成一个int[]表示,理论上该int[]数组的长度可以无限增大(大数规定int[]长度不超过1^26),该类提供了普通整型具有的所有运算方法,包括加减乘除,与或非等。本文介绍大数的构造和基本计算原理。

 

主要成员变量


    final int signum;  //符号位,1表示正数,-1表示负数,0的符号位为0

   
    final int[] mag;  //int数组,从index=0开始表示大数的最高位

     
    private int bitCount; //大数的bit个数加1,默认值为0,当需要时才会被初始化

   
    private int bitLength;

    
    private int lowestSetBit;

    
    private int firstNonzeroIntNum;

最重要的两个成员变量:signum表示大数的符号,int数组mag[]表示大数的值,mag[0]表示大数的最高位

构造方法

通过byte[]数组构造

byte[]数组可以理解为整数在内存中的表示,如:

byte[] b = {0x81,0x00,0x00,0x00} // 在内存中即为0b10000001 00000000 00000000 00000000

由byte[]数组转为大数,可以理解为将byte[]数组转为一个占用 byte.length * 8 位的大整型,byte[]是该数的补码

源码如下:

    public BigInteger(byte[] val) {
        if (val.length == 0)
            throw new NumberFormatException("Zero length BigInteger");

        if (val[0] < 0) {
            mag = makePositive(val);
            signum = -1;
        } else {
            mag = stripLeadingZeroBytes(val);
            signum = (mag.length == 0 ? 0 : 1);
        }
        if (mag.length >= MAX_MAG_LENGTH) {
            checkRange();
        }
    }

首先判断byte[0]是正数还是负数,如果byte[0]是正数,则大数的符号位signum为1,mag值为byte[]去掉前缀0;

否则大数的符号位为-1,此时mag的值是-val ,举例如下

byte[] = {0b00001000,0b00000000}  最高位是0,表示正数, 转为大数是它本身
signum = 1
mag[] = int[0] = 0b00001000_00000000 -> 4096

//////////////////////////////////////////////////////////////////////////////
byte[] = {0b10001000,0b00000000}  最高位是1,表示负数,转为大数是它的负值
signum = -1
mag[] = int[0] = 0b01111000_00000000 

Q:符号位存在的必要性?

指定符号位 BigInteger(byte[] bytes, int signum) 

当指定符号位时,无论指定1还是-1,mag[]值都是大数本身

 

位运算

分析之前先看一段关键代码,getInt方法用于获得一个大数中的每一个int的实际值,为什么要这么做?因为在构造的时候,根据符号位对mag[]的值做了转换,而位运算需要对实际值的每一位做运算,所以要把取负的数再取负还原;

/**
 * 对于符号位为正的大数,mag[]返回它本身,对于符号位为负的大数,由于在构造的时候对int值取了负,进行位运算要还原
**/
private int getInt(int n) {
        if (n < 0)
            return 0;
        if (n >= mag.length)
            return signInt();

        int magInt = mag[mag.length-n-1];

        return (signum >= 0 ? magInt :
                (n <= firstNonzeroIntNum() ? -magInt : ~magInt));
}

再来看这段代码 n <= firstNonzeroIntNum() ? -magInt : ~magInt

考虑当我们对一个数取负时做了什么操作,答案是减一取反,那么对每一个bit来说,从后往前看找到第一个非0的位,该位和它的后面的位实际上是减一取反(-),该位之前做的都是取反操作(~)

根据上述原理,firstNonzeroIntNum()方法会返回mag[]从后往前第一个非0的index,该index左边的数取反,右边的数取负

按位与 and

public BigInteger and(BigInteger val) {
        int[] result = new int[Math.max(intLength(), val.intLength())];
        for (int i=0; i < result.length; i++)
            result[i] = (getInt(result.length-i-1)
                         & val.getInt(result.length-i-1));

        return valueOf(result);
}

按位取反 not

原理是按照符号位signum将mag[]数组的每个值取其实际值,然后对该值取反

public BigInteger not() {
        int[] result = new int[intLength()];
        for (int i=0; i < result.length; i++)
            result[i] = ~getInt(result.length-i-1);

        return valueOf(result);
}

 

Java Bigdecimal使用原理详解 主要介绍了Java Bigdecimal使用原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 立即下载

相关推荐

2025年数学建模美赛(MCM)C题阅读与思考

2025年数学建模美赛(MCM)C题阅读与思考

carefreekid123的博客 7339

基础篇-BigInteger

先说说基础篇吧。谈起java基础应该是有很多很多的知识点,不是一篇两篇能够说完的。一听到java基础就能想到N多种集合的优缺点、多线程下出现的问题如何解决,java的Atomic原子操作类、jvm结构、jmm模型、jvm调优、各种循环的速度快慢(java基础语法不在复盘范围内)。 今天咱们来聊一个问题,众所周知java接受整数类型是用int和lang,但是int是4字节,long是8字节,都是有范围的,一个字节=8位二进制数,int的4字节最大就是存储的就是32位二进制。最大的数字无非也就是二进制的32.

weixin_42027340的博客 637

Lisflood

文献:基于SWMM和LISFLOOD-FP模型的居住区低影响开发模拟评价。问题:多个节点溢流同时,不行,待解决。目录下,cmd命令行。

警警的博客 2662

biginteger 原理_BigInteger实现原理

BigInteger存储大数的方式就是将数字存储在一个整型的数组中只用一个整型数组的话,如何表示一个整数的正负呢?那么就需要有一个单独的成员变量来标明该数的正负。18927348*(10^9)^2 +347389543*(10^9)+834934878,最终从整体上来看mag数组保存的是一个10^9进制的数.1、以前把数字存在字符串中,大数之间的四则运算及其它运算都是通过数组完成;2、JDK实现,...

weixin_39884738的博客 1122

QCPColorMap实现瀑布图

QCPColorMap实现真正的瀑布图

pf1873252141的博客 5268

TJA1445/TJA1465 CAN收发器硬件设计与软件配置实战指南

控制器局域网(CAN)总线是汽车电子和工业控制领域实现电子控制单元(ECU)间可靠通信的核心技术。其工作原理是将数字信号转换为差分信号进行抗干扰传输,技术价值在于构建稳定、高效的分布式实时控制系统。随着汽车电子架构向域集中式演进,对CAN总线的通信速率、网络复杂度和静态功耗提出了更高要求,这催生了支持CAN FD协议和智能电源管理的新一代高速CAN收发器。在车载网关、域控制器及工业网络节点等应用场景中,NXP的TJA1445和TJA1465系列收发器凭借其部分组网(Partial Networking)和选

weixin_29655587的博客 407

biginteger 原理_java BigInteger源码学习

在java中,有很多基本数据类型我们可以直接使用,比如用于表示浮点型的float、double,用于表示字符型的char,用于表示整型的int、short、long等。但是,拿整数来说,如果我们想要表示一个非常大的整数,比如说超过64位,那么能表示数字最大的long也无法存取这样的数字时,我们怎么办。以前的做法是把数字存在字符串中,大数之间的四则运算及其它运算都是通过数组完成。JDK也有类似的实现...

weixin_36296215的博客 982

Linux | Ubuntu18.04安装WIFI6 AX201驱动完整教程

本节介绍了如何在Ubuntu18下安装AX201驱动的教程。

九七的博客 8880

Java大数模幂运算:BigInteger.modPow原理、性能与实战

模幂运算(Modular Exponentiation)是计算大数幂后取模的核心算法,其原理基于快速幂(Binary Exponentiation)与模运算分配律,将指数按二进制展开,每步乘法后立即取模,使中间结果始终不超过模数位数。该技术将时间复杂度从O(n)降至O(log n),彻底解决了大数幂运算的内存溢出与性能瓶颈问题。在公钥密码学(如RSA加密解密、Diffie-Hellman密钥交换)、哈希校验、竞赛编程的大指数取模等场景中,模幂运算不可或缺。Java的BigInteger.modPow方法正是

weixin_32667955的博客 202

【异常】OpenClaw网关仪表盘 pairing required 报错排查与解决方案

在OpenClaw网关仪表盘页面,完成WebSocket URL、网关令牌等必填项配置后,点击「连接」按钮尝试建立网关连接时,页面下方出现红色报错提示框,核心报错内容为,无法完成网关连接建立,且该报错在令牌配置正确、网络链路通畅的场景下仍会触发。该报错常见于非本地回环地址的访问场景,包括局域网远程访问、公网域名/IP访问、云服务器部署的网关远程管理等场景,本地127.0.0.1回环地址访问通常可正常连接。

奶爸的编程之路,也就一周冷个三天 1077

基于Simulink的电机功率因数校正仿真

PF=SP​=视在功率有功功率​=cosϕ⋅Irms​I1​​(非正弦时)位移因数(cosϕ):基波电压电流相位差畸变因数(I1​/Irms​):谐波导致电流有效值增大本文带你完成了电机系统功率因数校正的Simulink仿真,实现了:✅ 理解了低功率因数的成因与危害✅ 搭建了无PFC、无源PFC、有源PFC三种对比模型✅ 掌握了Vienna整流器建模与dq解耦控制方法✅ 实现了PF与THD的自动计算与评估✅ 验证了有源PFC在PF、THD、稳定性上的全面优势。

amy_mhd的博客 154

Java大数运算:BigInteger与BigDecimal核心原理与应用

在计算机科学中,大数运算是指处理超出基本数据类型范围的数值计算。Java通过BigInteger和BigDecimal类实现任意精度的整数和浮点数运算,其核心原理基于数组存储和符号-数值表示法。这类技术在金融计算、密码学等领域尤为重要,能有效避免数值溢出和精度丢失问题。以区块链开发为例,处理加密货币金额时常规数据类型无法满足需求,必须依赖大数运算类。实际工程中需要注意对象不可变性、内存优化以及合理的舍入策略,特别是在涉及财务计算时,推荐使用String构造方式和银行家舍入法来确保精确性。

weixin_29306571的博客 332

图注意力网络(GAT)原理与代码实战案例讲解

1. 背景介绍 图注意力网络(Graph Attention Network,简称GAT)是一种基于图神经网络(Graph Neural Networks,简称GNN)的深度学习方法。它能够处理具有复杂关系的节点数据,并在多个领域取得了显著的效果,如社交网络分析、推荐系统等。 2. 核心概念与联系

AI架构师小马 2712

Java BigInteger详解:大数运算原理、实战应用与性能陷阱

在Java开发中,基本整数类型long有固定上限,一旦数值超出范围就会发生溢出,产生难以排查的脏数据。为处理任意精度的整数运算,Java提供了BigInteger类,它采用int[]数组存储数值,通过模拟进位与借位实现加减乘除,并针对大数乘法引入Karatsuba等优化算法。BigInteger在RSA加密、大数组合计算、哈希处理等场景中不可或缺,同时modPow等模幂运算能高效支撑密码学应用。然而,BigInteger的不可变性和toString()的隐藏代价也可能带来性能陷阱,需要结合long等基本类型

weixin_42568801的博客 128

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Java BigInteger详解:大数运算原理、性能优化与实战应用

在Java开发中,int和long等基本类型都有固定的数值范围,一旦运算结果超越边界就会发生溢出,且这种错误难以察觉。当业务涉及超大整数,比如高精度科学计算、RSA类加密算法、哈希生成或分布式唯一ID时,基本类型已无能为力。此时需要借助Java提供的BigInteger类,它采用int数组存储每一位数据,支持任意精度整数运算,从加法、乘法到位运算、模幂等一应俱全。理解BigInteger的底层存储机制和算法设计,不仅有助于避开常见的性能陷阱,还能在金融、数据分析和算法竞赛中做出更高效的设计选择。从构造方式、

weixin_30899023的博客 163

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

BigInteger和BigDecimal

类似,为了提升效率,提前创建好了[-10,10]的数,当创建该范围内的对象时,不会创建新对象。记录小数点后有几位,最终数值 = intVal ÷ (10^scale)。为了提升效率,提前创建好了[-16,16]的数,当创建该范围内的。适用于高精度的浮点数运算,避免浮点精度误差,常用于金融计算。存储符号1 代表正数,-1 代表负数,0 代表零。适用于任意精度的整数运算,支持大数计算,如超出。存储大整数,每个元素存储 32 位(4 字节)。存储去掉小数点后的整数,通过。时,会使用相同的对象。

gyijh的博客 1979

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

java BigInteger类的原理

转载自:https://blog.youkuaiyun.com/gjb724332682/article/details/51488765/ JDK对BigInteger类的介绍: Immutable arbitrary-precision integers. All operations behave as if BigIntegers were represented in two's-compleme...

qq_27430551的博客 1596

java数组实现几乎任意长度两数字乘法

java数组实现几乎任意长度两数字乘法。 我们知道,在java中整数型long最大只能为9223372036854775807,那么大于计算结果大于这个数怎么办呢?甚至需要计算这么大甚至更大的两个数相乘呢?当然jdk提供了进行大数相乘的类BigInteger,传入任意长度的两个数字字符串即可进行各种运算。它为什么能...

vttsor的博客 1360

java中大数开方_Java中的大数运算

#一:大数运算出现的背景java里面整型int与浮点型float,double它们存放数据的范围是有限的,当出行更大的数值时会发生溢出。最典型的场景是金融行业,直接使用单精度或者双精浮点数来表示金额信息会出现精度误差。二:Java中的大数运算类Java提供了两个用于高精度计算的类:BigInteger和BigDecimal。创建:需要注意必须使用String类型参数来创建大数变量,而不是用基本类型...

weixin_39872624的博客 184

Java 大数使用

Java 大数BigInteger使用 由于在 Java中,在不使用大数的情况下,整数最大范围为long型(能够表示64位的整数),速度快 ,但是当运算超过long型的范围时,我们就需要用java.math.BigInteger(另外一个是java.math.BigDecimal,用于进行小数运算 )来表示任意大小的整数了,其内部用一个int[]数组来模拟一个非常大的整数 以下为BigInteger以及BigDecimal相关API介绍: 以下用一个例子来实现BigInteger: **程序 :**

weixin_44442186的博客 2065

java biginteger范围_[十六]大数计算来啦~深入源码,手撕BigInteger计算过程!

点击上方“布衣码农”,免费订阅~选择“设为星标”,第一时间免费获得更新~「布衣码农」一步一步教你BigInteger内部计算模式。BigInteger和BigDecimal都是Java针对大数提供的类超出了java的表示范围属性简介借助于signum和mag来实现数据的符号位和实际数据的保存final intsignum 保存BigInteger的符号负数-100正数1f...

weixin_39847945的博客 395

Java基础教程(四十五)Java核心类之BigInteger:解剖 Java BigInteger,大数处理的源码魔法与实战避坑指南

Java的BigInteger突破原生整数限制,实现任意精度计算。本文深度剖析其核心机制:基于int[]的数值存储、符号位独立管理及自动扩容策略。通过质数检测、大数阶乘等示例,揭示其强大功能背后的计算代价——内存消耗与运算效率的隐性成本。同时警示开发者警惕递归计算中的StackOverflowError及幂运算的指数限制,并对比BigDecimal适用场景。掌握这些关键点,方能在金融加密、科学计算等领域安全驾驭“无限”数值。

jxf_jxfcsdn的博客 376

02、大数 -- BigDecimal、BigInteger

如果基本的整数和浮点数精度不足以满足需求,可以使用 java.math 包中两个很有用的类:BigInteger和BigDecimal。这两个类可以处理包含任意长度数字序列的数值。二、BigInteger1、用途BigInteger类可实现任意精度的整数运算。如:超出long范围(-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)的大整数。2、典型场景大数阶乘(如:1000!

butingdejiaobu的专栏 1278

java biginteger sqrt_Java BigInteger sqrt方法的实现

本来是为我上学期写好的MathTool工具类转化,也就是原来这个工具类的方法参数类型是long。为了实现任意大数的运算,long用BigInteger替换带哦。好了废话少数,先说数学原理,也就是手算平方根计算机代码实现!那么什么叫手算平方根了???手开方据说前苏联的普通工人都会的(毛熊国果然是一个神奇的国度!听到这里我背脊发冷,再次膜拜俄罗斯基础数!!和那令人望而生畏的吉米多维奇了!!! )它的计...

weixin_42469012的博客 184

BigInteger大数加法源代码及分析

我们可以把一个很大很长的数分成多个短小的数,然后保存在一个数组中,大数之间的四则运算及其它运算都是通过数组完成.JDK就是这么实现的.JDK的BigInteger类里用一个int数组来保存数据: /** *ThemagnitudeofthisBigInteger,in<i>big-...

weixin_30949361的博客 336
上一篇: Mysql批量插入数据时是否为原子操作
sysong13
博客等级 码龄9年 3粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值