素数判定とエラトステネスの篩

回 3-3 分野 3 整数と余り

素数判定は、ある整数 n が素数 (1 と自分の 2 つしか約数を持たない 2 以上の整数) かを決める計算です。一番素直な試し割りは、2 から √n までの整数で割り切れるかを見れば足ります。n が合成数なら、√n 以下の約数が必ず 1 つあるからです。1000003 なら 1000 回ほどの割り算で素数と分かります。たくさんの素数をまとめて出すときはエラトステネスの篩、暗号のような数百桁の数ではミラー・ラビン法を使います。

下のコードの数を書き換えると、その場で素数かどうかを判定できます。そのうえで、割る数を √n までに減らす理由と、篩で一度に全部を出す手を、割り算の回数で比べます。

1000003 は素数か、何回割れば分かるのか

1000003 が素数かどうかを確かめるのに、2 から 1000002 まで全部で割ってみる必要はありません。1000 まで割れば足ります。偶数を飛ばせば、500 回ほどです。

素数は、1 と自分の 2 つしか約数を持たない 2 以上の整数です。2、3、5、7、11 と続きます。2 以上で素数でない数を合成数と呼びます。1 は約数が 1 つしかないので、素数でも合成数でもありません。

素数判定は、暗号の鍵を作るときにも、競技プログラミングの問題にも出てきます。この回では、まず数を入れて判定できるコードを動かし、割る数を √n までに減らせる理由、たくさんの素数を一度に出すエラトステネスの篩、数百桁の数で使う判定法を、割り算の回数で比べます。

数を入れて判定する

下のコードの nums の中の数を書き換えて動かすと、その数が素数か、素数でなければ一番小さい約数は何かを出します。素数のときの後ろの数は、割り算の回数です。

動かす 素数判定 (数を書き換えて動かす)

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

1 素数でない
2 素数 1
91 約数 7
97 素数 5
1000003 素数 500
999999000001 素数 500000

91 は 7 × 13 で、素数ではありません。97 は素数です。1000003 は 500 回の割り算で、12 桁の 999999000001 も 50 万回ほどの割り算で素数と分かりました。12 桁を超えると、この書き方では時間がかかり始めます。そのためこのコードは、10^12 (1 兆) 以下の数だけを受け付け、超える数は assert で止めます。もっと大きな数は、下のミラー・ラビン法の節で扱います。

試し割りは √n まででよい理由

n が合成数なら、n = a × b (a ≤ b、どちらも 2 以上) と書けます。もし a も b も √n より大きいと、a × b は n より大きくなってしまいます。ですから小さい方の a は √n 以下です。

つまり、2 から √n までのどの数でも割り切れなければ、n は素数です。100 = 10 × 10 なら、√100 = 10 までに約数 2 が見つかります。97 なら √97 ≒ 9.8 なので、2 から 9 まで割れば足ります。

さらに、2 で割り切れなかった数は、4 や 6 でも割り切れません。2 のあとは奇数だけを試せば、回数はおよそ半分になります。

判定のしかた1000003 の割り算の回数
2 から n−1 まで全部1000001 回
2 から √n (1000) まで999 回
2 と、3 から √n までの奇数500 回

エラトステネスの篩

1 から N までの素数を全部出すなら、1 つずつ試し割りするより、エラトステネスの篩 (ふるい) が速いです。手順は次の通りです。

  1. 2 から N までの数を並べ、全部に「素数かもしれない」の印を付ける
  2. 印の残っている一番小さい数 p は素数。p × p から、p の倍数の印を消す
  3. p × p が N を超えたら止める。印の残っている数が全部の素数

倍数を p × p から消すのは、それより小さい p の倍数 (2p、3p など) は、もっと小さい素数の倍数として消されているからです。止める所が √N なのも、試し割りと同じ理由です。

篩で消す回数は、N を 2、3、5、7 と素数で割った数の和で、およそ N log log N です。log log N はとてもゆっくり増えるので、N が 100 万でも、数 1 個あたり 2 回ほどの印消しで済みます。

動かして確かめる

