Using BigInteger Multiply operator - java

I was wondering if there was a way to multiply BigInteger variables together, because the * operator cannot be applied to BigInteger.
So I was wondering if it was possible to multiply two BigIntegers together without using the * operator.

You use BigIntegers multiply() method like so:
BigInteger int1 = new BigInteger("131224324234234234234313");
BigInteger int2 = new BigInteger("13345663456346435648234313");
BigInteger result = int1.multiply(int2)
I should have pointed out a while ago that BigInteger is immutable. So any result of an operation has to be stored into a variable. The operator or operand are never changed.

Easier way to implement:
int i = 5;
BigInteger bigInt = new BigInteger("12345678901");
BigInteger result = bigInt.multiply(BigInteger.valueOf(i))

You can use the multiply(BigInteger) method in BigInteger. So:
BigInteger result = someBigInt.multiply(anotherBigInt);
BigInteger in Java API

The result multiplying these specific factors
A: 131224324234234234234313
B: 13345663456346435648234313
Could be this one (I hope I am correct):
R: 1751275668516575787795211751170772134115968581969
Both are considered being two positive integers. And the technique used
was Karatsuba’s method
int ab = (mul1) * 10^n + (mul3 - mul1 - mul2) * 10^n/2 + mul2;

Related

How to calculate 2 to-the-power N where N is a very large number

I need to find 2 to-the-power N where N is a very large number (Java BigInteger type)
Java BigInteger Class has pow method but it takes only integer value as exponent.
So, I wrote a method as follows:
static BigInteger twoToThePower(BigInteger n)
{
BigInteger result = BigInteger.valueOf(1L);
while (n.compareTo(BigInteger.valueOf((long) Integer.MAX_VALUE)) > 0)
{
result = result.shiftLeft(Integer.MAX_VALUE);
n = n.subtract(BigInteger.valueOf((long) Integer.MAX_VALUE));
}
long k = n.longValue();
result = result.shiftLeft((int) k);
return result;
}
My code works fine, I am just sharing my idea and curious to know if there is any other better idea?
Thank you.
You cannot use BigInteger to store the result of your computation. From the javadoc :
BigInteger must support values in the range -2^Integer.MAX_VALUE (exclusive) to +2^Integer.MAX_VALUE (exclusive) and may support values outside of that range.
This is the reason why the pow method takes an int. On my machine, BigInteger.ONE.shiftLeft(Integer.MAX_VALUE) throws a java.lang.ArithmeticException (message is "BigInteger would overflow supported range").
Emmanuel Lonca's answer is correct. But, by Manoj Banik's idea, I would like to share my idea too.
My code do the same thing as Manoj Banik's code in faster way. The idea is init the buffer, and put the bit 1 in to correct location. I using the shift left operator on 1 byte instead of shiftLeft method.
Here is my code:
static BigInteger twoToThePower(BigInteger n){
BigInteger eight = BigInteger.valueOf(8);
BigInteger[] devideResult = n.divideAndRemainder(eight);
BigInteger bufferSize = devideResult[0].add(BigInteger.ONE);
int offset = devideResult[1].intValue();
byte[] buffer = new byte[bufferSize.intValueExact()];
buffer[0] = (byte)(1 << offset);
return new BigInteger(1,buffer);
}
But it still slower than BigInteger.pow
Then, I found that class BigInteger has a method called setBit. It also accepts parameter type int like the pow method. Using this method is faster than BigInteger.pow.
The code can be:
static BigInteger twoToThePower(BigInteger n){
return BigInteger.ZERO.setBit(n.intValueExact());
}
Class BigInteger has a method called modPow also. But It need one more parameter. This means you should specify the modulus and your result should be smaller than this modulus. I did not do a performance test for modPow, but I think it should slower than the pow method.
By using repeated squaring you can achieve your goal. I've posted below sample code to understand the logic of repeated squaring.
static BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
while (exponent.signum() > 0) {
if (exponent.testBit(0)) result = result.multiply(base);
base = base.multiply(base);
exponent = exponent.shiftRight(1);
}
return result;
}
An interesting question. Just to add a little more information to the fine accepted answer, examining the openjdk 8 source code for BigInteger reveals that the bits are stored in an array final int[] mag;. Since arrays can contain at most Integer.MAX_VALUE elements this immediately puts a theoretical bound on this particular implementation of BigInteger of 2(32 * Integer.MAX_VALUE). So even your method of repeated left-shifting can only exceed the size of an int by at most a factor of 32.
So, are you ready to produce your own implementation of BigInteger?

