patternjavaMinor
Simplifying Radical Expressions
Viewed 0 times
radicalexpressionssimplifying
Problem
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 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));
}
}Solution
Better approach
First, if you got rid of all floating point and just use
Second, your loop is trying to find the greatest factor of the number that is a square. But for a large number it will run for a long time because you check every number up to \$\sqrt n\$. You can shorten the time by dividing any factors you find along the way. For example, if 2 divides into \$n\$ 7 times, then \$2^3\$ can be factored out of the square root and \$2\$ will remain under the radical. I.e.:
If: \$n = 2^7 * m\$
\$\sqrt n = 2^3 \sqrt {2 * m}\$
If a factor divides an even number of times into your number, then it can be pulled out without leaving anything under the radical.
After you simplify for each factor, you keep going to find factors of \$m\$, which is smaller, so you only need to check factors up to \$\sqrt m\$. You just need to keep track of the internal and external factors as you go.
In the worst case (if the number is prime), it will still take the same amount of time. You could research factorization algorithms if you want something better.
First, if you got rid of all floating point and just use
long, that would fix your inaccuracy problems.Second, your loop is trying to find the greatest factor of the number that is a square. But for a large number it will run for a long time because you check every number up to \$\sqrt n\$. You can shorten the time by dividing any factors you find along the way. For example, if 2 divides into \$n\$ 7 times, then \$2^3\$ can be factored out of the square root and \$2\$ will remain under the radical. I.e.:
If: \$n = 2^7 * m\$
\$\sqrt n = 2^3 \sqrt {2 * m}\$
If a factor divides an even number of times into your number, then it can be pulled out without leaving anything under the radical.
After you simplify for each factor, you keep going to find factors of \$m\$, which is smaller, so you only need to check factors up to \$\sqrt m\$. You just need to keep track of the internal and external factors as you go.
In the worst case (if the number is prime), it will still take the same amount of time. You could research factorization algorithms if you want something better.
Context
StackExchange Code Review Q#106078, answer score: 3
Revisions (0)
No revisions yet.