1 本目は、1000003 の判定を 3 つの書き方で行い、割り算の回数を上の表と照らします。

動かす 割る範囲を変えて回数を比べる

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

全部 1000001
√nまで 999
奇数 500
√n 1000

全部で割ると 100 万回、√n までなら 999 回、奇数だけなら 500 回でした。素数のときは最後まで割り切れないので、回数は割る範囲の数と同じです。

2 本目は、篩で 100 以下の素数を全部出し、100 万以下の素数を数えます。

動かす エラトステネスの篩

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

25 個
2 3 5 7 11 13 17 19 23
29 31 37 41 43 47 53 59 61
67 71 73 79 83 89 97
100万以下 78498
印を消した回数 2122048

100 以下の素数は 25 個で、2 から 97 までです。100 万以下の素数は 78498 個で、印を消した回数は約 212 万回、数 1 個あたり 2 回ほどでした。同じ 78498 個を 1 つずつ試し割りで見つけるより、ずっと少ない手間です。

3 本目は、試し割りを全部の数にかけた割り算の回数と、篩の印消しの回数を、N を変えて比べます。

動かす 試し割りと篩の手間を比べる

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

1000 5456 1411
10000 118756 16981
100000 2755286 193078

N が 10 倍になるたびに、試し割りの合計は約 22 倍、23 倍と増えますが、篩は約 12 倍、11 倍です。N = 10 万では、試し割りの割り算の回数が篩の印消しの約 14 倍になりました。差は N が大きいほど開きます。素数をまとめて使うなら、先に篩で表を作っておくのが定石です。

4 本目は、フェルマーの小定理で判定する手と、それをすり抜ける数です。p が素数なら、p と互いに素な a について a^(p−1) を p で割った余りは 1 です。逆に、余りが 1 にならない a が 1 つでもあれば、n は合成数です。

動かす フェルマーの判定と 561

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

91 False
True
互いに素な a 319
通った a 319

91 は、a = 2 で余りが 1 にならないので、合成数だと分かります。ところが 561 = 3 × 11 × 17 は、2 から 560 までの 561 と互いに素な 319 個の a の全部で余りが 1 になり、フェルマーの判定をすり抜けます。こうした合成数をカーマイケル数と呼びます。フェルマーの判定は「合成数だ」とは言い切れますが、「素数だ」とは言い切れません。

5 本目は、フェルマーの判定を強めたミラー・ラビン法です。底に最初の 12 個の素数 (2 から 37) を使うと、3.18 × 10^23 より小さい数では、判定が外れないことが分かっています。

動かす ミラー・ラビン法で大きな数を判定

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

561 False
1000003 True
1000000007 True
2305843009213693951 True
2147483662032385529 False

561 は合成数と正しく出ました。19 桁の 2^61 − 1 は、試し割りなら √n が約 15 億なので、奇数だけでも 7 億回を超える割り算が要ります。ミラー・ラビン法なら、底 12 個の分だけ繰り返し二乗法を回すだけで、一瞬で素数と分かります。2 つの素数を掛けた最後の数は、合成数と出ました。

素数判定は、どこで外れるか

1 と 2 の扱い

1 は素数ではありません。「割り切れる数が見つからなければ素数」と書くと、1 は割る数が 1 つも無いので素数と出てしまいます。2 は偶数で唯一の素数で、「偶数なら素数でない」と書くと 2 を落とします。上のコードは、どちらも先に別に扱っています。

小数の √ で範囲がずれる

int(math.sqrt(n)) は、n が大きいと小数の誤差で 1 ずれることがあります。n = (10^8 + 7)² − 1 では、本当の整数の平方根 100000006 に対し、int(math.sqrt(n)) は 100000007 を返します。整数のまま正しく求める math.isqrt(n) か、d * d <= n の比べを使います。

フェルマーの判定だけで決める

4 本目の通り、561 のようなカーマイケル数は、フェルマーの判定を全部すり抜けます。カーマイケル数は無数にあることが、1994 年に Alford、Granville、Pomerance によって示されています。素数と言い切るには、ミラー・ラビン法のような強い判定を使います。

