Find the sum of all the primes below two million. Project euler, C

Using float as the sum is the problem. The largest integer k such that all integers from [-k, k] are exactly representable in 32-bit float is 2^241; after that you will start losing precision in some integers. Since your sum is outside that range that, by an absurd margin, you lose precision and all bets are off.

You need to change to a larger type like long (assuming it's 64-bits on your machine). Make the change, and you'll get right answer (as I did with you code):

[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 explicit bits in the mantissa plus one hidden bit.


As @LeeDanielCrocker suggested, here is an implementation of the Sieve of Eratosthenes that solves the problem instantaneously:

#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; }

At ideone, that returns in thirty milliseconds. The optimized version shown below, which sieves only on odd numbers and handles 2 separately, runs in zero time (less than ten milliseconds) at ideone.

#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; }

If you're interested in programming with prime numbers, I modestly recommend this essay at my blog; it describes both algorithms given above, covers all the algorithms you will need to solve the prime-number problems at Project Euler, and includes source code in C and four other languages.


Please try this way, fast and simple:

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;
}

Tags:

C