I'm working on a program to handle simplifying square roots (radicals). My biggest issue is, in order to stay precise, I can't have input any longer than 15 digits. Whenever a number is longer than 15 digits, it loses precision when converted to double
when I try to determine if the square is actually a factor. I realize I can just use an int
and call it a day, but I'd really like to be able to use bigger numbers. Is there a better way I can do this to handle numbers longer than 15 digits? Also, any other optimization or readability ideas would be greatly appreciated! This is the best algorithm I could come up with for finding square roots.
import java.util.Scanner;
public class SimpRad
{
public static final String SQUARE_ROOT_SYMBOL = "\u221A";
public static final int INPUT_FAILURE = -1;
static long[] simplify( long square )
{
double outside = 1;
double inside = square;
long[] simplified = { 1, square };
// Check if it's already a perfect square
outside = Math.sqrt(square);
if (outside == Math.floor(outside))
{
simplified[0] = (long)outside;
simplified[1] = 1;
return simplified;
}
// Find all the squares that could be factors and see if they are
for (long factor = 2, sqr = 4; sqr <= (square / 2); factor++, sqr = (factor * factor))
{
// Is this square a factor?
double in = (double)square / sqr;
if (in == Math.floor(in))
{
simplified[0] = factor;
simplified[1] = (long)in;
}
}
// Otherwise, since it hasn't simplified, return the original radical
return simplified;
}
public static String display( long radicand, long multiplier, long newRad, boolean negative )
{
String i = negative ? "i" : "";
String negativeStr = negative ? "-" : "";
// If it's already simplified
if (multiplier == 1)
{
return (SQUARE_ROOT_SYMBOL + negativeStr + radicand + " = " + i
+ SQUARE_ROOT_SYMBOL + newRad);
}
// If it's a perfect square
else if (newRad == 1)
{
return (SQUARE_ROOT_SYMBOL + negativeStr + radicand + " = " + multiplier + i);
}
else
{
return (SQUARE_ROOT_SYMBOL + negativeStr + radicand + " = " + multiplier + i
+ SQUARE_ROOT_SYMBOL + newRad);
}
}
public static void main( String[] args )
{
Scanner userInput = new Scanner(System.in);
long radicand;
long[] rads;
String radStr;
boolean isNegative = false;
do
{
System.out.print("Please enter the current radicand: ");
radStr = userInput.next();
try {
radicand = Long.parseLong(radStr);
} catch (NumberFormatException e) {
System.out.print("That's not an integer! ");
radicand = INPUT_FAILURE;
continue;
}
if (radicand < 0)
{
radicand = -radicand;
isNegative = true;
}
if (radicand > 999999999999999l)
{
System.out.print("Please enter a radicand that is 15 digits or less. ");
radicand = INPUT_FAILURE;
}
} while (radicand < 0);
rads = simplify(radicand);
System.out.println(display(radicand, rads[0], rads[1], isNegative));
}
}