10章 原始根(primitive root)


pを素数、aを1<a<pとする。
aのn乗(1<n<p)の mod p の時の値を調べてみる。
例えば、p=7の時の値を調べて見よう。

  1  2  3  4 
1p7  
2a , n123
31=MOD(RC1^R2C,R1C2)=MOD(RC1^R2C,R1C2) 
42   

R3C2 に計算式、=MOD(RC1^R2C,R1C2) を入力し、R3C2 から R8C7 までコピーする。
R1C2 にはpの値を代入する。
結果は以下のとおり。

  1  2  3   4  5  6  7 
1p7      
2a , n 123456
31 111111
42 241241
53 326451
64 421421
75 546231
86 616161

p=7に対してa=3の時は、6乗(=p−1)の時はじめて1となり、
かつ1からp−1までの数が全て現れる。
このような性質を持つ数を、素数pの原始根(primitive root)と呼ぶ。


上の表を眺めていると、いくつかの点に気付く。

等。


100以下の素数(2、3を除く)について、原始根を求めてみよう。
素数pに対して、2 <= a <= p-1 の範囲で、aが原始根か否かを調べて表示する。
原始根か否かの判定は、ワーク領域として (p-1) 個分の配列 t(p-1) を用意して0で初期化、
1 <= i <= (p-1) の範囲で、ai mod p の値を計算、
t(i) が0のときは格納(t(i)=1とする)、
t(i) が1の時は (p-1) 乗する前に同じ余りになってしまったことを意味し、
原始根とはなり得ない。1 <= i <= (p-1) で、t(i) が全て 1 となった場合、aは原始根となる。
Excel のマクロは以下のようになる。

Sub Record9()
    Worksheets("sheet2").Activate

'   prime table
    Dim p(25)
    p(1) = 2: p(2) = 3: p(3) = 5: p(4) = 7: p(5) = 11
    p(6) = 13: p(7) = 17: p(8) = 19: p(9) = 23: p(10) = 29
    p(11) = 31: p(12) = 37: p(13) = 41: p(14) = 43: p(15) = 47
    p(16) = 53: p(17) = 59: p(18) = 61: p(19) = 67: p(20) = 71
    p(21) = 73: p(22) = 79: p(23) = 83: p(24) = 89: p(25) = 97
'
    Cells(1, 1).Value = "a...p"

    For i = 2 To 96: Cells(i, 1) = i: Next i
    For i = 3 To 25: v = prm_root(p(i), i - 1): Next i

End Sub

Function prm_root(p, k)
    Dim t(100)

    r = p - 1: q = r / 2
    Cells(1, k).Value = p

    For a = 2 To r
        For j = 1 To r: t(j) = 0: Next j
        b = a: t(b) = 1
        For j = 2 To r
            b = b * a - p * Int(b * a / p): t(b) = 1
        Next j
        f = 0
        For j = 2 To r
          If t(j) = 0 Then f = 1
        Next j
        If f = 0 Then Cells(a, k).Value = "r"
    Next a

    prm_root = a
End Function

先頭の prime table で定数を設定している部分は、他の言語の時にも応用がきく。


実行結果は次のとおり(表のサイズが大きいので注意のこと)。

原始根に関しては、

2を原始根として持つ素数は、無数に存在する

という有名な未解決問題 (Artin 予想) がある。


前頁 目次 次頁

E-mail : kc2h-msm@asahi-net.or.jp
三島 久典