카테고리 없음

(정수론/C) 범위 지정해서 소수 구하기 (unsigned long)

미친토끼 2021. 9. 22. 14:27
// 지정한 범위 안에서 소수를 구하는 프로그램
// 프로그램명: get_primes_between.c
// 사용법:  ./get_primes_between 2 1000  // 2부터 1000까지의 소수 구하기 (양쪽 포함)

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

int isPrime(unsigned long num) {
  unsigned long i, root_num;
  
  root_num = (int)sqrt(num) + 1;
  //if (num <= 1) return 0;  // 1 이하라면 소수 아님
  if (num % 2 == 0) return 0; // 2의 배수라면 소수 아님

  for (i = 3; i < root_num; i+=2)
    if (num % i == 0)
      return 0;
    //printf("i = %lu", i);
  return 1;
}

unsigned long getPrimes(unsigned long num) {
    printf("2\n");   // 소수 2를 별도로 출력
    // 속도를 위해 소수 2는 제외하고 3부터 홀수만 검사함. 2 외에는 짝수에 소수 없음.
    for (unsigned long i = 3; i <= num; i+=2) {
        if(isPrime(i))   //소수면 출력한다.
            printf("%lu\n", i);
    }
}

// 시작 숫자 이상에서 해당 갯수만큼 소수를 구해준다
unsigned long getPrimes2(unsigned long start_num, unsigned long howmany){
  unsigned long count = 0;
  
  if (start_num == 2) {
    count += 1;
    printf("%lu\n", start_num);
    start_num += 1;
  }
  if (start_num % 2 == 0)  // 짝수라면 +1을 해서 홀수로 시작
    start_num += 1;
  for (unsigned long i = start_num; count < howmany; i+=2) {
    if(isPrime(i)) {
      count += 1;
      printf("%lu\n", i);
    }
  }
}

// start_num과 end_num 사이의 소수를 구해준다. 양쪽 포함.
unsigned long getPrimes3(unsigned long start_num, unsigned long end_num) {
  if (start_num == 2) {
    printf("%lu\n", start_num);
    start_num += 1;
  }
  if (start_num % 2 == 0)  // 짝수라면 +1을 해서 홀수로 시작
    start_num += 1;
    
    // 속도를 위해 홀수로만 검사함. 2 외에는 짝수에 소수 없음.
  for (unsigned long i = start_num; i <= end_num; i+=2) {
    if(isPrime(i))   //소수면 출력한다.
      printf("%lu\n", i);
  }
}


int main (int argc, char *argv[]) {
  //unsigned long MAX_NUM = 100000000;    // 소수 1억개 구하기
  //printf("UINT_MAX = %u\n", UINT_MAX);     //           4294967295 : 42억
  //printf("ULONG_MAX = %lu\n", ULONG_MAX);  // 18446744073709551615 : 1844경6..조

  if (argc < 3) {
    printf("This program will get prime numbers between 'start_number' and 'end_number' (include both sides).\n");
    printf("Usage: %s  start_number end_number\n", argv[0]);
    return -1;
  }

  getPrimes3(atol(argv[1]), atol(argv[2]));
  //getPrimes2(UINT_MAX, 10);
  // getPrimes(UINT_MAX, MAX_NUM);
  
  return 1;
}