Square Root and ++ Operators for BigInteger and BigDecimal - java

Is there any ready-made Java library for operations over BigInteger and BigDecimal objects?
I'd like to use square root and ++ operators.
Thank you
P.S. BigInteger.add() should be used instead of ++, I got it.
What about square root from BigInteger?

BigInteger is immutable. That makes something like the ++-operator on it conceptually impossible. You can not change the value of a given BigInteger, just like you can't do it with String.
Incrementing
You always have to create a new BigInteger that holds the incremented value (you can then of course store the reference to that BigInteger in the same variable).
Edit: As pointed out in the comment, "incrementing" would look like:
BigInteger result = a.add(BigInteger.ONE);
or
a = a.add(BigInteger.ONE);
Note that both lines do not change the value of the BigInteger which a originally points to. The last line creates a new BigInteger and stores the reference to it in a.
Calculating the Square
You can calculate the square of a BigInteger like this:
BigInteger a = BigInteger.valueOf(2);
BigInteger a_square = a.multiply(a); // a^2 == a * a
or
BigInteger a_square = a.pow(2);
Square Root
The code is taken from https://gist.github.com/JochemKuijpers/cd1ad9ec23d6d90959c549de5892d6cb .
It uses simple bisection and a clever upper bound. Note that a.shiftRight(x) is equivalent to a / 2^x (only for non-negative numbers, but that is all we deal with, anyway)
BigInteger sqrt(BigInteger n) {
BigInteger a = BigInteger.ONE;
BigInteger b = n.shiftRight(5).add(BigInteger.valueOf(8));
while (b.compareTo(a) >= 0) {
BigInteger mid = a.add(b).shiftRight(1);
if (mid.multiply(mid).compareTo(n) > 0) {
b = mid.subtract(BigInteger.ONE);
} else {
a = mid.add(BigInteger.ONE);
}
}
return a.subtract(BigInteger.ONE);
}
Using Operators Instead of Methods
Operator overloading like in C++ is not possible in Java.

Related

How to divide a BigInteger by integer?

