I have Java code that does the following:
1. Works with all combinations of integers a,b
from 2
to 100
in sets of two. For instance, 2,2
, 2,3
,...
,100,100
. I just use two for
loops for that.
2. For each set, checks whether the gcd
of both integers is 1
(ignores sets where the gcd
is 2 or more). I use the BigInteger
Class because it has a method for that.
3. If the gcd
is 1
, check whether each of the two integers can be reconciled into a perfect power of base2
or more and exponent 3
or more. This is how I do that: For instance, let's consider the set 8,27
. First, the code finds the max
of the two. Then, for this set, the maximum power we can check for is Math.log10(27)/Math.log10(2)
because the least the base can be is 2
. This is just a trick from the field of mathematics. Hold that in variable powlim
. I then use a for
loop and Math.pow
to check if all of the two integers have perfect nth
roots like so;
for (double power = 3; power <= powlim; power++) {
double roota = Math.pow(a, 1.0 / power);
double rootb = Math.pow(b, 1.0 / power);
if ((Math.pow(Math.round(roota), power) == a) == true &&
(Math.pow(Math.round(rootb), power) == b) == true) {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
a<b
condition makes sure that I don't get duplicate values such as both 8,27
and 27,8
. For my purposes, the two are one and the same thing. Below is the entire code:public static void main(String[] args) {
for (int a = 2; a <= 100; a++) {
for (int b = 2; b <= 100; b++) {
BigInteger newa = BigInteger.valueOf(a);
BigInteger newb = BigInteger.valueOf(b);
BigInteger thegcd = newa.gcd(newb);
if (thegcd.compareTo(BigInteger.ONE) == 0) {
double highest = Math.max(a, b);
double powlim = (Math.log10(highest) / Math.log10(2.0));
for (double power = 3; power <= powlim; power++) {
double roota = Math.pow(a, 1.0 / power);
double rootb = Math.pow(b, 1.0 / power);
if ((Math.pow(Math.round(roota), power) == a) == true
&& (Math.pow(Math.round(rootb), power) == b) == true {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
}
}
}
}
}
So far so good. The code works fine. However, some few outputs that meet all the above criteria are ignored. For instance, when I run the above code I get;
8,27
16,81
27,64
What I don't understand is why a set like 8,81
is ignored. Its gcd
is 1
and both of those integers can be expressed as perfect powers of base 2
or more and exponent 3
or more. 8
is 2^3
and 27
is 3^3
. Why does this happen? Alternatively, it's fine if you provide your very own code that accomplishes the same task. I need to investigate how rare (or common) such sets are.
Math.pow(b, 1.0 / power); for 81 is 4.32 Then you round 4.32, and 4 at the power 3 is 64. 64 is not equal to 81. What you should be doing is: Math.round(Math.pow(roota, power)) == a
Also, you need to iterate trough the powers of A and B separately, and check if the number can be rooted. This means an additional check if the rounded-down value of the double is the same as the double. (Meaning the pow 1/3, 1/4 yields an integer result.)
public static void main(String[] args) {
for (int a = 2; a <= 100; a++) {
for (int b = 2; b <= 100; b++) {
BigInteger newa = BigInteger.valueOf(a);
BigInteger newb = BigInteger.valueOf(b);
BigInteger thegcd = newa.gcd(newb);
if (thegcd.compareTo(BigInteger.ONE) == 0) {
double highest = Math.max(a, b);
double powlim = (Math.log10(highest) / Math.log10(2.0));
for (double powerA = 3; powerA <= powlim; powerA++) {
double roota = Math.pow(a, 1.0 / powerA);
for (double powerB = 3; powerB <= powlim; powerB++) {
double rootb = Math.pow(b, 1.0 / powerB);
if (rootb == Math.floor(rootb) && roota == Math.floor(roota)) {
if ((Math.round(Math.pow(roota, powerA)) == a) && (Math.round(Math.pow(rootb, powerB)) == b)) {
if (a < b) {
System.out.println(a + "\t" + b);
}
}
}
}
}
}
}
}
}