BigInteger简单分析
早上看到一篇写使用BigInteger计算阶乘的文章,看了下源码,有点小收获。
BigInteger的主要内部数据:
int signum;
如果数值为正,则signum为1,值为负则signum为-1,值为0则signum为0。
int[] mag;
使用一个数组表示大数,例如: 如果大数用一个int就可以表示,则直接存这个数在mag[0]中,如果超出int的范围,就扩充这个数组,存储采用big endian方式。
简单分析,把BigInteger中的stripLeadingZeroBytes()函数拷贝出来并调用:
public class A {
// Copy from the jdk 1.6 source code
private static int[] stripLeadingZeroBytes(byte a[]) {
int byteLength = a.length;
int keep;
// Find first nonzero byte
for (keep = 0; keep < a.length && a[keep] == 0; keep++)
;
// Allocate new array and copy relevant part of input array
int intLength = ((byteLength - keep) + 3) / 4;
int[] result = new int[intLength];
int b = byteLength - 1;
for (int i = intLength - 1; i >= 0; i--) {
result[i] = a[b--] & 0xff;
int bytesRemaining = b - keep + 1;
int bytesToTransfer = Math.min(3, bytesRemaining);
for (int j = 8; j <= 8 * bytesToTransfer; j += 8)
result[i] |= ((a[b--] & 0xff) << j);
}
return result;
}
public static void main(String[] args) {
byte x[] = new byte[5];
for (int i = 0; i < x.length; i++)
x[i] = 2;
System.out.println(Arrays.toString(stripLeadingZeroBytes(x)));
System.out.println(new BigInteger(x).toString(2));
}
}
output
=============
[2, 33686018]
1000000010000000100000001000000010
// 分开就是 10 00000010 00000010 00000010 00000010
可以看出,此时的mag长度是2,mag[0] 保存的是溢出位2(big endian)。
顺便说一句,BigInteger和BigDecimal的作者是Bloch,都实现成他比较推崇的Immutable Object的形式,缺点是某些环境下可能产生性能问题。
=================================================
new updated 2010.1.4
可能产生性能问题时的解决方案
Bloch在Effect Java中对不可变类由于生产对象过多而可能产生性能问题提出了两种解决方案。
方案一:在不可变类中对可能产生重复数据的情况提供方法实现
例如:考虑到可能使用BigInteger进行幂元素,在BigInteger中直接提供pow函数:
BigInteger中的pow的内部实现并不会产生多余的BigInteger对象。但如果是个人使用BigInteger来实现x的n次方,即使使用平方后再相乘的方法,也会产生log2(N)个BigInteger对象,当n很大时,过多不必要的对象将占有大量空间,如果来不及回收则会导致out of memory。
提供这种方法实现的很大一个好处就是域共用,即:新产生的BigInteger可以共用“旧”的BigInteger的部分域。典型的例子有:
// BigInteger的negate()方法:
public BigInteger negate() {...}
// 新产生的BigInteger和旧的BigInteger仅仅符号位不同,mag数组时共用的。
// BigInteger的setBit()方法:
public BigInteger setBit(int n)
// 用于置BigInteger的某一位为1,新产生的BigInteger和旧的BigInteger仅仅在某个mag项不同。
缺点:不可能在不可变对象中提供所有可能的方法。
方案二:为不可变类提供一个相应的可变类
例如String是不可变类,StringBuilder是String的可变类。
分享到:
相关推荐
下面我们将对 BigInteger 的构造过程进行详细的分析。 首先,我们需要了解 BigInteger 的成员域。BigInteger 使用两个成员域来存储大数:signum 和 mag。signum 存储源数的符号,可以是 1、0 或 -1,分别表示目标数...
biginteger 源码#深度理解Android InstantRun原理以及源码分析 @Author 莫川##Instant Run官方介绍简单介绍一下Instant Run,它是Android Studio2.0以后新增的一个运行机制,能够显着减少你第二次及以后的构建和部署...
#### 四、代码示例分析 在给定的代码片段中,主要实现了计算阶乘的功能,即`N!`,其中`N`可以是较大的整数。 1. **导入必要的类**: ```java import java.math.*; import java.util.*; ``` 2. **定义主类`...
本文将重点介绍如何利用`BigInteger`类处理大数,并通过一个具体的示例程序进行深入分析。 #### 二、`BigInteger`类简介 `BigInteger`是`java.math`包下的一个类,专门用于处理任意精度的整数。它可以表示远远超出...
`MathContext`主要用于设置精度和舍入规则,但在简单的加法运算中,我们通常不需要设置它。 ```java import java.math.BigInteger; ``` 接着,我们可以创建`BigInteger`对象来存储大数。假设我们有两个大数字符串...
在Java世界中,Hibernate是一个非常流行的持久化框架,它简化了数据库...而提供的"HibernateMapping"文件很可能包含了这些映射关系的示例代码,通过分析和运行这些代码,可以更直观地理解上述各种映射方式的工作原理。
这两个类在软件开发中尤其在金融计算、统计分析等领域非常有用,因为它们能够提供精确的计算结果。 `BigInteger`类是Java中的大整数类,它允许进行任意精度的整数运算。当涉及到非常大的数字,例如在彩票概率计算...
在编程领域,阶乘是一个常见的数学概念,它在计算、概率论、组合数学等领域有着广泛的应用。...通过阅读和分析`1000.txt`文件,可以直观地看到Java程序计算出的阶乘结果,进一步加深对阶乘和大数运算的理解。
Pollard's rho算法则是一种更高效的策略,特别适合于大数分解,但其复杂性超过了简单的试除法。 在源代码中,我们可以预期看到关于线程管理的类和方法,比如`System.Threading`命名空间下的`Thread`类,用于创建和...
接着,我们将用Java语言设计并实现SM3算法,同时针对存储数据的不同数据类型,探讨两种实现方式:SM3-String模式和SM3-BigInteger模式,分析各自的优缺点。最后,通过对比SM3算法与常用的MD5和SHA-256算法,探讨它们...
BigInteger提供了无限制大小的整数运算,而BigDecimal则用于进行任意精度的浮点数运算。分析这两个类库的构成和各个方法,有助于深入理解它们在密码学中的应用,比如在加密算法中进行大数运算。 此外,刘鹏还搜索了...
通过阅读和分析这个文件,我们可以学习到如何在C++中有效地处理大数,并理解随机数生成和大数乘法的实现细节。 总之,随机生成大数并计算其乘积是计算机科学中的一项基本技能,特别是在密码学、分布式计算和模拟等...
- 注意处理阶乘值可能会非常大的情况,可能需要使用`BigInteger`等数据类型来存储较大的阶乘结果。 #### 程序18: 递归求阶乘 - **目标**: 利用递归方法计算5的阶乘。 - **递归公式**: - `fn = fn-1 * n` - **程序...
#### 四、实战演练分析 从提供的部分代码来看,该代码段展示了一个基于ASP.NET的经典Web应用程序中用户注册的功能实现。其中涉及到了使用MD5加密来存储用户密码的过程。具体步骤如下: 1. **数据库连接**:首先...
例如,Java中的`long`类型只能表示-9,223,372,036,854,775,808到9,223,372,036,854,775,807之间的整数,对于更大的数值,我们需要使用特殊的数据类型,如Java的`BigInteger`或Python的`int`类型,这些类型可以处理...
此外,解决高精度计算问题时,还可以考虑使用特定的库,如GMP(GNU Multiple Precision Arithmetic Library)或Java中的BigInteger类,它们提供了高效的大数运算功能。这些库在处理非常大的数字时更为可靠,但可能会...
总之,大数的比较和处理是计算机科学的基础部分,无论是简单的数值比较还是复杂的数据分析,都需要掌握这些基本技巧。理解和熟练运用大数的比较方法,以及学会将大数改写为更易读的形式,都是IT从业者必备的能力。
例如,为了实现一个简单的加法计算器,可以使用以下代码: ```java import java.math.BigInteger; public class BigCalculator { public static void main(String[] args) { BigInteger num1 = new BigInteger...
对于一般的整数而言,计算GCD相对简单,但对于高位数(例如几十位甚至更多位数),传统的算法可能不再适用或效率较低。本文将介绍一种用于计算高位数最大公约数的方法,并通过Java代码实现。 #### Java代码解析 该...
Java 提供的 java.math 包含了处理大整数(BigInteger)和大浮点数(BigDecimal)的类,以及进行数学运算的方法,如 pow()(指数运算)、sqrt()(平方根)等。在计算器项目中,可能利用了这些方法进行高级计算。 7...