Go中负整数的模

I am learning GoLang currently and I come from a Python background.

Recently, I stumbled onto a behaviour of the %(modulo) operator which is different from the corresponding operator in Python. Quite contrary to the definition of modular operation and remainder, the modulus of negative integers by a positive integer returns a negative value.

Example:

Python

a, b, n = -5, 5, 3
for i in range(a, b):
    print(i%n)    

Output:

1
2
0
1
2
0
1
2
0
1

Go

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

Output:

-2
-1
0
-2
-1
0
1
2
0
1

After reading about the Modulo operator and few similar questions asked about the reason behind these differences, I understand that these were due to design goals of the concerned languages.

Q1. I would like to know why Go follows the protocol of C/C++ instead of Python here. Any links to relevant discussion will be helpful.

Q2. Is there a built-in functionality in Go which replicates the modulus operation of Python?
Alternate: Is there an internal method for computing the "modulus" instead of the "remainder"?

See this comment by one of the language designers:

There are a several reasons for the current definition:

  • the current semantics for % is directly available as a result from x86 architectures
  • it would be confusing to change the meaning of the elementary operator % and not change its name
  • it's fairly easy to compute another modulus from the % result

Note that % computes the "remainder" as opposed to the "modulus".

There is not an operator or function in the standard library which replicates the modulus operation of Python.

It is possible to write a function which replicates the modulus operation of 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
}

Note that in Python 5 % -3 is -1 and this code replicates that behavior as well. If you don't want that, remove the second part after || in the if statement.

Python is an idiosyncratic language with Guido Guido van Rossum as BDFL. Here's his explanation of why he decided to be different:

The History of Python: Why Python's Integer Division Floors