Trying to understand sage number system for BigInteger

I have the following sage code that runs instantly (less than a second) and I am trying to convert it to Java (using Java's built-in BigInteger library). But I am not successful.
In short, I initialized N as a BigInteger and delta as double and in order to calculate power (BigInteger ^ double) I converted N to BigDecimal (i.e. new BigDecimal(BigInteger)) and then:
I used this approach but it is too slow (extremely slow).
I used this library but I lost too much precision.
I used this library but I got overflow exception.
N = 16260595201356777876687102055392856230368799478725437225418970788404092751540966827614883675066492383688147288741223234174448378892794567789551235835087027626536919406320142455677084743499141155821894102610573207343199194327005172833989486958434982393556326206485954223151805798621294965926069728816780985683043030371485847746616146554612001066554175545753760388987584593091716701780398711910886679925612838955858736102229719042291682456480437908426849734556856917891628730543729446245974891735371991588505429152639045721840213451875487038496578525189542369448895368117152818687795094021869963915318643663536132393791
delta = 0.26
X = 2*floor(N^delta) # in sage, ^ operator means exponentiation
# similar to ** operator in python
print("X:" + str(x))
Output:
X:32803899270297070621193977210731234596426011189989730481205367370572340252530823123935195892838208219967066426399488721710159859316222019683979411877007525412864
What is the magic? How sage does this? How to convert this code to Java (and be able to get a similar result), there should be some solution.
You can use approach #1 with a workaround. The problem there is that BigFunctions.ln() is not very effective for numbers with large integer part (number of digits to the left of the decimal point). As a workaround I scaled the number so that it contained at most one digit in integer part and compensated that later by adding ln(10) * rescale * delta to the argument of exp().
You should also note that using new BigDecimal(double) constructor leads to loss of precision - read the javadoc for explanation. Instead you should use new BigDecimal(String) (especially if that double comes from some sort of configuration value), or BigDecimal.valueOf(double).
BigInteger N = new BigInteger("16260595201356777876687102055392856230368799478725437225418970788404092751540966827614883675066492383688147288741223234174448378892794567789551235835087027626536919406320142455677084743499141155821894102610573207343199194327005172833989486958434982393556326206485954223151805798621294965926069728816780985683043030371485847746616146554612001066554175545753760388987584593091716701780398711910886679925612838955858736102229719042291682456480437908426849734556856917891628730543729446245974891735371991588505429152639045721840213451875487038496578525189542369448895368117152818687795094021869963915318643663536132393791");
double delta = 0.26;
// this scale is sufficient to get the exact integer part
// it is roughly equal to the number of digits in the result's integer part
final int SCALE = 170;
BigDecimal x = new BigDecimal(N);
BigDecimal y = BigDecimal.valueOf(delta);
int maxIntDigits = 1;
int intDigits = x.precision() - x.scale();
int rescale = Math.max(intDigits - maxIntDigits, 0);
BigDecimal rescaledX = x.scaleByPowerOfTen(-rescale);
BigDecimal z = BigFunctions.exp(
BigFunctions.ln(rescaledX, SCALE)
.add(BigFunctions.ln(BigDecimal.TEN, SCALE).multiply(BigDecimal.valueOf(rescale)))
.multiply(y),
SCALE)
.setScale(0, BigDecimal.ROUND_FLOOR)
.multiply(BigDecimal.valueOf(2));
System.out.println(z);
Output:
32803899270296656086551107648280231830313861082788744611797945239672375099902513857958219091523648839375388564236289659519690404775361188478777234501437677352644

Work out co-prime of two numbers in java

I have two BigIntegers holding prime numbers.
BigInteger a = BigInteger.probablePrime(16, new Random());
BigInteger b = BigInteger.probablePrime(16, new Random());
BigInteger c;
How would I find the co-prime of these two BigIntegers and store it in c;
Co-primality of integers a and b refers to the question of whether the gcd(a,b) = 1 or not. Java's BigInteger class provides the gcd method to compute this:
BigInteger c = a.gcd(b); // or equivalently b.gcd(a).

How do you use BigInteger? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
How do you use BigInteger exactly? I'm trying to do the following:
import java.util.*;
import java.math.*;
public class hello{
public static void main(String[] args){
for(int i = 0; i <= 1024; i++){
BigInteger a = new BigInteger(Math.pow(2,i));
System.out.println(a);
}
}
}
I want a to hold this potentially huge value so that I can manipulate it in the program.
Math.pow returns a double and 2^i cannot be represented in a double as it is way too big.
You need to use the pow method from BigInteger:
BigInteger a = BigInteger.valueOf(2).pow(i);
Java's Math class does not have methods of BigInteger.
Use BigInteger's method instead.
BigInteger a = new BigInteger(Math.pow(2,i));
System.out.println(a);
should be
BigInteger a = new BigInteger("2").pow(i); // String to BigInteger, and then power
System.out.println(a);
or
BigInteger a = BigInteger.valueOf(2).pow(i); // long to BigInteger, and then power
System.out.println(a);
There is no BigInteger(double) constructor. Try using new BigInteger(String) and instead of Math.pow use BigInteger#pow method which also returns BigInteger.
for (int i = 0; i < 200; i++) {
BigInteger a = new BigInteger("2").pow(i);
System.out.println(a);
}
Think of BigInteger like a string. You can't use any of the arithmetic, relational, and unary operators on it like you would do for primitive data types. Instead, you have to use the methods inside the BigInteger class to perform operations on BigInteger.
For example, if you wanted to multiply two BigIntegers, you can't do this:
BigInteger a = (new BigInteger("5"))*(new BigInteger("7"));
Instead, you must declare two BigIntegers and then multiply them with .multiply()
BigInteger a = new BigInteger("5");//note how these numbers are like strings
BigInteger b = new BigInteger("7");
BigInteger c = a.multiply(b);
So in regards to your program where you want to print the powers of two, you have to use BigInteger in a slightly different way.
for(int i = 0; i <= 1024; i++){
BigInteger a = new BigInteger("2").pow(i);
System.out.println(a);
}
Note how the value inside the .pow() is an int. That's specified in the BigInteger documentation. Essentially, BigInteger is a very powerful tool when calculating large values, but it is also more tedious and requires lengthier and more involved code.

Time complexity of the simple java code

How to determine time complexity of this code ? I guess that modPow method is the most "expensive ".
import java.math.BigInteger;
public class FermatOne
{
public static void main(String[] args)
{
BigInteger a = new BigInteger ("2");
BigInteger k = new BigInteger ("15");
BigInteger c = new BigInteger ("1");
int b = 332192810;
BigInteger n = new BigInteger ("2");
BigInteger power;
power = a.pow(b);
BigInteger exponent;
exponent = k.multiply(power);
BigInteger mod;
mod = exponent.add(c);
BigInteger result = n.modPow(exponent,mod);
System.out.println("Result is ==> " + result);
}
}
Well this particular code deterministically runs in O(1).
However, in more general terms for arbitrary variables, multiply() will run in O(nlog n) where n is the number of bits.
pow() method will run in O(log b) for small a and b. This is achieved by exponentiation by squaring. For larger values, the number of bits gets large (linearly) and so the multiplication takes more time. I'll leave it up to you to figure out the exact analysis.
I'm not 100% about the details about modPow(), but I suspect it runs similarly to pow() except with the extra mod at each step in the exponentiation by squaring. So it'll still be O(log b) multiplications with the added benefit that the number of bits is bounded by log m where m is the mod.
tskuzzy is correct.
But maybe reading between the lines a bit, and assuming this is a homework question, they probably want you to realize that there are several operations happening in this method with varying complexities. And then they probably want you to realize that the complexity of the overall method is the same as whatever the most complex operation is that happens in the method.

Categories