Chapter 20: BigInteger

No Comments

The BigInteger class is used for mathematical operations involving large integers with magnitudes too large for primitive data types. For example 100-factorial is 158 digits – much larger than a long can represent. BigInteger provides analogues to all of Java’s primitive integer operators, and all relevant methods from java.lang.Math as well as few other operations.

Section 20.1: Initialization

The java.math.BigInteger class provides operations analogues to all of Java’s primitive integer operators and for all relevant methods from java.lang.Math. As the java.math package is not automatically made available you may have to import java.math.BigInteger before you can use the simple class name.

To convert long or int values to BigInteger use:

long  longValue  =  Long.MAX_VALUE;
BigInteger valueFromLong = BigInteger.valueOf(longValue);

or, for integers:

int  intValue  =  Integer.MIN_VALUE;  //  negative
BigInteger valueFromInt = BigInteger.valueOf(intValue);

which will widen the intValue integer to long, using sign bit extension for negative values, so that negative values will stay negative.

To convert a numeric String to BigInteger use:

String decimalString = “-1”;
BigInteger  valueFromDecimalString  =  new  BigInteger(decimalString);

Following constructor is used to translate the String representation of a BigInteger in the specified radix into a

BigInteger.

String binaryString = “10”;
int  binaryRadix  =  2;
BigInteger valueFromBinaryString = new BigInteger(binaryString , binaryRadix);

Java also supports direct conversion of bytes to an instance of BigInteger. Currently only signed and unsigned big endian encoding may be used:

byte[] bytes = new byte[] { (byte)  0x80  };
BigInteger valueFromBytes = new BigInteger(bytes);

This will generate a BigInteger instance with value -128 as the first bit is interpreted as the sign bit.

byte[] unsignedBytes = new byte[] { (byte) 0x80 };
int  sign  =  1;  //  positive
BigInteger  valueFromUnsignedBytes  =  new  BigInteger(sign,  unsignedBytes);

This will generate a BigInteger instance with value 128 as the bytes are interpreted as unsigned number, and the sign is explicitly set to 1, a positive number.

There are predefined constants for common values:

BigInteger.ZERO — value of “0”. BigInteger.ONE — value of “1”. BigInteger.TEN — value of “10”.

There’s also BigInteger.TWO (value of “2”), but you can’t use it in your code because it’s private.

Section 20.2: BigInteger Mathematical Operations Examples

BigInteger is in an immutable object, so you need to assign the results of any mathematical operation, to a new BigInteger instance.

Addition: 10 + 10 = 20

BigInteger value1 = new BigInteger(“10”);
BigInteger value2 = new BigInteger(“10”); 
BigInteger  sum  =  value1.add(value2);


System.out.println(sum);

output: 20

Subtraction: 10 – 9 = 1

BigInteger value1 = new BigInteger(“10”);
BigInteger value2 = new BigInteger(“9”);
 BigInteger sub = value1.subtract(value2);
System.out.println(sub);

output: 1

Division: 10 / 5 = 2

BigInteger value1 = new BigInteger(“10”);
BigInteger value2 = new BigInteger(“5”); 
BigInteger div = value1.divide(value2);
System.out.println(div);

output: 2

Division: 17/4 = 4

BigInteger value1 = new BigInteger(“17”);
BigInteger value2 = new BigInteger(“4”); 
BigInteger div = value1.divide(value2);
System.out.println(div);

output: 4

Multiplication: 10 * 5 = 50

BigInteger value1 = new BigInteger(“10”);
BigInteger value2 = new BigInteger(“5”); 
BigInteger mul = value1.multiply(value2);
System.out.println(mul);

output: 50

Power: 10 ^ 3 = 1000

BigInteger value1 = new BigInteger(“10”);
BigInteger  power  =  value1.pow(3);
System.out.println(power);

output: 1000

Remainder: 10 % 6 = 4

BigInteger value1 = new BigInteger(“10”);
BigInteger value2 = new BigInteger(“6”); 
BigInteger power = value1.remainder(value2);
System.out.println(power);

output: 4

GCD: Greatest Common Divisor (GCD) for 12and 18 is 6.

BigInteger value1 = new BigInteger(“12”);
BigInteger value2 = new BigInteger(“18”); 
System.out.println(value1.gcd(value2));

Output: 6

Maximum of two BigIntegers:

BigInteger value1 = new BigInteger(“10”);
BigInteger value2 = new BigInteger(“11”); 
System.out.println(value1.max(value2));

Output: 11

Minimum of two BigIntegers:

BigInteger value1 = new BigInteger(“10”);
BigInteger value2 = new BigInteger(“11”);
 System.out.println(value1.min(value2));

Output: 10

Section 20.3: Comparing BigIntegers

You can compare BigIntegers same as you compare String or other objects in Java. For example:

BigInteger  one  =  BigInteger.valueOf(1); BigInteger  
two  =  BigInteger.valueOf(2);

 if(one.equals(two)){
System.out.println(“Equal”);
}
else{
System.out.println(“Not  Equal”);
}
Output:
Not Equal

