In this post, we will see about BigInteger in java.
Table of Contents
Why do we need BigInteger?
Java provides various primitive data types such as int
, long
, and double
etc.but these data types can not handle very large numbers and will overflow causing issues in program.
BigInteger
is introduced in java to handle very large integers and this class provides all the java primitive integer operators and required methods of java.lang.Math. BigInteger can handle very large integers and only limited by the available memory in JVM.
Let me demonstrate this with the help of an example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package org.arpit.java2blog; import java.math.BigInteger; public class FactorialMain { public static void main(String[] args) { long l=factorial(40); System.out.println("Factorial of 40 (Long): "+l); BigInteger b1=factorialBigInteger(40); System.out.println("Factorial of 40 (BigInteger): "+b1); } static long factorial(int n) { int res = 1, i; for (i=2; i<=n; i++) res *= i; return res; } static BigInteger factorialBigInteger(int n) { BigInteger res = BigInteger.ONE; int i; for (i=2; i<=n; i++) res = res.multiply(BigInteger.valueOf(i)); return res; } } |
As you can see, I have written two versions of the factorial calculation. factorial()
returns long whereas factorialBigInteger()
returns BigInteger. We will run the above program to calculate factorial of 40 with the help of both methods.
When you run the program, you will get below out:
Factorial of 40 (BigInteger): 815915283247897734345611269596115894272000000000
As you can clearly see, BigInteger
was able to handle factorial of 40, whereas long
did not give correct result due to overflow issue.
Should we always use BigInteger instead of Integer?
BigInteger
should be only used whenever required, as there is performance hit associated with BigInteger and also memory taken per BigInteger is relatively very high compared to built-in types.
BigInteger is an immutable arbitrary-precision integer.
Initialize BigInteger objects
You can create BigInteger
from a byte array or String.
Let’s see with the help of an example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package org.arpit.java2blog; import java.math.BigInteger; public class BigIntegerMain{ public static void main(String args[]) { BigInteger bigIntegerStr = new BigInteger("1357986420123456789"); BigInteger bigIntegerByteArray = new BigInteger( new byte[] { 32, 32, 32, 32 }); BigInteger bigIntegerSigned = new BigInteger(-1, new byte[] { 32, 32, 32, 32 }); System.out.println("bigIntegerStr: "+ bigIntegerStr); System.out.println("bigIntegerByteArray: "+bigIntegerByteArray); System.out.println("bigIntegerSigned: "+bigIntegerSigned); } } |
You can also convert other radix String to BigInteger using constructor BigInteger(String val, int radix)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package org.arpit.java2blog; import java.math.BigInteger; public class BigIntegerMain{ public static void main(String args[]) { String hexaDecimalStr = "28A"; BigInteger bigIntegerStr = new BigInteger(hexaDecimalStr,16); System.out.println("BigInteger for hexaDecimal 28A: "+ bigIntegerStr); } } |
Compare two BigInteger objects
We can use compareTo()
method to compare two BigIntegers. BigInteger
returns 0, 1 or -1.
Let’s see with the help of an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package org.arpit.java2blog; import java.math.BigInteger; public class BigIntegerCompareToMain{ public static void main(String args[]) { BigInteger b1=new BigInteger("10"); BigInteger b2=new BigInteger("20"); BigInteger b3=new BigInteger("10"); System.out.println("comparing b1 and b2: "+b1.compareTo(b2)); System.out.println("comparing b1 and b3: "+b1.compareTo(b3)); System.out.println("comparing b2 and b3: "+b2.compareTo(b3)); } } |
Output:
comparing b1 and b3: 0
comparing b2 and b3: 1
You can also use equals
method also in case you want to check BigInteger equality. Just change compareTo to equals in above example
1 2 3 4 5 |
System.out.println("comparing b1 and b2: "+b1.equals(b2)); System.out.println("comparing b1 and b3: "+b1.equals(b3)); System.out.println("comparing b2 and b3: "+b2.equals(b3)); |
Output:
comparing b1 and b3: true
comparing b2 and b3: false
BigInteger
class provides constants for ZERO, ONE and TEN, so in case you want to compare it with these 3 constants, you need not create new objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package org.arpit.java2blog; import java.math.BigInteger; public class BigIntegerConstantsMain{ public static void main(String args[]) { BigInteger b1=new BigInteger("0"); BigInteger b2=new BigInteger("1"); BigInteger b3=new BigInteger("10"); System.out.println("comparing b1 to 0: "+b1.equals(BigInteger.ZERO)); System.out.println("comparing b2 to 1: "+b2.equals(BigInteger.ONE)); System.out.println("comparing b3 to 10: "+b3.equals(BigInteger.TEN)); } } |
Output:
comparing b2 to 1: true
comparing b3 to 10: true
Bit operations
BigInteger
has bit operations similar to int and long. We need to use methods instead of operations in case of BigInteger
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
package org.arpit.java2blog; import java.math.BigInteger; public class BigIntegerBitOperationsMain{ public static void main(String args[]) { BigInteger b1=new BigInteger("100"); BigInteger b2=new BigInteger("200"); // b1 and b2 BigInteger and = b1.and(b2); // b1 or b2 BigInteger or = b1.or(b2); // b1 xor b2 BigInteger xor = b1.xor(b2); // not b1 BigInteger not = b1.not(); // b1 andnot b2 BigInteger andNot = b1.andNot(b2); // will shift bits left by 1 which means multiply by 2 BigInteger shiftLeft = b1.shiftLeft(1); // will shift bits right by 1 which means divide by 2 BigInteger shiftRight = b1.shiftRight(1); // bitCount counts all the set bits i.e. '1' int bitCount = b1.bitCount(); // bitLength counts all the bits int bitLength = b1.bitLength(); // Find position of first set bit i.e. '1' int getLowestSetBit = b1.getLowestSetBit(); // Will check set bit at position 2 boolean testBit2 = b1.testBit(2); // Will set bit at positon 3 BigInteger setBit3 = b1.setBit(3); // Will flip bit at position 3 BigInteger flipBit3 = b1.flipBit(3); // Will clear bit at postion 2 BigInteger clearBit2 = b1.clearBit(2); System.out.println("Binary presentation of b1: "+ Integer.toBinaryString(new Integer(b1.toString()))); System.out.println("b1 and b2: "+and); System.out.println("b1 or b2: "+or); System.out.println("b1 xor b2: "+xor); System.out.println("b1 not: "+not); System.out.println("b1 andNot b2: "+andNot); System.out.println("b1 shiftLeft: "+shiftLeft); System.out.println("b1 shitfRight: "+shiftRight); System.out.println("b1 bitcount: "+bitCount); System.out.println("b1 bitLength: "+bitLength); System.out.println("b1 getLowestSetBit: "+getLowestSetBit); System.out.println("b1 testBit2: "+testBit2); System.out.println("b1 setBit3: "+setBit3); System.out.println("b1 flipBit3: "+flipBit3); System.out.println("b1 clearBit2: "+clearBit2); } } |
Output:
b1 and b2: 64
b1 or b2: 236
b1 xor b2: 172
b1 not: -101
b1 andNot b2: 36
b1 shiftLeft: 200
b1 shitfRight: 50
b1 bitcount: 3
b1 bitLength: 7
b1 getLowestSetBit: 2
b1 testBit2: true
b1 setBit3: 108
b1 flipBit3: 108
b1 clearBit2: 96
Min, Max, pow, abs, signum operations
BigInteger
provides methods to perform various operations such as Min, Max, pow, abs, signum.
Let’s see with the help of an example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package org.arpit.java2blog; import java.math.BigInteger; public class BigDecimalMiscMain { public static void main(String args[]) { BigInteger b1=new BigInteger("10"); BigInteger b2=new BigInteger("20"); BigInteger b3=new BigInteger("-10"); System.out.println("Min between b1 and b2: "+b1.min(b2)); System.out.println("max between b1 and b2: "+b1.max(b2)); System.out.println("10 to the pow 3: "+b1.pow(3)); System.out.println("Abosolute value of b3: "+b3.abs()); // Signum method helps to identify is // BigInteger is negative, positive or zero System.out.println("Signum for b1: "+b1.signum()); } } |
Modular and GCD computation
BigInteger
provides in-built methods for modular and GCD calculations.
Here is an example of the same.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package org.arpit.java2blog; import java.math.BigInteger; public class BigDecimalGCDModMain { public static void main(String args[]) { BigInteger b1=new BigInteger("55"); BigInteger b2=new BigInteger("20"); BigInteger b3=new BigInteger("4"); System.out.println("GCD b1 and b2: "+b1.gcd(b2)); System.out.println("mod b1 and b3: "+b1.mod(b3)); } } |
Output:
mod b1 and b3: 3
Prime generation and primality testing
BigInteger
also has methods for Prime generation and primality testing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package org.arpit.java2blog; import java.math.BigInteger; import java.util.Random; public class BigDecimalMiscMain { public static void main(String args[]) { BigInteger pp = BigInteger.probablePrime(10, new Random()); System.out.println("probable prime: "+pp); } } |
Output:
Conclusion
In this article, you learned about Why should we use BigInteger
, how to initialize BigInteger, and do various operations such as min, max, signum, pow, gcd, mod, and also bit operations.
That’s all about BigInteger in java.