篩の大きさ

篩は N 個の印を持つので、N が 10 億なら、1 個 1 バイトでも 1GB の場所が要ります。範囲が大きいときは、区間ごとに篩う書き方 (区間篩) に分けます。

仕事とコンテストでどう使うか

素数判定と篩が出てくる場面は、次の通りです。

  • 暗号の鍵。RSA の鍵は、数百桁の素数を 2 つ選んで作る。乱数で候補を作り、ミラー・ラビン法のような判定に何度もかけて素数を選ぶ。FIPS 186-5 は、こうした素数の作り方と判定の回数を決めている
  • 競技プログラミング。「N 以下の素数を数える」「素因数分解を何度も行う」問題は、先に篩で表を作る。1 つの大きな数の判定なら、ミラー・ラビン法
  • 素因数分解。篩で「一番小さい素因数」を表にしておくと、どの数も割り算を繰り返すだけで素因数分解できる
  • ハッシュ。ハッシュ表の大きさや、ハッシュの式に掛ける数に、素数を使うことがある

よくある問い

1 は素数ですか

素数ではありません。素数は「1 と自分の 2 つしか約数を持たない 2 以上の整数」と決めています。1 を素数に入れると、12 = 2 × 2 × 3 = 1 × 2 × 2 × 3 のように、素因数分解の形が 1 つに決まらなくなるからです。

素数は無限にありますか

無限にあります。素数が有限個だとして、全部を掛けて 1 を足した数を作ると、その数はどの素数で割っても 1 余ります。するとその数自身か、その約数に、並べた中に無い素数があることになり、有限個という仮定と食い違います。この証明はユークリッドの『原論』にあります。

一番大きな素数はいくつですか

素数は無限にあるので、一番大きな素数はありません。知られている中で一番大きな素数は、2026年10月30日に GIMPS (メルセンヌ素数を探す共同の計算の取り組み) の一覧で確かめた時点で、2024年10月に見つかった 2^136279841 − 1 で、10 進で 41024320 桁です。

素数判定の計算量はどのくらいですか

試し割りは √n 回ほどの割り算で、n の桁数に対しては指数関数的に増えます。ミラー・ラビン法は、底 1 つあたり繰り返し二乗法 1 回分で、桁数の多項式の手間です。2002 年には、乱数も仮定も使わずに桁数の多項式の時間で判定できる AKS 素数判定法が示されましたが、実際にはミラー・ラビン法の方が速く、よく使われます。

確認クイズ

答えだと思う選択肢を押すと、その場で正誤と理由が開きます。3 問すべてに正しく答えると、この回は修了で、石が緑に変わります (この端末のブラウザに残ります)。間違えた問いは、あとから解き直せます。

1 問目

100 以下の素数はいくつありますか。

2 問目

試し割りで 10007 が素数かを確かめます。割り切れるかを試す数は、どこまでで足りますか。

3 問目

561 について、正しいのはどれですか。

説明課題

「n が 2 から √n までのどの整数でも割り切れなければ、n は素数と言ってよい」理由を、n = a × b と書いて 3 文で説明してください。書いたら、下の模範解答を開いて比べてください。

模範解答

自分の説明を書いてから開いて、比べてください。

この回の先の一歩

前計算の篩と、1 つずつの判定を使い分けられると、素数が出る問題で間に合う手を選べます。いまの自分が転職までの道のどの段にいるかは、転職診断で確かめられます。

もっと深く

この回の続きを、ゆめさくのコースの章や道具で深められます。頁の中の確認クイズに答えたあと、手を動かす量を増やしたいときに使ってください。

一次資料

どれも 2026年10月30日に開いて、題と中身を確かめました。

次へ

分野 3 整数と余りの回

  1. 3-1最大公約数と互除法約数、素数、ユークリッドの互除法頁で読む
  2. 3-2余りと合同式余りの足し算と掛け算、繰り返し二乗法頁で読む
  3. 3-3素数を速く探す試し割りは √n まで、エラトステネスの篩この回

分野 3 の頁へ戻るほかの分野を見る