用初等數論函數計算剩餘類環Z/nZ的環不變量

不可逆元的個數n1(涉及到模逆函數InvMod)
冪等元個數n2
2次冪等元個數n4
2~3次冪等元個數n5
零乘個數n6
零因子個數n7
中心大小n8

gap> PowerMod(4,-1,3);
1
gap> PowerMod(3,-1,4);
3
D:\go20190906\src\SmallRing>go build InvMod.go
[0x7FEF96C3C50] ANOMALY: meaningless REX prefix used
# command-line-arguments
[0x7FEF96C3C50] ANOMALY: meaningless REX prefix used

D:\go20190906\src\SmallRing>InvMod 4 3
[0x7FEF96C3C50] ANOMALY: meaningless REX prefix used
PowerMod(4,-1,3)=1

D:\go20190906\src\SmallRing>InvMod 3 4
[0x7FEF96C3C50] ANOMALY: meaningless REX prefix used
PowerMod(3,-1,4)=3

D:\go20190906\src\SmallRing>InvMod 2 4
[0x7FEF96C3C50] ANOMALY: meaningless REX prefix used
PowerMod(2,-1,4)=0

D:\go20190906\src\SmallRing>InvMod 4 2
[0x7FEF96C3C50] ANOMALY: meaningless REX prefix used
PowerMod(4,-1,2)=0

/*
擴展歐幾里得算法,可以構造出u u1 + v u2 = u3 = gcd( u, v ).
現令v = p是素數,可知gcd = u3 = 1,我們得到 u u1 -1  = p u2
u u1=1 (mod p)
u1=InvMod(u,p)
v不是素數時,u u1 = 0 (mod v)時會導致u u1 = 1 (mod v)無解,即模逆不存在(InvMod(u,v)=0)

定理:Z/(p)爲域當且僅當p爲素數。
證 設p不是素數,那麼Z/(p)有零因子(p的因子),故Z/(p)不是域.
反之,當p爲素數時,可證Z/(p)中所有非零元素都有乘法運算的逆元,從而含麼交換環Z/(p)爲域.
設q是Z/(p)中任一非零元素,那麼q與p互素.據數論事實,有整數m,n使mp + nq = 1
從而(mp+nq)(mod p) = 1
即mp(mod p)+nq(mod p) = 1
0 + n(mod p)*q(mod p)= 1, 或 n(mod p)*q=1
因此,q有逆元n(mod p) .
定理得證。
*/
package main

import (
    "fmt"
    "os"
    "strconv"    
)

func mod(n, p int)int{
/*
    raw_mod := n % p
    if (raw_mod == 0){
            return 0
        }else if (n >= 0){
            return raw_mod
        }else{
            return raw_mod + p
        }
*/
    if(n<0){
       ret1:=n+(-n+1)*p
        return ret1%p
    }
    return n%p    

func inverse_mod_p(u, p int)int{
    var t1 int= 0
    var t3 int= 0
    var q  int= 0
    var u1 int= 1
    var u3 int= u
    var v1 int= 0
    var v3 int= p
    var inv_v int= 0

    for{
        q = (int)(u3 / v3)
        t1 = u1 - v1 * q
        t3 = u3 - v3 * q
        u1 = v1
        u3 = v3
        v1 = t1
        v3 = t3
        if( v3 == 0){
            break
        }
    }
    inv_v = mod( u1, p )
    if ( mod( u * inv_v, p ) != 1){
        return 0// 返回值爲0表示模逆不存在
    }
    return inv_v
}

func main(){
     var a,n,b int
     if(len(os.Args)<3){
         fmt.Printf("usage: InvMod a n:\n")
         fmt.Printf("Please input the number a,n:\n")
         fmt.Scanf("%d,%d",&a,&n)
     }else{
         a,_=strconv.Atoi(os.Args[1])
         n,_=strconv.Atoi(os.Args[2])     
     }
     b=inverse_mod_p(a,n)
     fmt.Printf("PowerMod(%d,-1,%d)=%d\n",a,n,b)
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章