Задачи программы C ++ Prime factor 2 - PullRequest
0 голосов
/ 27 сентября 2010

Хорошо, поэтому я пишу программу (на C ++), которая должна принимать число, пройти его, выяснить, являются ли его простые числа, если это так, добавить это к сумме, а затем вывести сумму всехпростых факторов вмененного числа.

Моя программа, кажется, успешно делает это, однако у нее есть 2 проблемы,

1) Число, которое я должен проверить, чтобы увидеть сумму простых факторовэто число (600851475143), но оно слишком велико для типа int. Я не уверен, какой другой тип переменной использовать или какие типы переменных нужно изменить. Мне бы очень хотелось получить четкое объяснение этого, если это вообще возможно.

2) По какой-то причине, когда программа проверяет, является ли 1 коэффициентом числа, а затем проверяет, является ли 1 простым, она говорит, что 1 является простым, хотя первый шаг функции для проверкиПосмотрим, простое ли это то, что если оно равно 1, то оно не простое. Я нашел решение для этого, сказав ему вычесть 1 из самого последнего значения для суммы всех простых факторов. Однако этоисправить, на самом деле не найти проблему.Если кто-то может указать, по крайней мере, где проблема, я был бы признателен!

Вот код, если у вас есть вопросы, пожалуйста, задавайте!

#include <iostream>

using namespace std;

bool prime (int recievedvalue) { //starts a function that returns a boolean with parameters being a factor from a number
     int j =1;
    int remainderprime = 0;
    bool ended = false;
    while (ended == false){ //runs loop while primality is undetermined
        if (recievedvalue == 1){ //if the recieved value is a 1 it isn't prime
            //not prime
            break; // breaks loop
            return false;
            }
        remainderprime=recievedvalue%j; //gives a remainder for testing
        if ((remainderprime==0 && j>2) && (j!=recievedvalue || j == 4)){ //shows under which conditions it isn't prime
        ended=true;
        //not prime
        return false;
        }
        else if (j==1){
            j++;
            }
        else if ( recievedvalue==2 || j==recievedvalue ){ // shows what conditions it is prime
          ended = true;
          //prime
          return true;
            }
            else {
            j++;
                }
        }
    }


int multiple(int tbfactor){ //factors and then checks to see if factors are prime, then adds all prime factors together
    //parameter is number to be factored
    int sum = 0;
    bool primetest = false;
    int remainderfact;
    int i=1;
    while (i<=tbfactor){ //checks if a i is a factor of tbfactor
        remainderfact=tbfactor%i;
        if (remainderfact==0){ //if it is a factor it checks if it is a prime
            primetest = prime(i);
        }
            if (primetest ==true){ //if it is prime it add that to the sum
                sum += i;
                primetest=false;
                }
                i++;
            }
            sum --; // for some reason it always ads 1 as a prime number so this is my fix for it
            return sum;
    }

int main()
{

    int input;
    int output;
    cout << "Enter number to find the sum of all it's prime factors: ";
    cin >> input;
        output = multiple(input);
    cout << output;
    return 0;
}

Я действительно новичок в этомПримерно через несколько дней, так что я очень незнаком с вещами прямо сейчас, поэтому, пожалуйста, объясните мне легко!Я с нетерпением жду вашей помощи!Спасибо!

Ответы [ 4 ]

3 голосов
/ 27 сентября 2010

Для 1) вам нужно использовать больший тип данных. Здесь должно быть достаточно 64-битного целого числа, поэтому измените int s на любой тип 64-битного целого, который вызывается на вашей платформе (вероятно, long или, возможно, long long).

Для 2) проблема заключается в том, что у вас есть break перед вашим return false. Прерывание приводит к тому, что код немедленно останавливает цикл while и продолжает выполнение сразу после цикла. Не похоже, что возвращаемое значение когда-либо назначается в этом случае (о чем ваш компилятор должен предупреждать вас), поэтому фактическое возвращаемое значение фактически произвольно.

1 голос
/ 27 сентября 2010

В то время как другие указали на проблему с вашими типами данных, есть несколько проблем со структурой первой функции, которые сразу же привлекли мое внимание.(Кстати, ваши отступления приводят в ярость.) Посмотрите на эту урезанную версию:

bool prime (int recievedvalue) {
    // ...
    bool ended = false;
    while (ended == false){
        if (...){
            break; // jumps _behind_ the loop
            return false;
        }
        // ...
        if (...) {
            ended=true;
            return false; // leaves function returning true
        }
        else if (...) {
            // ...
        }
        else if (...) {
          ended = true;
          return true; // leaves function returning false
        }
        else {
            // ...
        }
    }
    // behind the loop

    // leaves function returning random value
}

Например, каждый раз, когда вы устанавливаете переменную управления цикла ended, вы все равно выходите из цикла, используя другие средства, так что эта переменная не нужна.while(true) или for(;;) будет достаточно.

Кроме того, break прыгает за телом цикла, но там нет инструкции, поэтому код покидает функцию, не возвращая ничего явно!Это вызывает так называемое неопределенное поведение .(В соответствии со стандартом C ++ ваша программа с этого момента может делать все, что пожелает, в том числе возвращать случайные значения (большинство реализаций будут делать это), форматировать HD, вызывать на вас мерзких носовых демонов или возвращать именно то, что нужно.Вы ожидали, но только по воскресеньям.)

Наконец, это break происходит прямо перед return false;, который никогда не достигается.На самом деле ваш компилятор должен предупредить об этом .Если этого не произойдет, вы, вероятно, не компилируете на самом высоком уровне предупреждения.(Вы должны включить это. Всегда старайтесь аккуратно скомпилировать ваш код на самом высоком уровне предупреждения. ) Если это произойдет, научитесь обращать внимание на предупреждения компилятора .Они являются очень важным инструментом для диагностики проблем во время компиляции.(Помните: ошибки, диагностированные во время компиляции, не требуют тестирования и никогда не попадают к клиенту.)

0 голосов
/ 27 сентября 2010

Для хранения значений, превышающих 4 байта (емкость типа int), у вас есть различные варианты.Обратитесь к этой странице для этих опций.Относительно того, почему ваша программа возвращает true для проверки того, является ли 1 простым, проверьте этот раздел кода:

if (recievedvalue == 1){ //if the recieved value is a 1 it isn't prime
   //not prime
   break; // breaks loop
   return false;
}

Оператор break завершится, и значение false никогда не будет достигнуто.Чтобы решить проблему, удалите оператор break.

0 голосов
/ 27 сентября 2010
  1. Используйте 64-битное число в 64-битной системе или используйте библиотеку, которая выполняет арифметику произвольной точности
  2. Удалите break перед return false. Из-за перерыва выполнение возобновляется вне цикла, и return false никогда не выполняется.
...