I am learning Go 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:
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
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.
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"?
When only the dividend is negative. If only the dividend is negative, then: Truncated modulo returns the negative remainder; and. Floored modulo returns the positive remainder.
Adding a thumb rule to all the answers above: negative number modulo k = k minus positive number modulo k. To find (−n)%k just find k−(n%k). Ex: (−144)%5=5−(144%5)=5−(4)=1.
The Mod function is used to find the modulus or remainder from the floating-point division of the two arguments ( x / y ). To use this function, you must import the math package in your file and access the Mod function within it using the . notation ( math. Mod ).
Like in math, integers in computer programming are whole numbers that can be positive, negative, or 0 (…, -1, 0, 1, …). In Go, an integer is known as an int . As with other programming languages, you should not use commas in numbers of four digits or more, so when you write 1,000 in your program, write it as 1000 .
Modulo of Negative Numbers. The modulo operator returns the remainder of a division. But things get a little more tricky when you throw negative numbers into the mix. The modulo or often referred to as “mod” represents the remainder of a division. In 1801 Gauss published a book covering modular arithmetics.
The emphasis is, sign of left operand is appended to result in case of modulus operator in C. Anyone can predict the output of a modulus operator when the both operands are positive. But when it comes to the negative numbers, different languages give different outputs. a % n = a – ( n * trunc ( a/n ) ). = 8 – ( -3 * trunc (-2.666..) )
Integers are whole numbers that can be positive, negative, or 0 (…, -1, 0, 1, …). Floats are real numbers that contain a decimal point, like 9.0 or -2.25 .. This tutorial will review operators that we can use with number data types in Go.
The modulo operator returns the remainder of a division. But things get a little more tricky when you throw negative numbers into the mix. The modulo or often referred to as “mod” represents the remainder of a division. In 1801 Gauss published a book covering modular arithmetics.
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.
Is there an internal method for computing the "modulus" instead of the "remainder"?
Note that % computes the "remainder" as opposed to the "modulus".
These quotes are a bit misleading.
Look up any definition of "modulo", by and large it will say that it is the remainder after division. The problem is that when we say "the remainder", it implies that there is only one. When negative numbers are involved, there can be more than one distinct remainder. On the Wikipedia page for Remainder, it differentiates between the least positive remainder
and the least absolute remainder
. You could also add a least negative remainder
(least negative meaning negative, but closest to 0).
Generally for modulus operators, if it returned a positive value, it was the least positive remainder
and if it returned a negative value, it was the least negative remainder
. The sign of the returned value can be determined in multiple ways. For example given c = a mod b
, you could define the sign of c
to be
%
does in Go)%
does in Python)Here's a list of programming languages and their modulo implementations defined in this way https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages
Here's a branchless way to replicate Python's %
operator with a Go function
func mod(a, b int) int {
return (a % b + b) % b
}
To reiterate, this follows the rule:
given
c = a mod b
, the sign ofc
will be the sign of b. Or in other words, the modulus result has the same sign as the divisor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With