Go中负整数的模数

Ksh*_*ogi 4 python go modulo

我目前正在学习GoLang,而且我来自Python背景.

最近,我偶然发现了%(modulo)运算符的行为,它与Python中的相应运算符不同.与模运算和余数的定义完全相反,正整数的负整数模数返回负值.

例:

蟒蛇

a, b, n = -5, 5, 3
for i in range(a, b):
    print(i%n)    
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
0
1
2
0
1
2
0
1
Run Code Online (Sandbox Code Playgroud)

a, b, n := -5, 5, 3
for i:=a; i<b; i++ {
    fmt.Println(i%n)
}
Run Code Online (Sandbox Code Playgroud)

输出:

-2
-1
0
-2
-1
0
1
2
0
1
Run Code Online (Sandbox Code Playgroud)

阅读后模运算符和几个类似的问题问及背后这些差异的原因,据我所知,这是由于设计有关语言的目标.

Q1.我想知道为什么Go遵循C/C++协议而不是Python.任何相关讨论的链接都会有所帮助.

Q2.Go中是否有内置功能可以复制Python的模数运算?
替代:是否有内部方法来计算"模数"而不是"余数"?

Hym*_*sco 8

你的 Q2

是否有计算“模数”而不是“余数”的内部方法?

以及最高答案引用的评论......

请注意, % 计算的是“余数”而不是“模数”。

有点误导...

查找“模”的任何定义,总的来说,它会说它是除法后的余数。问题是,当我们说“余数”时,它意味着只有一个。当涉及负数时,可以有超过 1 个不同的余数。在Remainder的维基百科页面上,它区分了least positive remainderleast absolute remainder。您还可以添加一个least negative remainder(最不负面的意思是负面但最接近 0)。

通常对于模数运算符,如果返回正值,则为 the least positive remainder,如果返回负值,则为least negative remainder。返回值的符号可以通过多种方式确定。例如c = a mod b,您可以将 的符号定义c

  • a 的符号(%在 Go 中做什么)
  • b 的符号(%在 Python 中有什么作用)
  • 总是非负

这是以这种方式定义的编程语言及其模实现的列表https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages

无论如何,这是一种%使用 Go 函数复制 Python运算符的无分支方式

func mod(a, b int) int {
    return (a % b + b) % b
}
Run Code Online (Sandbox Code Playgroud)

重申一下,这遵循规则

给定c = a mod bcwill 的符号就是 b 的符号。或者换句话说,模数结果与除数具有相同的符号


Cer*_*món 7

由其中一位语言设计师查看此评论:

目前的定义有几个原因:

  • 由x86架构直接提供%的当前语义
  • 更改基本运算符%的含义并且不更改其名称会令人困惑
  • 从%结果计算另一个模数相当容易

请注意,%计算"余数"而不是"模数".

标准库中没有运算符或函数来复制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
}
Run Code Online (Sandbox Code Playgroud)

请注意,在Python 5 % -3-1,此代码也复制了该行为.如果您不想这样,请||if语句后删除第二部分.

  • 您可以将 Go to Python Modulus 代码简化为:“(i % n) + n) % n”。已验证[此处](https://play.golang.org/p/QT5PA9fltU) (5认同)