1
#include<stdio.h>
int main(){
    int n,k=1;
    int i,j;
    unsigned long long int sum=0;
    scanf("%d",&n);
    for(i=2;i<n;i++){
        for(j=2;j<=i;j++){
            if(i%j==0)
                k++;
        }
        if(k==2){
            sum=sum+i;
        }
        k=1;
    }
    printf("%lld",sum);
    return 0;
}

This code is working fine for input 1000,10000 but not for 100000,1000000, I mean it prints nothing. I have also tried %I64d but no use.
How can I print sum ?

Jay
  • 9,585
  • 6
  • 49
  • 72
  • 6
    You want `%llu` for *unsigned* – Kninnug Sep 11 '14 at 13:54
  • 4
    It might just take a long time to execute. Are you sure the program finishes executing? – Gutblender Sep 11 '14 at 13:58
  • Works for me. Are you leaving it long enough to run? Or can you find a better algorithm to identify primes? This one is fairly brute-force and slow, and doesn't e.g. abort scanning for a given number as soon as it knows it can't be a prime. – Rup Sep 11 '14 at 13:58
  • http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes – Barmar Sep 11 '14 at 14:09
  • 2
    The statement "prints nothing" implies that you have no idea about debugging your program, you just run it and expect to see results. Please make sure that the call to `printf` is actually executed before deciding that it "prints nothing". – barak manos Sep 11 '14 at 14:19
  • 1
    What's the size of an `int` on your platform? If it happens to be 16 bits, then things may fail when you try to read your input and store that into `n` (in this case, the last 2 numbers). –  Sep 11 '14 at 14:58
  • Related to the title of the question (which seems to not reflect the actual OP's issue): http://stackoverflow.com/q/8132399/3194340 – n0p Sep 11 '14 at 15:04

1 Answers1

3

I suggest you print the sum at each iteration instead of just at the end, so you can see the progress of the computation. Besides being easier to debug your printf statement, you can then also detect a possible wrap around (if unsigned long long is not enough for the sum, for example).

Anyway -- I think your question is actually related to your printf format string: use %llu instead of %lld. See the code below:

int main(){
    int n,k=1;
    int i,j;
    unsigned long long int sum=0;
    scanf("%d",&n);
    for(i=2;i<n;i++){
        for(j=2;j<=i;j++){
            if(i%j==0)
                k++;
        }
        if(k==2){
            sum=sum+i;
        }
        k=1;
        /* This helps you see what's going on: */
        printf("sum is %llu\n",sum);
    }
    printf("%llu",sum);
    return 0;
}

I have used %llu instead of %lld, and it works fine. If I change it back to %lld, nothing is printed on each iteration.

And see that your input (n) may not exceed the maximum size of int on your platform. (But the sum may be larger, since you declared it as unsigned long long).

Also, when checking for primes, you can do some basic optimizations:

  • The only even number you need to check is 2. All other primes are odd.
  • You don't need to check farther than up to the square root of n. Or, equivalently: suppose you are testing if k divides n. If n/k<k (or if k*k>n), you may stop testing.

Also, you may use the standard boolean type that is available in C.

See the comments in the code below.

#include<stdio.h>
#include<math.h>
/* stdbool defines the type "bool", which can be "true" or "false": */
#include<stdbool.h>

int main(){
    int n;
    int i,j;

    /* prime is initialized to true, since we presume every number is prime
       until we find a divisor for it */
    bool prime = true;

    /* sum is initialized to zero. */
    unsigned long long int sum=0;

    scanf("%d",&n);

    /* If n=2, the result is zero. But if it's greater than two, we need
       to count 2 and start searching from 3. It's easier this way, because then
       we can use i=i+2 in the for loop. */
    if (n>2)
        sum = 2;

    /* no need to count from 2. We start from 3 and count every two numbers. */           
    for(i=3;i<n;i=i+2){
        /* same here. And, since this is the divisor we're looking for, we only 
           need to go up to sqrt(i). We use the long casting here because checking
           j*j<=i would not fit in an int type if j^2 is greater than the maximum
           int. This is a corner case, that happens for example when i is maxint
           (j-1)^2 is below and and j^2 is above it. */
        for(j=3;(long)j*j<=i;j=j+2)
            if(i%j==0) {
                prime = false;
                /* get out, since we already know that this one is composite! */
                break;
            }

        /* no divisors? add it to sum! */
        if (prime)
            sum = sum + i;

        /* reset prime to true, we'll start again with next i */
        prime = true;

        printf("sum is %llu\n",sum);
    }
    printf("%llu\n",sum);
    return 0;
}

These are the reasonably simple optimizations that you can do. There are others, and if you are interested, you can study the sieve of Erathostenes or (if you are math inclined), the Miller-Rabin test (which is not deterministic, but may be of interest). The C library GMP has Miller-Rabin available if you want to use it.

Jay
  • 9,585
  • 6
  • 49
  • 72
  • 1
    Minor: `ceill(sqrt(i))` (spelling ? `ceil()`) should be calculated before the `for(j...)` loop rather than each time in the loop. – chux - Reinstate Monica Sep 11 '14 at 17:49
  • chux: right, it is being calculated every time. Will fix it in the answer. But I really meant `ceill`, which returns long. Thinking of it again, since i is int, there is no need to use `ceill`. Thanks! – Jay Sep 11 '14 at 17:50
  • 1
    Given that `double` typically can not represent every `long long x`, and `double y = sqrt(x)`, the `y` calculated _may_ be too small even when mathematically `y*y == x` exactly. Your `ceill()` or `ceil()` is a good step but I am not confident either are sufficient. With systems that calculate the remainder and quotient with little extra performance cost, checking when the quotient is less than `j` is an alternate end-loop condition that does not touch FP math. – chux - Reinstate Monica Sep 11 '14 at 17:57
  • 1
    Further speed-up, add `break`. `if(i%j==0) { prime = false; break; }`. Ahh, but I now see your "There are others...". +1 for a generally good approach. – chux - Reinstate Monica Sep 11 '14 at 18:20