灌注或不灌注输出缓慢

时间:2018-11-05 07:10:43

标签: c integer primes slowdown

这是C程序。这是我下面的code。我在终端中使用了nano。当我使用./a.out 9872349901进行编译和测试时,花了整整一分钟的时间才得到结果……有人知道为什么它这么慢吗? (我相信数字可能太长了,但是我在进行int isprime(long long n) {时是针对我的CS课程课程,这是获得分数的自动分配成绩,但是因为labcheck不会显示,所以它不会显示出来等待它。

/**
 * Make a function called isprime that returns true (i.e. 1) if the integer
 * number passed to it is prime and false (i.e. 0) if it is composite (i.e.
 * not prime.)  A number is composite if it is divisible by 2 or any odd number
 * up to the square root of the number itself, otherwise it is prime.
 * Hint: n is divisible by m if (n % m == 0)
 */

/**
 * Using the isprime function you made above, test if a number provided on the
 * command line is prime or not. The program should print a usage message if no
 * number is provided ("Usage: p4 <number>\n") and print a warning if the number
 * is less than 2 ("input number should be > 1\n") and should be able to handle
 * numbers greater than 4 billion.
 * 
 * Example input/output:
 * ./p4 9872349901
 * 9872349901 is prime
 * ./p4 65
 * 65 is not prime
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>

int isprime(long long n) {
    for (long long i = 2; i != n; ++i)
        if (n%i == 0)
            return 0;
    return 1;
}

int main (int argc, char *argv[])
{
    if (argc < 2)
    {
        printf ("Usage: p4 <number>\n");
        return -1;
    }
    char* p;
    long long n = strtoll(argv[1], &p, 10);
    if (n < 2 || *p != '\0')
    {
        printf ("input wrong\n");
        return -1;
    }
    int result = isprime(n);

    if (result == 1)
        printf ("%lld is prime\n", n);
    else
        printf ("%lld is not prime\n", n);
    return 0;
}

许多不同的数字都可以很好地工作,但对于9872349901来说却不能,因为这是教师将测试我的作业的数字。

这是我做“实验室检查”时的预览

cs25681@cs:/instructor/class/cs25681/cs/h5> labcheck 5
Checking assignment #5:
p1:
p2:
p3:
p4:
-3.0 output of program (p4) is not correct for input '9872349901':
------ Yours: ------
---- Reference: ----
9872349901 is prime
--------------------
p5:
p6:
p7:
p8:

我想测试每个不同的数字,所以这里是./a.out <number>的预览

cs25681@cs:/lecture/class/cs25681/cs> ./a.out 3
3 is prime
cs25681@cs:/lecture/class/cs25681/cs> ./a.out 1
input wrong
cs25681@cs:/lecture/class/cs25681/cs> ./a.out 9
9 is not prime
cs25681@cs:/lecture/class/cs25681/cs> ./a.out 9872349901
9872349901 is prime
cs25681@cs:/lecture/class/cs25681/cs> echo "took 43 seconds to output"
took 43 seconds to output
cs25681@cs:/lecture/class/cs25681/cs> 

1 个答案:

答案 0 :(得分:3)

将我的评论转化为答案。

使用:

for (long long i = 2; i * i <= n; ++i)

这会限制测试,直到i刚好大于n的平方根为止,如代码注释中所建议。

更好的算法将测试2,然后测试奇数3、5、7,...,这将大大减少测试量。

最好还是测试2和3,然后对于N = 1、2、3,...测试6 * N±1,这将测试5、7、11、13、17、19、23、25(这是第一次)它没有选择素数对),等等。

if (n <= 1)
    return 0;
if (n == 2 || n == 3)
    return 1;
if (n % 2 == 0 || n % 3 == 0)
    return 0;
for (unsigned long long x = 5; x * x <= n; x += 6)
{
    if (n % x == 0 || n % (x + 2) == 0)
        return 0;
}
return 1;

请注意,您不使用sqrt(N);您使用i * i <= N。或者,如果必须使用sqrt(N),则需要在循环之前计算值,然后使用计算出的值四舍五入到下一个整数(ceil()中的<math.h>)。至少这是几年前我的基准测试告诉我的。

JFTR:将上面的代码转移到问题中的代码中,并定时p4 9872349901产生的报告是,它在大约0.005秒的经过时间中是最佳的(在2.7 GHz的普通2016 15“ MacBook Pro上英特尔酷睿i7处理器)。我还尝试了98723499017333(在数字的右端加4位数字,并在击中该数字之前获得了许多非素数),在0.044秒内报告为素数。当然,主要报告更快。