Note:

In general, do not use use the == operator to compare BigIntegers

  • == operator: compares references; i.e. whether two values refer to the same object
  • equals() method: compares the content of two BigIntegers.

For example, BigIntegers should not be compared in the following way:

if (firstBigInteger == secondBigInteger) {
// Only checks for reference equality, not content equality!
}

Doing so may lead to unexpected behavior, as the == operator only checks for reference equality. If both BigIntegers contain the same content, but do not refer to the same object, this will fail. Instead, compare BigIntegers using the equals methods, as explained above.

You can also compare your BigInteger to constant values like 0,1,10.

for example:

BigInteger  reallyBig  =  BigInteger.valueOf(1);
if(BigInteger.ONE.equals(reallyBig)){
//code when they are equal.
}

You can also compare two BigIntegers by using compareTo() method, as following: compareTo() returns 3 values.

  • 0: When both are equal.
  • 1: When first is greater than second (the one in brackets).
  • -1: When first is less than second.
BigInteger  reallyBig  =  BigInteger.valueOf(10);
BigInteger  reallyBig1  =  BigInteger.valueOf(100);

 if(reallyBig.compareTo(reallyBig1) == 0){//code when both are equal.
}
else if(reallyBig.compareTo(reallyBig1) == 1){
//code when reallyBig is greater than reallyBig1.
}
else if(reallyBig.compareTo(reallyBig1) == -1){
//code when reallyBig is less than reallyBig1.
}

Section 20.4: Binary Logic Operations on BigInteger

BigInteger supports the binary logic operations that are available to Number types as well. As with all operations they are implemented by calling a method.

Binary Or:

BigInteger val1 = new BigInteger(“10”);
BigInteger val2 = new BigInteger(“9”); 
val1.or(val2);

Output: 11 (which is equivalent to 10 | 9)

Binary And:

BigInteger val1 = new BigInteger(“10”);
BigInteger val2 = new BigInteger(“9”); 
val1.and(val2);

Output: 8 (which is equivalent to 10 &  9)

Binary Xor:

BigInteger val1 = new BigInteger(“10”);
BigInteger val2 = new BigInteger(“9”); 
val1.xor(val2);

Output: 3 (which is equivalent to 10 ^  9)

RightShift:

BigInteger  val1  =  new  BigInteger(“10”);

val1.shiftRight(1);            //  the  argument  be  an  Integer

Output: 5 (equivalent to 10 >>  1)

LeftShift:

BigInteger  val1  =  new  BigInteger(“10”); 
val1.shiftLeft(1);             //  here  parameter  should  be  Integer

Output: 20 (equivalent to 10 <<  1)

Binary Inversion (Not) :

BigInteger  val1  =  new  BigInteger(“10”);
 val1.not();

Output: 5

NAND (And-Not):*

BigInteger val1 = new BigInteger(“10”);
BigInteger val2 = new BigInteger(“9”);
 val1.andNot(val2);

Output: 7

Section 20.5: Generating random BigIntegers

The BigInteger class has a constructor dedicated to generate random BigIntegers, given an instance of java.util.Random and an int that specifies how many bits will the BigInteger have. Its usage is quite simple – when you call the constructor BigInteger(int,  Random) like this:

BigInteger  randomBigInt  =  new  BigInteger(bitCount,  sourceOfRandomness);

then you’ll end up with a BigInteger whose value is between 0 (inclusive) and 2bitCount (exclusive).

This also means that new  BigInteger(2147483647,  sourceOfRandomness) may return all positive BigIntegers given enough time.

What will the sourceOfRandomness be is up to you. For example, a new Random() is good enough in most cases:

new  BigInteger(32,  new  Random());

If you’re willing to give up speed for higher-quality random numbers, you can use a new

=”https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html” rel=”nofollow noreferrer”>SecureRandom() instead:

import java.security.SecureRandom; 
// somewhere in the code…new  BigInteger(32,  new  SecureRandom());

You can even implement an algorithm on-the-fly with an anonymous class! Note that rolling out your own RNG algorithm will end you up with low quality randomness, so always be sure to use an algorithm that is proven to be decent unless you want the resulting BigInteger(s) to be predictable.

new  BigInteger(32,  new  Random()  {
int  seed  =  0; @Overrideprotected int next(int bits) {seed  =  ((22695477  *  seed)  +  1)  &  2147483647;  //  Values  shamelessly  stolen  from

=”https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use” rel=”nofollow noreferrer”>Wikipedia return seed; } });

About us and this blog

We are a digital marketing company with a focus on helping our customers achieve great results across several key areas.

Request a free quote

We offer professional SEO services that help websites increase their organic search score drastically in order to compete for the highest rankings even when it comes to highly competitive keywords.

Subscribe to our newsletter!

More from our blog

See all posts
No Comments

Recent Posts