不可逆元的個數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)
}