所以,一切似乎都运行良好,但程序没有给我正确的答案。我的是142,915,960,832,而应该是142,913,828,922。差异是2,131,910(如果我仍然可以减去纸上的数字哈哈),我不知道我从哪里获得这两百万。有谁可以帮助我?
#include <stdio.h>
#include <math.h>
#define BELOW 2000000
int isaprime (int num);
int main (void) {
int i;
float sum = 0;
for (i = 2; i < BELOW; i++) {
if (isaprime(i) == 1) {
sum = sum + i;
printf ("\n%d\t%.1f", i, sum);
}
}
getch();
return 0;
}
int isaprime (int num) {
int i;
for (i = 2; i <= sqrt(num); i++) {
if (num % i == 0) {
return 0;
}
else {
;
}
}
return 1;
}
答案 0 :(得分:9)
使用float
作为sum
是问题所在。最大整数k
使得[-k, k]
中的所有整数完全在32位浮点数中表示为2 ^ 24 1 ;之后你会开始失去一些整数的精度。因为你的总和超出了这个范围,所以你会失去精确度并且所有的赌注都会被关闭。
您需要更改为更大的类型,例如long
(假设它在您的计算机上为64位)。做出改变,你会得到正确的答案(正如我对你的代码所做的那样):
[ec2-user@ip-10-196-190-10 ~]$ cat -n euler.c
1 #include <stdio.h>
2 #include <math.h>
3
4 #define BELOW 2000000
5
6 int isaprime (int num);
7
8 int main (void) {
9
10 int i;
11 long sum = 0;
12
13 for (i = 2; i < BELOW; i++) {
14
15 if (isaprime(i) == 1) {
16 sum = sum + i;
17 }
18 }
19 printf("sum: %ld\n", sum);
20
21 return 0;
22 }
23
24 int isaprime (int num) {
25
26 int i;
27
28 for (i = 2; i <= sqrt(num); i++) {
29 if (num % i == 0) {
30 return 0;
31 }
32 else {
33 ;
34 }
35 }
36
37 return 1;
38 }
[ec2-user@ip-10-196-190-10 ~]$ gcc euler.c -lm
[ec2-user@ip-10-196-190-10 ~]$ ./a.out
sum: 142913828922
1 :尾数中的23个显式位加上一个隐藏位。
答案 1 :(得分:5)
正如@LeeDanielCrocker所建议的,这是Sieve of Eratosthenes的一个实现,可以即时解决问题:
#include <stdio.h>
#include <string.h>
#define ISBITSET(x, i) (( x[i>>3] & (1<<(i&7)) ) != 0)
#define SETBIT(x, i) x[i>>3] |= (1<<(i&7));
#define CLEARBIT(x, i) x[i>>3] &= (1<<(i&7)) ^ 0xFF;
long long sumPrimes(int n) {
char b[n/8+1];
long long i, p;
long long s = 0;
memset(b, 255, sizeof(b));
for (p=2; p<n; p++) {
if (ISBITSET(b,p)) {
//printf("%d\n", p);
s += p;
for (i=p*p; i<n; i+=p) {
CLEARBIT(b, i); }}}
return s; }
int main(void) {
printf("%lld\n", sumPrimes(2000000));
return 0; }
在ideone,返回30毫秒。下面显示的优化版本仅在奇数和单独处理2上进行筛选,在ideone处以零时间(小于10毫秒)运行。
#include <stdio.h>
#include <string.h>
#define ISBITSET(x, i) (( x[i>>3] & (1<<(i&7)) ) != 0)
#define SETBIT(x, i) x[i>>3] |= (1<<(i&7));
#define CLEARBIT(x, i) x[i>>3] &= (1<<(i&7)) ^ 0xFF;
long long sumPrimes(int n) {
int m = (n-1) / 2;
char b[m/8+1];
int i = 0;
int p = 3;
long long s = 2;
int j;
memset(b, 255, sizeof(b));
while (p*p < n) {
if (ISBITSET(b,i)) {
s += p;
j = (p*p - 3) / 2;
while (j < m) {
CLEARBIT(b, j);
j += p; } }
i += 1; p += 2; }
while (i < m) {
if (ISBITSET(b,i)) {
s += p; }
i += 1; p += 2; }
return s; }
int main(void) {
printf("%lld\n", sumPrimes(2000000));
return 0; }
如果您对素数编程感兴趣,我在我的博客上谦虚地推荐这个essay;它描述了上面给出的两种算法,涵盖了解决Project Euler中素数问题所需的所有算法,并包含C语言和其他四种语言的源代码。
答案 2 :(得分:2)
请尝试这种方式,快速而简单:
int const MAX = 2000000;
int checkPrime(int n){
int range = n;
for (int i = 2; i < range; i++){
if (n%i == 0){
return 0;
}
range = n / i;
}
return 1;
}
int solution(){
double sum = 0;
for (int i = 2; i < MAX; i++){
if (checkPrime(i) == 1){
sum += i;
}
}
return sum;
}
答案 3 :(得分:0)
#include<stdio.h>
#define MAX 2000001
long long a[MAX],c=0;
main()
{
long long i=0,k,j,p,temp=0;
long long inc=0;
for(i=0;i<MAX;i++)
a[i]=i;
for(j=2;j*j<MAX;j++)
{
temp=j;
inc=2*temp;
k=((MAX-1)/temp)-1;
while(k)
{
printf("%d",inc);
printf("\n");
if(a[inc]!=0)
a[inc]=0;
inc+=temp;
--k;
}
}
for(p=0;p<MAX;p++)
{
if(a[p]!=0)
c=c+a[p];
printf("%lld",a[p]);
printf("\n");
}
printf(" The sum is : %lld",c-1);
}
答案 4 :(得分:0)
您可以使用Sieve algorithm,因为这是最快的: -
在C ++中
std::vector<int> generate_primes( int n )
{
std::vector<bool>sieve( n, true ) ;
for( std::size_t i = 2 ; i < sieve.size() ; ++i ) if( sieve[i] )
for( auto j = i*i ; j < sieve.size() ; j += i ) sieve[j] = false ;
std::vector<int> primes ;
for( std::size_t i = 2 ; i < sieve.size() ; ++i )
if( sieve[i] ) primes.push_back(i) ;
return primes ;
}
答案 5 :(得分:0)
虽然这个答案并不完美,但执行时间不到 3秒。 C#中的代码。
步骤1-省略了可被2,3,5,7整除的数字步骤2 - 要检查素数,我们不需要将给定的数字除以所有数字。使用平方根会将代码减少到一半。
using System;
namespace ProjectEuler
{
class Program
{
static void Main(string[] args)
{
long i, j, sum = 17;
bool flag = true;
for (i = 2; i < 2000000; i++)
{
if ((i % 2) != 0 && (i % 3) != 0 && (i % 5) != 0 && (i % 7) != 0)
{
flag = true;
for (j = 2; j <= Math.Sqrt(i); j++)
{
if (i % j == 0)
{
flag = false;
}
}
if (flag == true)
{
sum = sum + i;
}
}
}
Console.WriteLine(sum);
Console.ReadLine();
}
}
}
答案 6 :(得分:0)
{{1}}
答案 7 :(得分:0)
这是我的javascript解决方案:
function sumPrimes(num) {
// determine if a number is prime
function isPrime(n) {
if (n === 2) return true;
if (n === 3) return true;
if (n % 2 === 0) return false;
if (n % 3 === 0) return false;
var i = 5;
var w = 2;
while (i * i <= n) {
if (n % i === 0) {
return false;
}
i += w;
w = 6 - w;
}
return true;
}
// subtract 1 for 'not being prime' in my context
var sum = isPrime(num) ? num - 1 : -1;
for (var x = 0; x < num; x++) {
if (isPrime(x) === true) {
sum += x;
}
}
return sum;
}
答案 8 :(得分:-2)
您可以在c:
中查看以下代码/*Program to print sum of all prime numbers upto 2000000*/
/*To check whether a number is prime or not it takes n^2 time by
brute force but this program is sqrt(n) according to
mathematical rules to check prime number efficiently.
*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MAX 2000000
int main()
{
int i,j;
unsigned long int prod=0;
int prime;
for(i=2;i<=MAX;i++){
prime=1;
for(j=2;j<(int)(sqrt(i)+1);j++){
if(i%j==0){
prime=0;
break;
}
}
if(prime==1){
prod=prod+i;
}
}
printf("%ld",prod);
return 0;
}