skip to Main Content

This is a small code to calculate prime numbers, compile with gcc (Debian 8.3.0-6) 8.3.0
When I use int64_t p = 0, it work fine. use int64_t p, it work error.What’s wrong with this?

The variable p will be assigned by use scanf

OK with int64_t p = 0:

gcc t.c && ./a.out
input a prime:3
i:2 < number:3
3 is a prime, again

error with int64_t p:

gcc t.c && ./a.out
input a prime:3
i:2 < number:3
i:3 < number:3
i:4 < number:3
i:5 < number:3
i:6 < number:3
i:7 < number:3
i:8 < number:3
i:9 < number:3
i:10 < number:3
i:11 < number:3
i:12 < number:3
i:13 < number:3
3 not a prime, again
#include <stdint.h>
#include <stdio.h>

int32_t isPrime(int64_t number)
{
    int64_t i = 2;
    for(; i < number; i++)
    {   
        printf("i:%d < number:%dn",i, number);
        if((number % i) == 0)
            return 0;
        if ((i * i) >= number)
            break;
    }   
    return 1;
}

int32_t main(void)
{
    int64_t t = 0;
    int64_t p;                                                                                                                                                                                                                              
    //int64_t p = 0;

    printf("input a prime:");
    do  
    {   
        scanf("%d",&p);
        getchar();
        if (isPrime(p))
            printf("%d is a prime, again:", p); 
        else
            printf("%d not a prime, again:", p); 
    }while(1);
}

2

Answers


  1. You’ve declared p as an int64_t, but %d means int. The conversion specifiers for int64_t and other stdint.h types live in inttypes.h:

    #include <inttypes.h>
    
    scanf("%" SCNd64, &p);
    

    Similarly, when printing it (using the correct specifier here would have shown you the problem):

    printf("i:%" PRId64 " < number:%" PRId64 "n", i, number);
    

    Both of these mistakes are something good compilers should be able to warn you about – for example, clang will do it by default. If you’re using gcc, be sure to compile with at least gcc -Wall.

    Also, checking the return value of scanf to make sure it succeeded is a good idea. Exiting otherwise is fine if you don’t want to do any deeper recovery.

    if (scanf("%" SCNd64, &p) != 1) {
        return EXIT_FAILURE;
    }
    

    Finally, the correct return type for main is int, not int32_t.

    Login or Signup to reply.
  2. This (scanf("%d",&p);) is the wrong code to read int64_t. Formally, you need scanf("%" SCNd64, &p) — and <inttypes.h> (instead of, or as well as, <stdint.h>).

    You would probably get away with scanf("%lld", &p); since on most machines, int64_t is a synonym for long long.

    You should also check that scanf() returns 1 before using the result.

    When you initialize p, you get the ‘correct’ part of p set by the scanf() call because you’re on a little-endian machine, and the remainder is zero as you want. But doing that invokes undefined behaviour. Anything could happen. It is unportable (it probably won’t do what you want on big-endian machines), and completely unreliable because it is undefined behaviour.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search