问题描述
在 sagemath 命令行中,当我进行这样的操作时
sage: m = pow(2,5,2)
sage: m
0
sage: m = pow(2,3)
....: n = pow (3,4)
....: m
2
sage: n
3
sage: m * n
unsupported operand parent(s) for *: 'Ring of integers modulo 3' and 'Ring of integers modulo 4'
由此看来,每当您调用模数 pow
时,输出就会与模数相关联,而不是本身就是一个数值
这不会发生在本机 python 程序中。
cat a.py
m = pow (2,3)
n = pow (3,4)
print (m*n)
python a.py
6
此外,如果我将数字相乘,即使我没有要求这样做,乘法也会以模数进行
sage: m = pow(2,5)
....: n = pow (3,5)
....: m
2
sage: n
3
sage: m * n
1
所以我的问题是
-
如何从此处的
m
和n
中提取数值,以便在非模块化操作中使用它们? -
这是
pow
特有的吗?如果没有,还有哪些其他函数表现出这种行为? -
这背后有什么理由吗?我的意思是,python 本身不会这样做
-
可以关闭吗?
解决方法
为了避免模幂运算给出“整数模某物”,
使用power_mod
:
sage: a = power_mod(2,5,3)
sage: b = power_mod(3,4)
sage: a,a.parent(),b,b.parent()
(2,Integer Ring,3,Integer Ring)
sage: p = a * b
sage: p,p.parent()
(6,Integer Ring)
要将“整数模数”拯救为“通常的整数”,
使用 int
或 Integer
或 ZZ
:
sage: m = pow(2,3)
sage: n = pow(3,4)
sage: m,m.parent(),n,n.parent()
(2,Ring of integers modulo 3,Ring of integers modulo 4)
sage: p = int(m) * int(n)
sage: p,type(p)
(6,<class 'int'>)
sage: p = Integer(m) * Integer(n)
sage: p,Integer Ring)
sage: p = ZZ(m) * ZZ(n)
sage: p,Integer Ring)
要检查 Sage 预解析器在这种情况下的作用:
sage: preparse('m = pow(2,3)')
'm = pow(Integer(2),Integer(5),Integer(3))'
所以 Sage 不是在调整 pow
而是只是转动
输入到 Sage 整数中的任何整数。
然后会发生pow(a,c)
变成 a.__pow__(b,c)
和 Sage 整数
有自己的 __pow__
方法可以吐出
整数模某物。
要关闭 Sage 预解析器:
sage: preparser(False)
sage: m = pow(2,type(m),type(n)
(2,<class 'int'>,<class 'int'>)
sage: p = m * n
sage: p,<class 'int'>)
为了避免使用 pow
和预解析器时的行为,
将整数标记为原始或使用 int
:
sage: preparser(True)
sage: m = pow(2r,5r,3r)
sage: n = pow(3r,4r)
sage: m,<class 'int'>)
sage: m = pow(int(2),int(5),int(3))
sage: n = pow(int(3),int(4))
sage: m,<class 'int'>)
禁用所有 Python 整数到 Sage 整数的转换 同时保持 Sage 预解析器开启:
sage: Integer = int
sage: m = pow(2,<class 'int'>)
恢复 Python 整数到 Sage 整数的转换:
sage: Integer = sage.rings.integer.Integer