代码之家  ›  专栏  ›  技术社区  ›  samuraiseoul

C++素数程序2题

  •  0
  • samuraiseoul  · 技术社区  · 14 年前

    我的程序似乎成功地做到了这一点,但它有两个问题,

    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 回复  |  直到 14 年前
        1
  •  3
  •   Michael Madsen    14 年前

    int s到在您的平台上调用的任何64位整数类型(可能是 long long long ).

    对于2),问题似乎是你有一个 break return false . 中断会导致代码立即停止while循环,并在循环结束后立即继续执行。在这种情况下,似乎从未分配过返回值(这是您的编译器需要的) 应该 因此实际返回的值实际上是任意的。

        2
  •  1
  •   sbi    14 年前

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

    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 跳转到循环体的后面,但是那里没有语句,所以代码没有显式返回任何内容就离开了函数!这就是所谓的 未定义的行为

    最后,那 打破 发生在 return false; 这是永远也达不到的。事实上 . 如果没有,则很可能无法以最高警告级别编译。(你应该打开这个。 始终尝试以最高警告级别干净地编译代码。 )如果是的话, 学会注意编译器警告

        3
  •  0
  •   Sjoerd    14 年前
    1. 在64位系统上使用64位数字,或使用具有此功能的库 arbitrary precision arithmetic
    2. break return false 返回false 永远不会被执行。
        4
  •  0
  •   AndyPerfect    14 年前

    要存储大于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语句。