(EDIT: Before more people downvote, I did look at the Javadoc beforehand but since I'm a beginner I wasn't sure where in the document to look. See my response to Jim G, which is posted below. I understand that this question is maybe viewed as too basic. But I think it has some value for other beginners in my situation. So please, consider the full situation from a beginner's perspective before downvoting.)
I want to divide a BigInteger by a regular integer (i.e. int) but I don't know how to do this. I did a quick search on Google and on Stack Exchange but didn't find any answers.
So, how can I divide a BigInteger by an int? And while we're at it, how can I add/subtract BigInts to ints, compare BigInts to ints, et cetera?
Just use BigInteger.valueOf(long) factory method. An int can be implicitly "widened" to be long... This is always the case when going from smaller to large, e.g. byte => short, short => int, int => long.
BigInteger bigInt = BigInteger.valueOf(12);
int regularInt = 6;
BigInteger result = bigInt.divide(BigInteger.valueOf(regularInt));
System.out.println(result); // => 2
Convert the Integer to BigInteger and than divide both BigInteger, as following:
BigInteger b = BigInteger.valueOf(10);
int x = 6;
//convert the integer to BigInteger.
BigInteger converted = new BigInteger(Integer.toString(x));
//now you can divide, add, subtract etc.
BigInteger result = b.divide(converted); //but this will give you Integer values.
System.out.println(result);
result = b.add(converted);
System.out.println(result);
Above division will give you Integer values of divisions, to get exact values, use BigDecimal.
EDIT:
To remove two intermediate variables converted and result in above code:
BigInteger b = BigInteger.valueOf(10);
int x = 6;
System.out.println(b.divide(new BigInteger(Integer.toString(x))));
OR
Scanner in = new Scanner(System.in);
System.out.println(BigInteger.valueOf((in.nextInt())).divide(new BigInteger(Integer.toString(in.nextInt()))));

BigInteger power of a BigDecimal in Java

I tried to get the power of a double value where the exponent is very large (Java BigInteger can contain it (the exponent), for example: 10^30)
That is, I want to find something like 1.75^(10^30) or 1.23^(34234534534222).if the output is too large modify it by getting the modulus by a prime like 10^9+7.
If I want to find a power of an Integer I can use BigInteger.modPow() method which take BigInteger arguments:
( BigInteger modPow(BigInteger exponent, BigInteger m) )
As far as i can go this is what i got in Java
new BigDecimal("1.5").pow(1000); // .pow() can get only integers as a parameter , but i want to pass a big number like a BigInteger
I cannot find an equivalent for that (BigInteger.modPow()) in java for BigDecimal
, or i'm missing that.
Are there any ways to do that - Calculate a large power of a floating point number (a Decimal)?
Example of input and output :
Input : num // or 1.5 or any decimal number. can be an integer also.
exponent : exp // big integer or a Long value
output : num^exp // num to ther power exp
i.e like calculating 1.23^(34234534534222)
if the output is too large modify it by getting the modulus by a prime like 10^9+7
There is a Math.BigDecimal implementation of core mathematical functions which has:
static java.math.BigDecimal powRound(java.math.BigDecimal x, java.math.BigInteger n)
Raise to an integer power and round.
which seems exactly what you need. The fact that there is an external library for it denotes that there is no core implementation of a method like this in java.Math.
As a side note I can say that if your input is considerably small in terms of decimal places (thus no irrational) just like 1.5 you can transform it in 15/10 and do
(15^BigInteger)/(10^BigInteger)
with the modPow(BigInteger exponent, BigInteger m) of BigInteger. This obviously raises the complexity and the numbers to calculate.
There are several caveats. As Gábor Bakos pointed out, the resulting value would most likely contain too many digits to even be represented as a BigDecimal.
Additionally, these number of digits grows quickly, so computing something like 2.034234534534222 is completely out of scope in terms of storage (and, as I assume, in terms of required time).
You mentioned that the value may be computed modulo a large prime when it becomes "too large". Although you did not say what exactly this means, this won't necessarily help you here, because using modulo will not truncate the decimal places. You'll somehow have to limit the precision in which the computation takes place.
However, the most simple implementation using exponentiation by squaring could roughly look like this:
import java.math.BigDecimal;
import java.math.BigInteger;
public class BigDecimalPow {
public static void main(String[] args) {
BigDecimal b = new BigDecimal(1.5);
BigInteger e = new BigInteger("325322");
BigDecimal result = pow(b, e);
System.out.println("Done "+result.scale());
System.out.println(result);
}
/**
* Computes d to the power of e
* #param b The value
* #param e The exponent
* #return The power
*/
private static BigDecimal pow(BigDecimal b, BigInteger e) {
BigDecimal result = BigDecimal.ONE;
BigDecimal p = b;
int skipped = 0;
while (e.compareTo(BigInteger.ZERO) > 0) {
if (e.and(BigInteger.ONE).equals(BigInteger.ONE)) {
if (skipped > 0) {
if (skipped > 29) {
p = pow(p, BigInteger.ONE.shiftLeft(skipped));
} else {
p = p.pow(1 << skipped);
}
skipped = 0;
}
result = result.multiply(p);
}
skipped++;
e = e.shiftRight(1);
System.out.println(e);
}
return result;
}
}
Note: The implementation above is really simple. There most likely is a solution that is more efficient for some cases, or uses the modulo operation to support "larger" numbers. But you simply can not represent (potentially) 34234534534222 decimal places unless you have 34 terabytes of RAM and a JVM with long addressing, so I doubt that there will be a solution that satisfies the requirements that you stated until now - but would upvote+bounty anyone who proved me wrong...

BigInteger Modulo '%' Operation & Less Than / More Than Operations

Hi I have an algorithm in which I need to apply operations to BigInt's.
I understand that BigInt's can be manipulated using the Maths class such as:
import java.math.*;
BigInteger a;
BigInteger b = BigInteger.ZERO;
BigInteger c = BigInteger.ONE;
BigInteger d = new BigInteger ("3");
BigInteger e = BigInteger.valueOf(5);
a.multiply(b);
a.add(b);
a.substract(b);
a.divide(b);
I need to be able to apply greater than for a while condition e.g.
while (a > 0) {
Which gives me a syntax error saying "bad operand types for binary operator '>', first type: java.math.BigInteger, second type: int.
I also need to be able to apply the modulo (%) operator to a BigInteger.
b = a % c;
Can anyone suggest a way of doing this?
If there isn't a solution then I'm just going to have to somehow manipulate my BigInteger into an unique Long using a reduce function (which is far from ideal).
Silverzx.
To compare BigInteger, use BigInteger.compareTo.
while(a.compareTo(BigInteger.ZERO) > 0)
//...
And for modulo (%), use BigInteger.mod.
BigInteger blah = a.mod(b);
For comparing BigIntegers you may use compareTo, but in the special case when you compare to 0 the signum method will also do the job(and may be a bit faster). As for taking the remainder of a given division you may use the method mod(better option here) or alternatively use divideAndRemainder which returns an array with both the result of the division and the remainder.

How can I examine each digit of a BigInteger in Java?

How can I examine each digit (System.out.println() each digit, for instance) of a BigInteger in Java? Is there any other way other than converting it to a string?
Straight-forward code prints digits from the last towards the first:
private static void printDigits(BigInteger num) {
BigInteger[] resultAndRemainder;
do {
resultAndRemainder = num.divideAndRemainder(BigInteger.TEN);
System.out.println(Math.abs(resultAndRemainder[1].intValue()));
num = resultAndRemainder[0];
} while (num.compareTo(BigInteger.ZERO) != 0);
}
The BigInteger API docs do not appear to provide any functionality as such. Moreover, the numbers are quite likely not represented in base 10 (since it would be quite inefficient). So it is most likely that the only way to inspect the decimal digits of a BigInteger is to look at its string representation.
You could of course use basic math to calculate each digit. Especially the method divideAndRemainder might help here. But I doubt, that this is more efficient than converting to a String and examing the characters. BigInteger math is more expensive than plain int or long math after all.
I think the only way you could do it is converting it into a String and verify each char. Here is an example:
BigInteger bigInteger = new BigInteger("123");
String bigIntegerValue = bigInteger.toString();
for(int i = 0; i < bigIntegerValue.length(); i++) {
System.out.println(bigIntegerValue.charAt(i));
}
Maybe you can try to examine each bit in your biginteger using BitSet like this,
BitSet bitSet = BitSet.valueOf(bigInteger.toByteArray());
It seems pretty simple what you need to do get each digit of a number.
create a loop that tracks if you number is greater then ten and then preform a mod 10 operation on it and then divide by ten.
while (num >10)
{
System.out.println(num%10);
num = num/10;
}

BigInteger.pow(BigInteger)?

I'm playing with numbers in Java, and want to see how big a number I can make. It is my understanding that BigInteger can hold a number of infinite size, so long as my computer has enough Memory to hold such a number, correct?
My problem is that BigInteger.pow accepts only an int, not another BigInteger, which means I can only use a number up to 2,147,483,647 as the exponent. Is it possible to use the BigInteger class as such?
BigInteger.pow(BigInteger)
Thanks.
You can write your own, using repeated squaring:
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;
}
might not work for negative bases or exponents.
You can only do this in Java by modular arithmetic, meaning you can do a a^b mod c, where a,b,c are BigInteger numbers.
This is done using:
BigInteger modPow(BigInteger exponent, BigInteger m)
Read the BigInteger.modPow documentation here.
The underlying implementation of BigInteger is limited to (2^31-1) * 32-bit values. which is almost 2^36 bits. You will need 8 GB of memory to store it and many times this to perform any operation on it like toString().
BTW: You will never be able to read such a number. If you tried to print it out it would take a life time to read it.
Please be sure to read the previous answers and comments and understand why this should not be attempted on a production level application. The following is a working solution that can be used for testing purposes only:
Exponent greater than or equal to 0
BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ZERO; i.compareTo(exponent) != 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(base);
}
return result;
}
This will work for both positive and negative bases. You might want to handle 0 to the power of 0 according to your needs, since that's technically undefined.
Exponent can be both positive or negative
BigDecimal allIntegersPow(BigInteger base, BigInteger exponent) {
if (BigInteger.ZERO.compareTo(exponent) > 0) {
return BigDecimal.ONE.divide(new BigDecimal(pow(base, exponent.negate())), 2, RoundingMode.HALF_UP);
}
return new BigDecimal(pow(base, exponent));
}
This re-uses the first method to return a BigDecimal with 2 decimal places, you can define the scale and rounding mode as per your needs.
Again, you should not do this in a real-life, production-level system.
java wont let you do BigInteger.Pow(BigInteger) but you can just put it to the max integer in a loop and see where a ArithmeticException is thrown or some other error due to running out of memory.
2^2,147,483,647 has at least 500000000 digit, in fact computing pow is NPC problem, [Pow is NPC in the length of input, 2 input (m,n) which they can be coded in O(logm + logn) and can take upto nlog(m) (at last the answer takes n log(m) space) which is not polynomial relation between input and computation size], there are some simple problems which are not easy in fact for example sqrt(2) is some kind of them, you can't specify true precision (all precisions), i.e BigDecimal says can compute all precisions but it can't (in fact) because no one solved this up to now.
I can suggest you make use of
BigInteger modPow(BigInteger exponent, BigInteger m)
Suppose you have BigInteger X, and BigInteger Y and you want to calculate BigInteger Z = X^Y.
Get a large Prime P >>>> X^Y and do Z = X.modPow(Y,P);
For anyone who stumbles upon this from the Groovy side of things, it is totally possible to pass a BigInteger to BigInteger.pow().
groovy> def a = 3G.pow(10G)
groovy> println a
groovy> println a.class
59049
class java.math.BigInteger
http://docs.groovy-lang.org/2.4.3/html/groovy-jdk/java/math/BigInteger.html#power%28java.math.BigInteger%29
Just use .intValue()
If your BigInteger is named BigValue2, then it would be BigValue2.intValue()
So to answer your question, it's
BigValue1.pow(BigValue2.intValue())

Categories

Resources