这是乘法顺序的定义https://en.wikipedia.org/wiki/multiplicative_order
这是程序
(defun power (x y)
(if (= y 0) 1
(if (evenp y) (* (power x (/ y 2)) (power x (/ y 2)))
(* x (power x (/ (- y 1) 2)) (power x (/ (- y 1) 2))))))
(defun ord (n r)
(if (> (gcd n r) 1) 0
(let ((a 0))(loop (defvar a (+ a 1))
(when (= (mod (- (power r a) 1) n) 0)(return a))))))
这是一个可能的解决方案,而无需使用power
函数(请注意,该函数已经在Common LISP,expt
中定义了。
(defun ord (n r)
(if (> (gcd r n) 1)
0
(loop for k from 1
for v = r then (* v r)
when (= 1 (mod v n))
do (return k))))
要计算 a modulo n 的乘法顺序,应使用(ord a n)
调用该函数。例如:
(ord 7 10) ; => 6
因为10 6 = 1(mod 7(
首先检查函数以查看两个参数是否为coprimes,否则返回0。然后,扩展的 loop
form用于在两个变量k
(结果(上执行一个循环,从1开始,从1增加到1个变量每次迭代和v
,即r
的当前功率,从r
开始,并在每次迭代时增加了前面的值,将前一个值乘以r
(因此,在每次迭代中,不变的不变性为 v = r k (。当我们达到 k
的值时, v mod n = 1时,我们终止了返回k
的迭代。
有关loop
的详细描述,请参见真正有用的书籍实用的常见LISP的形式定义或实际解释(第7和22章中(("必须阅读"以学习常见的LISP(。