【问题标题】:Cannot calculate prime factors with a number with 12 digits in C无法用 C 中的 12 位数字计算素数
【发布时间】:2012-02-16 13:00:26
【问题描述】:

我试图通过在 Project Eular 页面上做示例来学习更多关于 C 代码的知识:http://projecteuler.net/problems 目前我试图从数字 600851475143 中计算出最高的素数。 这是我的代码:

/* The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?*/
#include <stdio.h>

unsigned long long GetPrimeFactor(unsigned long long number)
{
    /* printf("The number you typed was %d\n", number);*/
    unsigned long long prime = 2;
    unsigned long long LargestPrime = 0;

    while (prime != 0)
    {
        if(number%prime == 0)
        {
            if(number == prime)
            {
                if(LargestPrime < prime)
                    LargestPrime = prime;

                printf("End of prime factors \nLargest Prime: %d\nEnding Number: %d\n", LargestPrime, number);
                break;
            }
            else if(LargestPrime < prime)
                LargestPrime = prime;

            //divide number by prime

            number = number/prime;
            printf("Prime: %d\n", prime);
        }

        else
        {
            //get new prime
            prime = nextPrimeNumber(prime);
        }
    }
}

unsigned long long nextPrimeNumber(unsigned long long input)
{
    unsigned long long nextPrimeNumber;

    while(input !=0)
    {
        if( input < 0)
        {
            printf("The number you have entered is negative\n");
        }
        else if (input > 0)
        {
            nextPrimeNumber = input + 1;

            if(nextPrimeNumber%2 == 0 && nextPrimeNumber != 2)
            {
                nextPrimeNumber += 1;
            }

            while(!isPrime(nextPrimeNumber))
            {
                nextPrimeNumber += 2;
            }

            return nextPrimeNumber;
        }
    }
}

int isPrime(int number)
{
    int i;
    int prime = 1; //true

    if(number == 2)
        prime = 0; //false

    if(number%2 == 0 || number <= 1)
        prime = 0;
    else
    {
        for(i=3; i<sqrt(number) && prime == 1; i+=2)
            if(number%i == 0)
                prime = 0;
    }

    return prime;
}

int main(void)
{
    unsigned long long number;

    printf("Enter a Number: \n");
    scanf("%d", &number);
    GetPrimeFactor(number);

    return 0;
}

此代码适用于示例中的数字 13195,但当我尝试更大的数字时会变坏,我不确定是什么问题。

输出大数 600851475143:素数:3 素数:29 素数:5108231 等。 这不可能是正确的,因为这个数字无论如何都不能被 3 整除。

无法弄清楚出了什么问题,所以任何帮助都会很棒

【问题讨论】:

  • 600851475143 需要 40 位以二进制表示。显然你的ints 是 32 位宽的。尝试使用更大的类型,例如:long long unsigned
  • 您的函数定义顺序错误。编译器假定它们隐式返回int。这在尝试切换到更大的整数类型时会导致问题。在使用函数之前定义它们。
  • 1) int isPrime(int number) 应该是 int isPrime(unsigned long long number) 2) 有几个地方可以测试小于或等于。确保你不会在这些地方失败。

标签: c primes prime-factoring


【解决方案1】:

签名ints 最高可达 2147483647,unsigned ints 最高可达 4294967295,您可以使用unsigned long long,最高可达 18446744073709551615,如果您需要更大的东西,请使用任意精度/bignum 库,如 GnuMP (@ 987654321@)

更新您已编辑的问题:

您使用的 scanf 格式说明符甚至没有读取整个 unsigned long long,我在某处读到您必须使用 %llu,但是在我的 gcc 上这不起作用,我必须使用:

printf("Enter a Number: \n");
scanf("%I64d", &number);
printf("%I64d", number);  // <- make sure that this prints the number you 
                 // gave it before even calling GetPrimeFactor()

【讨论】:

  • 好的,我尝试通过将我的初始数字变量设为 unsigned long long,但现在它除以 181 再次无法发生,但我尝试将所有整数设为 unsigned long long
  • @spartan2417 你改变了问题,所以我编辑了我的答案。
  • 感谢您的帮助,我最终在页面顶部定义了我的函数,就像@Complicated See bio 说的那样。并使用 unsigned long long。但是我确实有人建议使用 uint64_t 代替?这还会有同样的效果吗?
  • @spartan2417 试试看,请告诉我们。
  • 它们都用于非常长的数字,但从外观上看,使用“uint64_t”而不是“long long”的唯一区别是 uint64_t 可以容纳 20 个十进制数字而不是 19 个跨度>
【解决方案2】:

你改变了scanf吗?

scanf("%L", &number)

【讨论】:

    猜你喜欢
    • 2018-06-12
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 2014-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多