我目前正在学习GoLang,而且我来自Python背景。
最近,我偶然发现了%
(modulo)运算符的行为,它与Python中的相应运算符不同。与modular operation和余数的定义完全相反,正整数的负整数模数返回负值。
示例:
a, b, n = -5, 5, 3
for i in range(a, b):
print(i%n)
输出:
1
2
0
1
2
0
1
2
0
1
a, b, n := -5, 5, 3
for i:=a; i<b; i++ {
fmt.Println(i%n)
}
输出:
-2
-1
0
-2
-1
0
1
2
0
1
在阅读Modulo operator并且很少有类似questions询问这些差异背后的原因之后,我了解这些是由于相关语言的设计目标。
Q1。我想知道为什么Go遵循C / C ++协议而不是Python。任何相关讨论的链接都会有所帮助。
Q2。 Go中是否有内置功能可以复制Python的模数运算? 备选:是否有内部方法来计算“模数”而不是“余数”?
答案 0 :(得分:6)
请参阅https://gist.github.com/jianingy/5472640:
目前的定义有几个原因:
- %的当前语义可直接从x86架构获得
- 更改基本运算符%的含义并且不更改其名称
会令人困惑- 从%result
计算另一个模数相当容易请注意,%计算“余数”而不是“模数”。
标准库中没有运算符或函数复制Python的模数运算。
可以编写一个复制Python模数运算的函数:
func modLikePython(d, m int) int {
var res int = d % m
if ((res < 0 && m > 0) || (res > 0 && m < 0)) {
return res + m
}
return res
}
请注意,Python 5 % -3
中的-1
是||
,此代码也会复制该行为。如果您不想这样,请在if
语句中的int
后删除第二部分。
答案 1 :(得分:1)
Python是一种特殊语言,Guido Guido van Rossum为BDFL。以下是他为什么决定与众不同的解释:
答案 2 :(得分:0)
您的第二季度
是否存在用于计算“模数”而不是“余数”的内部方法?
以及最前面的答案所引用的评论...
请注意,%计算的是“余数”,而不是“模数”。
有点误导...
查找“模”的任何定义,大体上说这是除法后的余数。问题在于,当我们说“余数”时,意味着只有一个。当涉及负数时,可以有1个以上的不同余数。在Remainder的维基百科页面上,它区分了least positive remainder
和least absolute remainder
。您还可以添加least negative remainder
(最小负表示负,但最接近0)。
通常对于模运算符,如果返回正值,则为least positive remainder
;如果返回负值,则为least negative remainder
。可以多种方式确定返回值的符号。例如,给定c = a mod b
,您可以将c
的符号定义为
%
的符号)%
在Python中的作用)以下是以此https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages方式定义的编程语言及其模实现的列表。
无论如何,这是一种使用Go函数复制Python的%
运算符的无分支方式
func mod(a, b int) int {
return (a % b + b) % b
}
重申一下,这符合规则
给定
c = a mod b
,c
的符号将为b的符号。 换句话说,模数结果与除数的符号相同
答案 3 :(得分:0)
math/big
做欧几里得模数:
package main
import "math/big"
func mod(x, y int64) int64 {
bx, by := big.NewInt(x), big.NewInt(y)
return new(big.Int).Mod(bx, by).Int64()
}
func main() {
z := mod(-5, 3)
println(z == 1)
}