새 UI(Beta)를 사용 중입니다.기존 UI로 돌아가기

이 페이지는 기계 번역으로 자동 번역되었습니다. 번역이 정확하지 않을 수 있으니 양해 부탁드립니다.

keisan일상생활과 업무에 도움이 되는 고정밀 계산 사이트

100만까지의 소수 나열

작성자: ameya 님실행 횟수: 13362

※ 이 라이브러리는 회원이 작성한 작품입니다. 본 사이트는 그 내용에 대해 관여하지 않습니다.

북마크 관리
에라토스테네스의 체를 사용하여 100만까지의 소수를 표시할 수 있습니다.
2부터
사이의 모든 소수를 표시합니다.
'휠 체(Wheel Sieve)'라고 하는 고속화 기법을 사용하고 있습니다. 아마도요.
영어 해설은 잘 이해하지 못했지만, 위키백과에 있던 이미지를 보고 추측하여 대충 구성해 보았습니다.

/* 먼저 2*3*5*7=210까지의 자연수 중에서 2, 3, 5, 7의 배수를 제외한 배열 Wheel을 준비합니다. 처리상의 이유로 211까지 포함되어 있지만, 이는 ‘210+1’이며, 다음 소수인 것은 우연일 뿐입니다. */
numeric wheel[] = {1,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101, 103, 107, 109, 113, 121, 127, 131, 137, 139, 143, 149, 151,157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199, 209, 211};
/* Wheel의 요소 수는 */
whlen = 48;
/* 차분(의 1/2) 배열을 준비합니다(사정상 시작이 1개 어긋납니다. 회전 처리가 번거로우므로 2회분 있습니다)*/
numeric ntb105[] = {1,2,1,2,3,1,3,2,1,2,3,3,1,3,2,1,3,2,3,4,2,1,2,1,2,4,3,2,3,1,2,3,1,3,3,2,1,2,3,1,3,2,1,2,1,5,1,5,1,2,1,2,3,1,3,2,1,2,3,3,1,3,2,1,3,2,3,4,2,1,2,1,2,4,3,2,3,1,2,3,1,3,3,2,1,2,3,1,3,2,1,2,1,5,1,5};
/* 체의 인덱스에서 휠상의 위치를 뺀 테이블도 만들고 */
numeric nrev105[105];
for (k = 1; k <= whlen; k = k + 1) {
  nrev105[(wheel[k] - 3) / 2] = k - 1;
}
/* 나머지는 적당히 돌리면 됨 */
numeric numx[48];
idx = 4;
while (idx < enphsiev) {
  for (z = 0; z < whlen; z = z + 1) {
    if (sieve[idx] == 0) {
      m = nrev105[mod(idx, 105)];    /* wheel 시작 위치 */
      num = idx * 2 + 3;         /* 이 식은 sieve의 인덱스를 실제 수치로 변환합니다 */
      j = ((num * num) - 3) / 2;     /* 이는 제곱을 역변환하여 인덱스로 되돌리는 것입니다 */
      for (k = 0; k < whlen; k = k + 1) {
        numx[k] = ntb105[m + k] * num; /* 곱셈은 연산 부하가 크기 때문에 테이블로 미리 저장해 둡니다 */
      }
      while (j < sievemax) {      /* 체의 메인 루프 */
        for (k = 0; k < whlen; k = k + 1) {
          sieve[j] = 1;
          j = j + numx[k];
        }
      }
    }
    idx = idx + ntb105[z];
    if (idx >= enphsiev) {break;}
  }
}
※체 배열 sieve[idx]는 idx=0 → 3, idx=1 → 5, idx=2 → 7과 같이 대응합니다.
※참고로 메인 루프에서 sieve[j]의 인자 j가 최대 whlen-1만큼 maxsieve를 초과하므로 어떤 대책이 필요합니다.
※완성하려면 다음 코드와 결과를 표시하는 처리가 필요합니다.
/* 입력 변수를 UpperLimit라고 하면 */
sievemax = ceiling(UpperLimit / 2);
enphsiev = int(sqrt(UpperLimit) / 2);
/* 입력 수치는 변경할 때까지 상수로 취급되는 듯하여 배열의 인자로 사용할 수 있음 */
numeric sieve[UpperLimit];

이 계산에 대한 고객 피드백이 아직 없습니다.