I have a BigInteger value, let's say it is 282 and is inside the variable x. I now want to write a while loop that states:
while b2 isn't a perfect square:
a ← a + 1
b2 ← a*a - N
endwhile
How would I do such a thing using BigInteger?
EDIT: The purpose for this is so I can write this method. As the article states one must check if b2 is not square.
No number can be a perfect square unless its digital root is 1, 4, 7, or 9. You might already be familiar with computing digital roots. (To find digital root of a number, add all its digits. If this sum is more than 9, add the digits of this sum.
Compute the integer square root, then check that its square is your number. Here is my method of computing the square root using Heron's method:
private static final BigInteger TWO = BigInteger.valueOf(2);
/**
* Computes the integer square root of a number.
*
* @param n The number.
*
* @return The integer square root, i.e. the largest number whose square
* doesn't exceed n.
*/
public static BigInteger sqrt(BigInteger n)
{
if (n.signum() >= 0)
{
final int bitLength = n.bitLength();
BigInteger root = BigInteger.ONE.shiftLeft(bitLength / 2);
while (!isSqrt(n, root))
{
root = root.add(n.divide(root)).divide(TWO);
}
return root;
}
else
{
throw new ArithmeticException("square root of negative number");
}
}
private static boolean isSqrt(BigInteger n, BigInteger root)
{
final BigInteger lowerBound = root.pow(2);
final BigInteger upperBound = root.add(BigInteger.ONE).pow(2);
return lowerBound.compareTo(n) <= 0
&& n.compareTo(upperBound) < 0;
}
I found a sqrt method used here, and simplified the square test.
private static final BigInteger b100 = new BigInteger("100");
private static final boolean[] isSquareResidue;
static{
isSquareResidue = new boolean[100];
for(int i =0;i<100;i++){
isSquareResidue[(i*i)%100]=true;
}
}
public static boolean isSquare(final BigInteger r) {
final int y = (int) r.mod(b100).longValue();
boolean check = false;
if (isSquareResidue[y]) {
final BigInteger temp = sqrt(r);
if (r.compareTo(temp.pow(2)) == 0) {
check = true;
}
}
return check;
}
public static BigInteger sqrt(final BigInteger val) {
final BigInteger two = BigInteger.valueOf(2);
BigInteger a = BigInteger.ONE.shiftLeft(val.bitLength() / 2);
BigInteger b;
do {
b = val.divide(a);
a = (a.add(b)).divide(two);
} while (a.subtract(b).abs().compareTo(two) >= 0);
return a;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With