Простой код не выводит все необходимые результаты - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть Java код, который выполняет следующие действия: 1. Работает со всеми комбинациями целых чисел a,b от 2 до 100 в наборах по два. Например, 2,2, 2,3, ..., 100,100. Я просто использую две for петли для этого. 2. Для каждого набора проверяется, является ли gcd обоих целых чисел 1 (игнорирует наборы, где gcd равно 2 или более). Я использую класс BigInteger, потому что у него есть метод для этого. 3. Если gcd равно 1, проверьте, можно ли примирить каждое из двух целых чисел в идеальную степень с базой 2 или более и степенью 3 или более. Вот как я это делаю: например, давайте рассмотрим набор 8,27. Во-первых, код находит max из двух. Тогда для этого набора максимальная мощность, которую мы можем проверить, равна Math.log10(27)/Math.log10(2), потому что минимальная база может быть 2. Это просто трюк из области математики. Держите это в переменной powlim. Затем я использую for l oop и Math.pow, чтобы проверить, имеют ли все два целых числа идеальные корни nth, как это;

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 гарантирует, что я не получу повторяющиеся значения, такие как 8,27 и 27,8. Для моих целей это одно и то же. Ниже приведен весь код:
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);
                        }
                    }
                }
            }
        }
    }
}

Пока все хорошо. Код работает отлично. Тем не менее, некоторые результаты, которые соответствуют всем вышеперечисленным критериям, игнорируются. Например, когда я запускаю приведенный выше код, я получаю; 8,27 16,81 27,64 Чего я не понимаю, так это почему набор типа 8,81 игнорируется. Его gcd равно 1, и оба эти целых числа могут быть выражены в виде совершенных степеней базовой 2 или более и показателя степени 3 или более. 8 равно 2^3 и 27 равно 3^3. Почему это происходит? В качестве альтернативы, хорошо, если вы предоставите свой собственный код, который выполняет ту же задачу. Мне нужно выяснить, насколько редки (или распространены) такие наборы.

1 Ответ

0 голосов
/ 12 апреля 2020

Math.pow (б, 1,0 / мощность); для 81 это 4,32. Затем вы округляете 4,32, а 4 при степени 3 равно 64. 64 не равно 81. Что вы должны делать, так это: Math.round (Math.pow (roota, power)) == a

Кроме того, вам нужно выполнить итерации по степеням A и B по отдельности и проверить, может ли число быть укоренено. Это означает дополнительную проверку, совпадает ли округленное значение double с двойным. (Значение pow 1/3, 1/4 дает целочисленный результат.)

    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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
...