不同编程语言中的整数求余【Modulo (Mathematical Definition)/Remainder (Truncated Division)】
TL;DR
There are 2 definitions:
- Modulo (Mathematical Definition). In this class, the result of
a % balways has the same sign as the divisor (b). - Remainder (Truncated Division). In this class, the result of
a % balways has the same sign as the dividend (a).
Programming languages can be classified into different categories based on how they handle modulo/remainder operations, particularly when negative numbers are involved. The behavior of the modulo operator in various languages mainly falls into two classes:
1. Modulo (Mathematical Definition)
In this class, the result of a % b always has the same sign as the divisor (b). This behavior corresponds to the true mathematical definition of modulo.
Examples:
5 % 3 = 2-5 % 3 = 1(result has the same sign as3)5 % -3 = -1(result has the same sign as-3)-5 % -3 = -2(result has the same sign as-3)
Languages in this Class:
- Python
- Ruby
- R
- Haskell
- Erlang
- Ada
2. Remainder (Truncated Division)
In this class, the result of a % b always has the same sign as the dividend (a). This behavior corresponds to the remainder after truncated division (division rounded toward zero).
Examples:
5 % 3 = 2-5 % 3 = -2(result has the same sign as-5)5 % -3 = 2(result has the same sign as5)-5 % -3 = -2(result has the same sign as-5)
Languages in this Class:
- JavaScript
- C
- C++
- Java
- Go
- Swift
- Kotlin
- Scala (%)
3. Other/Hybrid Behaviors
Some languages use non-standard or configurable behavior for modulo, allowing you to choose between different definitions.
Examples:
-
SQL (e.g., PostgreSQL):
- PostgreSQL uses the remainder definition (
a % btakes the sign ofa). - However, it also offers a
MOD(a, b)function, which behaves like the mathematical modulo (result takes the sign ofb).
- PostgreSQL uses the remainder definition (
-
Fortran:
- Fortran has two operators:
MOD(a, b)(result takes the sign ofb) andMODULO(a, b)(result takes the sign ofa).
- Fortran has two operators:
-
Scala:
- Scala's
%operator behaves like remainder (same sign asa). - However, the
math.floorMod(a, b)method behaves like mathematical modulo (same sign asb).
- Scala's
-
Perl:
- Perl's
%operator behaves like remainder (same sign asa), but you can implement mathematical modulo manually if needed.
- Perl's
Comparison Table
| Language | % Behavior (Modulo or Remainder) |
Notes |
|---|---|---|
| Python | Modulo | Result sign matches divisor (b). |
| Ruby | Modulo | Result sign matches divisor (b). |
| Haskell | Modulo | Result sign matches divisor (b). |
| R | Modulo | Result sign matches divisor (b). |
| C | Remainder | Result sign matches dividend (a). |
| C++ | Remainder | Result sign matches dividend (a). |
| Java | Remainder | Result sign matches dividend (a). |
| JavaScript | Remainder | Result sign matches dividend (a). |
| Go | Remainder | Result sign matches dividend (a). |
| Swift | Remainder | Result sign matches dividend (a). |
| Scala | Remainder | Use math.floorMod for true modulo. |
| SQL | Configurable | % is remainder; MOD() is modulo. |
| Fortran | Configurable | MOD(a, b) (modulo), MODULO(a, b). |
How Do We Use This Classification?
-
When Porting Code Between Languages:
- Be aware of the differences in
%behavior when translating code between languages like Python and JavaScript (or others in different classes). They can lead to subtle bugs, particularly with negative numbers.
- Be aware of the differences in
-
When Writing Cross-Language Algorithms:
-
If you're working with mixed-language environments or need consistent behavior across multiple languages, you can manually implement a specific modulo definition (e.g., using formulas) to unify the behavior.
-
Mathematical Modulo Formula (in languages that use remainder):
result = ((a % b) + b) % b -
Remainder Formula (in languages that use modulo):
result = a % b if a * b > 0 else a % b - b
-
-
Choosing a Language for Specific Applications:
-
For applications involving modular arithmetic (e.g., cryptography, cyclic computations), languages with mathematical modulo (Python, Ruby) may be more intuitive.
-
For low-level programming or compatibility with hardware (e.g., embedded systems), languages with remainder behavior (C, C++) might be preferred.
-
My question
Adapter of different modulo? More Examples are appreciated.
// javascript
function pythonMod(a, b) {
return ((a % b) + b) % b;
}
// scala
/*
Python's % operator returns a result with the same sign as the divisor, and // rounds towards negative infinity.
In Scala, % and / don't behave the same way. The % operator returns a result with the same sign as the dividend, and / performs truncating division, rounding towards zero.
*/
def pythonMod(a: Int, b: Int): Int = ((a % b) + b) % b
def pythonDiv(a: Int, b: Int): Int = {
if ((a > 0 && b > 0) || (a < 0 && b < 0)) a / b
else if (a % b == 0) a / b
else a / b - 1
}
def scala_div(x, y):
if y == 0:
raise ZeroDivisionError('division by zero')
elif (x < 0 and y < 0) or (x > 0 and y > 0):
return abs(x) // abs(y)
else:
return -(abs(x) // abs(y))
def scala_mod(x, y):
if y == 0:
raise ZeroDivisionError('modulo by zero')
elif x < 0:
return -(abs(x) % abs(y))
else:
return x % abs(y)

浙公网安备 33010602011771号