C ++ Prime因子程序2问题

时间:2010-09-27 14:04:03

标签: c++ variables primes

好的所以我正在编写一个程序(用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 个答案:

答案 0 :(得分:3)

对于1),您需要使用更大的数据类型。这里64位整数就足够了,所以将int更改为平台上调用的64位整数类型(可能是long,或者long long)。< / p>

对于2),问题似乎是break之前有return false。中断导致代码立即停止while循环并在循环后立即继续执行。在这种情况下(你的编译器应该警告你),似乎没有分配返回值,因此返回的实际值实际上是任意的。

答案 1 :(得分:1)

虽然其他人已经指出了您的数据类型存在问题,但第一个功能的结构存在一些问题,这些问题立即引起了我的注意。 (顺便说一句,你的缩进是令人沮丧的。)看看这个精简版:

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跳转到循环体后面,但是那里没有声明,所以代码离开函数而没有显式返回任何东西!那就是调用所谓的 Undefined Behavior 。 (根据C ++标准,从这时起,你的程序就可以随意做任何事情,包括返回随机值(大多数实现都会这样做),格式化你的HD,调用令人讨厌的鼻恶魔,或者回归到底是什么你期望的,但只在星期天。)

最后,break发生在return false;之前,因此从未到达。实际上 你的编译器应警告 。如果没有,您可能无法在最高警告级别进行编译。 (你应该打开它。总是尝试在最高警告级别干净地编译代码。)如果确实如此,学会注意编译器警告。它们是在编译期间诊断问题的非常重要的工具。 (请记住:在编译过程中诊断出的错误不需要测试,也不会向客户提供。)

答案 2 :(得分:0)

  1. 在64位系统上使用64位数字,或使用arbitrary precision arithmetic
  2. 的库
  3. 删除break之前的return false。由于中断,执行在循环外部恢复,return false永远不会执行。

答案 3 :(得分:0)

要存储大于4个字节的值(int的容量),您有多种选择。有关这些选项,请参阅this page。至于为什么你的程序返回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语句。