Recent from talks
Contribute something
Nothing was collected or created yet.
Modulo
View on WikipediaIn computing and mathematics, the modulo operation returns the remainder or signed remainder of a division, after one number is divided by another, the latter being called the modulus of the operation.
Given two positive numbers a and n, a modulo n (often abbreviated as a mod n) is the remainder of the Euclidean division of a by n, where a is the dividend and n is the divisor.[1]
For example, the expression "5 mod 2" evaluates to 1, because 5 divided by 2 has a quotient of 2 and a remainder of 1, while "9 mod 3" would evaluate to 0, because 9 divided by 3 has a quotient of 3 and a remainder of 0.
Although typically performed with a and n both being integers, many computing systems now allow other types of numeric operands. The range of values for an integer modulo operation of n is 0 to n − 1. a mod 1 is always 0.
When exactly one of a or n is negative, the basic definition breaks down, and programming languages differ in how these values are defined.
Variants of the definition
[edit]In mathematics, the result of the modulo operation is an equivalence class, and any member of the class may be chosen as representative; however, the usual representative is the least positive residue, the smallest non-negative integer that belongs to that class (i.e., the remainder of the Euclidean division).[2] However, other conventions are possible. Computers and calculators have various ways of storing and representing numbers; thus their definition of the modulo operation depends on the programming language or the underlying hardware.
In nearly all computing systems, the quotient q and the remainder r of a divided by satisfy the following conditions:
| 1 |
This still leaves a sign ambiguity if the remainder is non-zero: two possible choices for the remainder occur, one negative and the other positive; that choice determines which of the two consecutive quotients must be used to satisfy equation (1). In number theory, the positive remainder is always chosen, but in computing, programming languages choose depending on the language and the signs of a or n.[a] Standard Pascal and ALGOL 68, for example, give a positive remainder (or 0) even for negative divisors, and some programming languages, such as C90, leave it to the implementation when either of n or a is negative (see the table under § In programming languages for details). Some systems leave a modulo 0 undefined, though others define it as a.

Quotient (q) and remainder (r) as functions of dividend (a), using truncated division Many implementations use truncated division, for which the quotient is defined by
where is the integral part function (rounding toward zero), i.e. the truncation to zero significant digits. Thus according to equation (1), the remainder has the same sign as the dividend a so can take 2|n| − 1 values:

Quotient and remainder using floored division Donald Knuth[3] promotes floored division, for which the quotient is defined by
where is the floor function (rounding down). Thus according to equation (1), the remainder has the same sign as the divisor n:

Quotient and remainder using Euclidean division Raymond T. Boute[4] promotes Euclidean division, for which the non-negative remainder is defined by
- . (Emphasis added.)
Under this definition, we can say the following about the quotient :
where sgn is the sign function, is the floor function (rounding down), and are rational numbers.
Equivalently, one may instead define the quotient as follows:
where is the ceiling function (rounding up). Thus according to equation (1), the remainder is non-negative:

Quotient and remainder using rounded division Common Lisp and IEEE 754 use rounded division, for which the quotient is defined by
where round is the round function (rounding half to even). Thus according to equation (1), the remainder falls between and , and its sign depends on which side of zero it falls to be within these boundaries:

Quotient and remainder using ceiling division Common Lisp also uses ceiling division, for which the quotient is defined by
where ⌈⌉ is the ceiling function (rounding up). Thus according to equation (1), the remainder has the opposite sign of that of the divisor:
If both the dividend and divisor are positive, then the truncated, floored, and Euclidean definitions agree. If the dividend is positive and the divisor is negative, then the truncated and Euclidean definitions agree. If the dividend is negative and the divisor is positive, then the floored and Euclidean definitions agree. If both the dividend and divisor are negative, then the truncated and floored definitions agree.
Notation
[edit]Some calculators have a mod() function button, and many programming languages have a similar function, expressed as mod(a, n), for example. Some also support expressions that use "%", "mod", or "Mod" as a modulo or remainder operator, such as a % n or a mod n.
For environments lacking a similar function, any of the three definitions above can be used.
Common pitfalls
[edit]When the result of a modulo operation has the sign of the dividend (truncated definition), it can lead to surprising mistakes.
For example, to test if an integer is odd, one might be inclined to test if the remainder by 2 is equal to 1:
bool is_odd(int n) {
return n % 2 == 1;
}
But in a language where modulo has the sign of the dividend, that is incorrect, because when n (the dividend) is negative and odd, n mod 2 returns −1, and the function returns false.
One correct alternative is to test that the remainder is not 0 (because remainder 0 is the same regardless of the signs):
bool is_odd(int n) {
return n % 2 != 0;
}
Or with the binary arithmetic:
bool is_odd(int n) {
return n & 1;
}
Performance issues
[edit]Modulo operations might be implemented such that a division with a remainder is calculated each time. For special cases, on some hardware, faster alternatives exist. For example, the modulo of powers of 2 can alternatively be expressed as a bitwise AND operation (assuming x is a positive integer, or using a non-truncating definition):
x % 2n == x & (2n - 1)
Examples:
x % 2 == x & 1x % 4 == x & 3x % 8 == x & 7
In devices and software that implement bitwise operations more efficiently than modulo, these alternative forms can result in faster calculations.[7]
Compiler optimizations may recognize expressions of the form expression % constant where constant is a power of two and automatically implement them as expression & (constant-1), allowing the programmer to write clearer code without compromising performance. This simple optimization is not possible for languages in which the result of the modulo operation has the sign of the dividend (including C), unless the dividend is of an unsigned integer type. This is because, if the dividend is negative, the modulo will be negative, whereas expression & (constant-1) will always be positive. For these languages, the equivalence x % 2n == x < 0 ? x | ~(2n - 1) : x & (2n - 1) has to be used instead, expressed using bitwise OR, NOT and AND operations.
Optimizations for general constant-modulus operations also exist by calculating the division first using the constant-divisor optimization.
Properties (identities)
[edit]Some modulo operations can be factored or expanded similarly to other mathematical operations. This may be useful in cryptography proofs, such as the Diffie–Hellman key exchange. The properties involving multiplication, division, and exponentiation generally require that a and n are integers.
- Identity:
- (a mod n) mod n = a mod n.
- nx mod n = 0 for all positive integer values of x.
- If p is a prime number which is not a divisor of b, then abp−1 mod p = a mod p, due to Fermat's little theorem.
- Inverse:
- [(−a mod n) + (a mod n)] mod n = 0.
- b−1 mod n denotes the modular multiplicative inverse, which is defined if and only if b and n are relatively prime, which is the case when the left hand side is defined: [(b−1 mod n)(b mod n)] mod n = 1.
- Distributive:
- (a + b) mod n = [(a mod n) + (b mod n)] mod n.
- ab mod n = [(a mod n)(b mod n)] mod n.
- Division (definition): a/b mod n = [(a mod n)(b−1 mod n)] mod n, when the right hand side is defined (that is when b and n are coprime), and undefined otherwise.
- Inverse multiplication: [(ab mod n)(b−1 mod n)] mod n = a mod n.
In programming languages
[edit]| Language | Operator | Integer | Floating-point | Definition |
|---|---|---|---|---|
| ABAP | MOD
|
Yes | Yes | Euclidean |
| ActionScript | %
|
Yes | No | Truncated |
| Ada | mod
|
Yes | No | Floored[8] |
rem
|
Yes | No | Truncated[8] | |
| ALGOL 68 | ÷×, mod
|
Yes | No | Euclidean |
| AMPL | mod
|
Yes | No | Truncated |
| APL | |[b]
|
Yes | Yes | Floored |
| AppleScript | mod
|
Yes | No | Truncated |
| AutoLISP | (rem d n)
|
Yes | No | Truncated |
| AWK | %
|
Yes | No | Truncated |
| bash | %
|
Yes | No | Truncated |
| BASIC | Mod
|
Yes | No | Varies by implementation |
| bc | %
|
Yes | No | Truncated |
| C C++ |
%, div
|
Yes | No | Truncated[c] |
fmod (C)std::fmod (C++)
|
No | Yes | Truncated[11] | |
remainder (C)std::remainder (C++)
|
No | Yes | Rounded | |
| C# | %
|
Yes | Yes | Truncated |
Math.IEEERemainder
|
No | Yes | Rounded[12] | |
| Clarion | %
|
Yes | No | Truncated |
| Clean | rem
|
Yes | No | Truncated |
| Clojure | mod
|
Yes | No | Floored[13] |
rem
|
Yes | No | Truncated[14] | |
| COBOL | FUNCTION MOD
|
Yes | No | Floored[15] |
FUNCTION REM
|
Yes | Yes | Truncated[15] | |
| CoffeeScript | %
|
Yes | No | Truncated |
%%
|
Yes | No | Floored[16] | |
| ColdFusion | %, MOD
|
Yes | No | Truncated |
| Common Intermediate Language | rem (signed)
|
Yes | Yes | Truncated[17] |
rem.un (unsigned)
|
Yes | No | — | |
| Common Lisp | mod
|
Yes | Yes | Floored |
rem
|
Yes | Yes | Truncated | |
| Crystal | %, modulo
|
Yes | Yes | Floored |
remainder
|
Yes | Yes | Truncated | |
| CSS | mod()
|
Yes | Yes | Floored[18] |
rem()
|
Yes | Yes | Truncated[19] | |
| D | %
|
Yes | Yes | Truncated[20] |
| Dart | %
|
Yes | Yes | Euclidean[21] |
remainder()
|
Yes | Yes | Truncated[22] | |
| Eiffel | \\
|
Yes | No | Truncated |
| Elixir | rem/2
|
Yes | No | Truncated[23] |
Integer.mod/2
|
Yes | No | Floored[24] | |
| Elm | modBy
|
Yes | No | Floored[25] |
remainderBy
|
Yes | No | Truncated[26] | |
| Erlang | rem
|
Yes | No | Truncated |
math:fmod/2
|
No | Yes | Truncated (same as C)[27] | |
| Euphoria | mod
|
Yes | No | Floored |
remainder
|
Yes | No | Truncated | |
| F# | %
|
Yes | Yes | Truncated |
Math.IEEERemainder
|
No | Yes | Rounded[12] | |
| Factor | mod
|
Yes | No | Truncated |
| FileMaker | Mod
|
Yes | No | Floored |
| Forth | mod
|
Yes | No | Implementation defined |
fm/mod
|
Yes | No | Floored | |
sm/rem
|
Yes | No | Truncated | |
| Fortran | mod
|
Yes | Yes | Truncated |
modulo
|
Yes | Yes | Floored | |
| Frink | mod
|
Yes | No | Floored |
| Full BASIC | MOD
|
Yes | Yes | Floored[28] |
REMAINDER
|
Yes | Yes | Truncated[29] | |
| GLSL | %
|
Yes | No | Undefined[30] |
mod
|
No | Yes | Floored[31] | |
| GameMaker Studio (GML) | mod, %
|
Yes | No | Truncated |
| GDScript (Godot) | %
|
Yes | No | Truncated |
fmod
|
No | Yes | Truncated | |
posmod
|
Yes | No | Euclidean | |
fposmod
|
No | Yes | Euclidean | |
| Go | %
|
Yes | No | Truncated[32] |
math.Mod
|
No | Yes | Truncated[33] | |
big.Int.Mod
|
Yes | No | Euclidean[34] | |
big.Int.Rem
|
Yes | No | Truncated[35] | |
| Groovy | %
|
Yes | No | Truncated |
| Haskell | mod
|
Yes | No | Floored[36] |
rem
|
Yes | No | Truncated[36] | |
Data.Fixed.mod' (GHC)
|
No | Yes | Floored | |
| Haxe | %
|
Yes | No | Truncated |
| HLSL | %
|
Yes | Yes | Undefined[37] |
| J | |[b]
|
Yes | No | Floored |
| Java | %
|
Yes | Yes | Truncated |
Math.floorMod
|
Yes | No | Floored | |
| JavaScript TypeScript |
%
|
Yes | Yes | Truncated |
| Julia | mod
|
Yes | Yes | Floored[38] |
%, rem
|
Yes | Yes | Truncated[39] | |
| Kotlin | %, rem
|
Yes | Yes | Truncated[40] |
mod
|
Yes | Yes | Floored[41] | |
| ksh | %
|
Yes | No | Truncated (same as POSIX sh) |
fmod
|
No | Yes | Truncated | |
| LabVIEW | mod
|
Yes | Yes | Truncated |
| LibreOffice | =MOD()
|
Yes | No | Floored |
| Logo | MODULO
|
Yes | No | Floored |
REMAINDER
|
Yes | No | Truncated | |
| Lua 5 | %
|
Yes | Yes | Floored |
| Lua 4 | mod(x,y)
|
Yes | Yes | Truncated |
| Liberty BASIC | MOD
|
Yes | No | Truncated |
| Mathcad | mod(x,y)
|
Yes | No | Floored |
| Maple | e mod m (by default), modp(e, m)
|
Yes | No | Euclidean |
mods(e, m)
|
Yes | No | Rounded | |
frem(e, m)
|
Yes | Yes | Rounded | |
| Mathematica | Mod[a, b]
|
Yes | No | Floored |
| MATLAB | mod
|
Yes | Yes | Floored |
rem
|
Yes | Yes | Truncated | |
| Maxima | mod
|
Yes | No | Floored |
remainder
|
Yes | No | Truncated | |
| Maya Embedded Language | %
|
Yes | No | Truncated |
| Microsoft Excel | =MOD()
|
Yes | Yes | Floored |
| Minitab | MOD
|
Yes | No | Floored |
| Modula-2 | MOD
|
Yes | No | Floored |
REM
|
Yes | No | Truncated | |
| MUMPS | #
|
Yes | No | Floored |
| Netwide Assembler (NASM, NASMX) | %, div (unsigned)
|
Yes | No | — |
%% (signed)
|
Yes | No | Implementation-defined[42] | |
| Nim | mod
|
Yes | No | Truncated |
| Oberon | MOD
|
Yes | No | Floored-like[d] |
| Objective-C | %
|
Yes | No | Truncated (same as C99) |
| Object Pascal, Delphi | mod
|
Yes | No | Truncated |
| OCaml | mod
|
Yes | No | Truncated[43] |
mod_float
|
No | Yes | Truncated[44] | |
| Occam | \
|
Yes | No | Truncated |
| Pascal (ISO-7185 and -10206) | mod
|
Yes | No | Euclidean-like[e] |
| Perl | %
|
Yes | No | Floored[f] |
POSIX::fmod
|
No | Yes | Truncated | |
| Phix | mod
|
Yes | No | Floored |
remainder
|
Yes | No | Truncated | |
| PHP | %
|
Yes | No | Truncated[46] |
fmod
|
No | Yes | Truncated[47] | |
| PIC BASIC Pro | \\
|
Yes | No | Truncated |
| PL/I | mod
|
Yes | No | Floored (ANSI PL/I) |
| PowerShell | %
|
Yes | No | Truncated |
| Programming Code (PRC) | MATH.OP - 'MOD; (\)'
|
Yes | No | Undefined |
| Progress | modulo
|
Yes | No | Truncated |
| Prolog (ISO 1995) | mod
|
Yes | No | Floored |
rem
|
Yes | No | Truncated | |
| PureBasic | %, Mod(x,y)
|
Yes | No | Truncated |
| PureScript | `mod`
|
Yes | No | Euclidean[48] |
| Pure Data | %
|
Yes | No | Truncated (same as C) |
mod
|
Yes | No | Floored | |
| Python | %
|
Yes | Yes | Floored |
math.fmod
|
No | Yes | Truncated | |
math.remainder
|
No | Yes | Rounded | |
| Q# | %
|
Yes | No | Truncated[49] |
| R | %%
|
Yes | Yes | Floored[50] |
| Racket | modulo
|
Yes | No | Floored |
remainder
|
Yes | No | Truncated | |
| Raku | %
|
No | Yes | Floored |
| RealBasic | MOD
|
Yes | No | Truncated |
| Reason | mod
|
Yes | No | Truncated |
| Rexx | //
|
Yes | Yes | Truncated |
| RPG | %REM
|
Yes | No | Truncated |
| Ruby | %, modulo()
|
Yes | Yes | Floored |
remainder()
|
Yes | Yes | Truncated | |
| Rust | %
|
Yes | Yes | Truncated |
rem_euclid()
|
Yes | Yes | Euclidean[51] | |
| SAS | MOD
|
Yes | No | Truncated |
| Scala | %
|
Yes | Yes | Truncated |
| Scheme | modulo
|
Yes | No | Floored |
remainder
|
Yes | No | Truncated | |
| Scheme R6RS | mod
|
Yes | No | Euclidean[52] |
mod0
|
Yes | No | Rounded[52] | |
flmod
|
No | Yes | Euclidean | |
flmod0
|
No | Yes | Rounded | |
| Scratch | mod
|
Yes | Yes | Floored |
| Seed7 | mod
|
Yes | Yes | Floored |
rem
|
Yes | Yes | Truncated | |
| SenseTalk | modulo
|
Yes | No | Floored |
rem
|
Yes | No | Truncated | |
sh (POSIX) (includes bash, mksh, &c.)
|
%
|
Yes | No | Truncated (same as C)[53] |
| Smalltalk | \\
|
Yes | No | Floored |
rem:
|
Yes | No | Truncated | |
| Snap! | mod
|
Yes | No | Floored |
| Spin | //
|
Yes | No | Floored |
| Solidity | %
|
Yes | No | Truncated[54] |
| SQL (SQL:1999) | mod(x,y)
|
Yes | No | Truncated |
| SQL (SQL:2011) | %
|
Yes | No | Truncated |
| Standard ML | mod
|
Yes | No | Floored |
Int.rem
|
Yes | No | Truncated | |
Real.rem
|
No | Yes | Truncated | |
| Stata | mod(x,y)
|
Yes | No | Euclidean |
| Swift | %
|
Yes | No | Truncated[55] |
remainder(dividingBy:)
|
No | Yes | Rounded[56] | |
truncatingRemainder(dividingBy:)
|
No | Yes | Truncated[57] | |
| Tcl | %
|
Yes | No | Floored |
fmod()
|
No | Yes | Truncated (as C) | |
| tcsh | %
|
Yes | No | Truncated |
| Torque | %
|
Yes | No | Truncated |
| Turing | mod
|
Yes | No | Floored |
| Verilog (2001) | %
|
Yes | No | Truncated |
| VHDL | mod
|
Yes | No | Floored |
rem
|
Yes | No | Truncated | |
| VimL | %
|
Yes | No | Truncated |
| Visual Basic | Mod
|
Yes | No | Truncated |
| WebAssembly | i32.rem_u, i64.rem_u (unsigned)
|
Yes | No | —[58] |
i32.rem_s, i64.rem_s (signed)
|
Yes | No | Truncated[58] | |
| x86 assembly | IDIV
|
Yes | No | Truncated |
| XBase++ | %
|
Yes | Yes | Truncated |
Mod()
|
Yes | Yes | Floored | |
| Zig | %, @rem
|
Yes | Yes | Truncated[59] |
@mod
|
Yes | Yes | Floored | |
| Z3 theorem prover | div, mod
|
Yes | No | Euclidean |
In addition, many computer systems provide a divmod functionality, which produces the quotient and the remainder at the same time. Examples include the x86 architecture's IDIV instruction, the C programming language's div() function, and Python's divmod() function.
Generalizations
[edit]Modulo with offset
[edit]Sometimes it is useful for the result of a modulo n to lie not between 0 and n − 1, but between some number d and d + n − 1. In that case, d is called an offset and d = 1 is particularly common.
There does not seem to be a standard notation for this operation, so let us tentatively use a modd n. We thus have the following definition:[60] x = a modd n just in case d ≤ x ≤ d + n − 1 and x mod n = a mod n. Clearly, the usual modulo operation corresponds to zero offset: a mod n = a mod0 n.
The operation of modulo with offset is related to the floor function as follows:
To see this, let . We first show that x mod n = a mod n. It is in general true that (a + bn) mod n = a mod n for all integers b; thus, this is true also in the particular case when ; but that means that , which is what we wanted to prove. It remains to be shown that d ≤ x ≤ d + n − 1. Let k and r be the integers such that a − d = kn + r with 0 ≤ r ≤ n − 1 (see Euclidean division). Then , thus . Now take 0 ≤ r ≤ n − 1 and add d to both sides, obtaining d ≤ d + r ≤ d + n − 1. But we've seen that x = d + r, so we are done.
The modulo with offset a modd n is implemented in Mathematica as Mod[a, n, d] .[60]
Implementing other modulo definitions using truncation
[edit]Despite the mathematical elegance of Knuth's floored division and Euclidean division, it is generally much more common to find a truncated division-based modulo in programming languages. Leijen provides the following algorithms for calculating the two divisions given a truncated integer division:
/* Euclidean and Floored divmod, in the style of C's ldiv() */
typedef struct {
/* This structure is part of the C stdlib.h, but is reproduced here for clarity */
long int quot;
long int rem;
} ldiv_t;
/* Euclidean division */
inline ldiv_t ldivE(long numer, long denom) {
/* The C99 and C++11 languages define both of these as truncating. */
long q = numer / denom;
long r = numer % denom;
if (r < 0) {
if (denom > 0) {
q = q - 1;
r = r + denom;
} else {
q = q + 1;
r = r - denom;
}
}
return (ldiv_t){.quot = q, .rem = r};
}
/* Floored division */
inline ldiv_t ldivF(long numer, long denom) {
long q = numer / denom;
long r = numer % denom;
if ((r > 0 && denom < 0) || (r < 0 && denom > 0)) {
q = q - 1;
r = r + denom;
}
return (ldiv_t){.quot = q, .rem = r};
}
For both cases, the remainder can be calculated independently of the quotient, but not vice versa. The operations are combined here to save screen space, as the logical branches are the same.
See also
[edit]- Modulo (disambiguation) – many uses of the word modulo, all of which grew out of Carl F. Gauss' approach to modular arithmetic in 1801.
- Modulo (mathematics), general use of the term in mathematics
- Modular exponentiation
- Turn (angle)
Notes
[edit]- ^ Mathematically, these two choices are but two of the infinite number of choices available for the inequality satisfied by a remainder.
- ^ a b Argument order reverses, i.e.,
α|ωcomputes , the remainder when dividingωbyα. - ^ C99 and C++11 define the behavior of
%to be truncated.[9] The standards before then leave the behavior implementation-defined.[10] - ^ Divisor must be positive, otherwise undefined.
- ^ As discussed by Boute, ISO Pascal's definitions of
divandmoddo not obey the Division Identity of D = d · (D / d) + D % d, and are thus fundamentally broken. - ^ Perl usually uses arithmetic modulo operator that is machine-independent. For examples and exceptions, see the Perl documentation on multiplicative operators.[45]
References
[edit]- ^ Weisstein, Eric W. "Congruence". Wolfram MathWorld. Retrieved 2020-08-27.
- ^ Caldwell, Chris. "residue". Prime Glossary. Retrieved August 27, 2020.
- ^ Knuth, Donald. E. (1972). The Art of Computer Programming. Addison-Wesley.
- ^ Boute, Raymond T. (April 1992). "The Euclidean definition of the functions div and mod". ACM Transactions on Programming Languages and Systems. 14 (2). ACM Press (New York, NY, USA): 127–144. doi:10.1145/128861.128862. hdl:1854/LU-314490. S2CID 8321674.
- ^ Peterson, Doctor (5 July 2001). "Mod Function and Negative Numbers". Math Forum - Ask Dr. Math. Archived from the original on 2019-10-22. Retrieved 22 October 2019.
- ^ "Ada 83 LRM, Sec 4.5: Operators and Expression Evaluation". archive.adaic.com. Retrieved 2025-03-03.
- ^ Horvath, Adam (July 5, 2012). "Faster division and modulo operation - the power of two".
- ^ a b ISO/IEC 8652:2012 - Information technology — Programming languages — Ada. ISO, IEC. 2012. sec. 4.5.5 Multiplying Operators.
- ^ "C99 specification (ISO/IEC 9899:TC2)" (PDF). 2005-05-06. sec. 6.5.5 Multiplicative operators. Retrieved 16 August 2018.
- ^ ISO/IEC 14882:2003: Programming languages – C++. International Organization for Standardization (ISO), International Electrotechnical Commission (IEC). 2003. sec. 5.6.4.
the binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined
- ^ ISO/IEC 9899:1990: Programming languages – C. ISO, IEC. 1990. sec. 7.5.6.4.
The fmod function returns the value x - i * y, for some integer i such that, if y is nonzero, the result has the same sign as x and magnitude less than the magnitude of y.
- ^ a b dotnet-bot. "Math.IEEERemainder(Double, Double) Method (System)". Microsoft Learn. Retrieved 2022-10-04.
- ^ "clojure.core - Clojure v1.10.3 API documentation". clojure.github.io. Retrieved 2022-03-16.
- ^ "clojure.core - Clojure v1.10.3 API documentation". clojure.github.io. Retrieved 2022-03-16.
- ^ a b ISO/IEC JTC 1/SC 22/WG 4 (January 2023). ISO/IEC 1989:2023 – Programming language COBOL. ISO.
{{cite book}}: CS1 maint: numeric names: authors list (link) - ^ CoffeeScript operators
- ^ ISO/IEC JTC 1/SC 22 (February 2012). ISO/IEC 23271:2012 — Information technology — Common Language Infrastructure (CLI). ISO. §§ III.3.55–56.
{{cite book}}: CS1 maint: numeric names: authors list (link) - ^ "mod() - CSS: Cascading Style Sheets | MDN". developer.mozilla.org. 2024-06-22. Retrieved 2024-10-23.
- ^ "rem() - CSS: Cascading Style Sheets | MDN". developer.mozilla.org. 2024-10-15. Retrieved 2024-10-23.
- ^ "Expressions - D Programming Language". dlang.org. Retrieved 2021-06-01.
- ^ "operator % method - num class - dart:core library - Dart API". api.dart.dev. Retrieved 2021-06-01.
- ^ "remainder method - num class - dart:core library - Dart API". api.dart.dev. Retrieved 2021-06-01.
- ^ "Kernel — Elixir v1.11.3". hexdocs.pm. Retrieved 2021-01-28.
- ^ "Integer — Elixir v1.11.3". hexdocs.pm. Retrieved 2021-01-28.
- ^ "Basics - core 1.0.5". package.elm-lang.org. Retrieved 2022-03-16.
- ^ "Basics - core 1.0.5". package.elm-lang.org. Retrieved 2022-03-16.
- ^ "Erlang -- math". erlang.org. Retrieved 2021-06-01.
- ^ ANSI (28 January 1987). Programming Languages — Full BASIC. New York: American National Standards Institute. § 5.4.4.
X modulo Y, i.e., X-Y*INT(X/Y).
- ^ ANSI (28 January 1987). Programming Languages — Full BASIC. New York: American National Standards Institute. § 5.4.4.
The remainder function, i.e., X-Y*IP(X/Y).
- ^ "GLSL Language Specification, Version 4.50.7" (PDF). section 5.9 Expressions.
If both operands are non-negative, then the remainder is non-negative. Results are undefined if one or both operands are negative.
- ^ "GLSL Language Specification, Version 4.50.7" (PDF). section 8.3 Common Functions.
- ^ "The Go Programming Language Specification - The Go Programming Language". go.dev. Retrieved 2022-02-28.
- ^ "math package - math - pkg.go.dev". pkg.go.dev. Retrieved 2022-02-28.
- ^ "big package - math/big - pkg.go.dev". pkg.go.dev. Retrieved 2022-02-28.
- ^ "big package - math/big - pkg.go.dev". pkg.go.dev. Retrieved 2024-04-12.
- ^ a b "6 Predefined Types and Classes". www.haskell.org. Retrieved 2022-05-22.
- ^ "Operators". Microsoft. 30 June 2021. Retrieved 2021-07-19.
The % operator is defined only in cases where either both sides are positive or both sides are negative. Unlike C, it also operates on floating-point data types, as well as integers.
- ^ "Mathematics · The Julia Language". docs.julialang.org. Retrieved 2021-11-20.
- ^ "Mathematics · The Julia Language". docs.julialang.org. Retrieved 2021-11-20.
- ^ "rem - Kotlin Programming Language". Kotlin. Retrieved 2021-05-05.
- ^ "mod - Kotlin Programming Language". Kotlin. Retrieved 2021-05-05.
- ^ "Chapter 3: The NASM Language". NASM - The Netwide Assembler version 2.15.05.
- ^ "OCaml library : Stdlib". ocaml.org. Retrieved 2022-02-19.
- ^ "OCaml library : Stdlib". ocaml.org. Retrieved 2022-02-19.
- ^ Perl documentation
- ^ "PHP: Arithmetic Operators - Manual". www.php.net. Retrieved 2021-11-20.
- ^ "PHP: fmod - Manual". www.php.net. Retrieved 2021-11-20.
- ^ "EuclideanRing".
- ^ QuantumWriter. "Expressions". docs.microsoft.com. Retrieved 2018-07-11.
- ^ "R: Arithmetic Operators". search.r-project.org. Retrieved 2022-12-24.
- ^ "F32 - Rust".
- ^ a b r6rs.org
- ^ "Shell Command Language". pubs.opengroup.org. Retrieved 2021-02-05.
- ^ "Solidity Documentation". docs.soliditylang.org. Retrieved 2024-10-17.
- ^ "Apple Developer Documentation". developer.apple.com. Retrieved 2021-11-20.
- ^ "Apple Developer Documentation". developer.apple.com. Retrieved 2021-11-20.
- ^ "Apple Developer Documentation". developer.apple.com. Retrieved 2021-11-20.
- ^ a b Rossberg, Andreas, ed. (19 April 2022). "WebAssembly Core Specification: Version 2.0". World Wide Web Consortium. § 4.3.2 Integer Operations.
- ^ "Zig Documentation". Zig Programming Language. Retrieved 2022-12-18.
- ^ a b "Mod". Wolfram Language & System Documentation Center. Wolfram Research. 2020. Retrieved April 8, 2020.
External links
[edit]- Different kinds of integer division
- Modulorama, animation of a cyclic representation of multiplication tables (explanation in French)
Modulo
View on GrokipediaBasic Concepts and Definitions
Core Definition
The modulo operation is a fundamental concept in integer arithmetic that determines the remainder after dividing one integer by another. For integers and where , the modulo operation, denoted conceptually as , yields the remainder such that for some integer quotient , with the condition .[1] This remainder represents the part of that cannot be evenly divided by , capturing the "leftover" value in the division process. Underlying the modulo operation is the division algorithm, a cornerstone theorem in number theory that asserts the existence and uniqueness of the quotient and remainder for any integers and . The algorithm states that there are unique integers and satisfying and , where is the integer part of the division (specifically, ) and is always non-negative and strictly less than . This ensures a consistent, well-defined remainder regardless of the sign of , as the convention prioritizes a positive . For example, dividing 17 by 5 produces and since , so .[1] Similarly, for negative dividends, -7 divided by 3 gives and because , yielding . The division algorithm presupposes basic integer division, where the goal is to express any integer as a multiple of plus a smaller non-negative component . This decomposition is unique and forms the basis for modular arithmetic, enabling analysis of integers based on their remainders rather than their full magnitude.[7] This core remainder-based definition extends to various contexts in mathematics, though specialized variants may adjust the remainder convention for specific applications.[1]Historical Development
The division algorithm underlying the modulo operation was first formalized by Euclid in his Elements around 300 BC.[8] The roots of the modulo concept trace back to ancient Chinese mathematics, where remainder problems were systematically addressed in Sunzi's Suanjing, a text dating to the 3rd or 4th century AD, featuring examples like divisions yielding specific remainders that anticipated solutions to systems of congruences.[9] In parallel, Indian mathematician Brahmagupta advanced these ideas in the 7th century through his Brahmasphutasiddhanta, introducing the kuttaka method—a pulverizer technique for resolving linear remainder equations, which provided general solutions to Diophantine problems involving moduli.[9] The formalization of modular arithmetic emerged in the early 19th century with Carl Friedrich Gauss's Disquisitiones Arithmeticae, published in 1801, where he introduced the notation of congruences to describe integers equivalent under division by a fixed number, building on prior remainder traditions to create a rigorous framework for number theory.[10] Gauss coined the term "modulo" from the Latin modulus, signifying a measure or standard, to refer to this divisor in congruence relations, establishing it as a foundational element of arithmetic investigations.[3] In the late 19th century, these concepts influenced abstract algebra, particularly through Richard Dedekind's 1871 introduction of ideals as substructures within rings of algebraic integers, which extended modular principles to address factorization failures in number fields.[11] By the 20th century, modular arithmetic was fully integrated into ring theory, with Emmy Noether's axiomatic developments in the 1920s unifying commutative rings and emphasizing their role in broader algebraic structures.[11]Variants and Mathematical Foundations
Remainder-Based Variant
The remainder-based variant of the modulo operation, also known as the least non-negative residue, defines for integers and positive integer as the unique integer such that and , meaning divides .[12] This variant ensures a canonical representative from the set for each congruence class modulo .[13] The uniqueness of follows directly from the division algorithm, which asserts that for any integers and , there exist unique integers and satisfying with . To see uniqueness, suppose there are two such pairs and . Then , so . Since , it follows that . The only integer multiple of with absolute value less than is 0, so and , hence and .[14] When the dividend is negative, the convention maintains a non-negative remainder by adjusting the quotient accordingly, using . Specifically, for , the remainder can be computed as if , and otherwise, ensuring remains in . For example, , since and , corresponding to .[15] This approach differs from truncation toward zero, which might yield a negative remainder for negative , but prioritizes consistency with the non-negative residue system in mathematical number theory.[15]Symmetric and Other Variants
In contrast to the standard remainder-based variant, which is the default in pure mathematics where the remainder is always non-negative, alternative definitions of the modulo operation address scenarios involving negative numbers or require balanced representations. The symmetric variant, known as the least absolute remainder, selects the remainder such that and is minimized, with ranging from to . This ensures the residue is centered around zero for balanced distribution. For instance, because and , while since gives , but adjusting to minimizes the absolute value. This approach appears in algorithms like the Aryabhata method for efficient computation.[16][17] Another variant is the truncated toward zero modulo, defined by where is the truncation of toward zero, which can yield negative remainders when is negative and . For example, , as the truncation of the quotient leads to a signed residue matching the dividend's sign in this convention. This differs from the positive remainder standard by preserving the sign, useful in contexts requiring consistent directional behavior.[18]| Variant | Range of (for ) | Example: | Example: |
|---|---|---|---|
| Remainder-based | 2 | 3 | |
| Symmetric (least absolute) | 2 | -2 | |
| Truncated toward zero | $ | r | < n a $ |
Notation and Conventions
Mathematical Notation
In mathematical literature, the primary notation for congruence in modular arithmetic is , where and are integers congruent modulo the positive integer , meaning divides .[20] This symbol indicates that and leave the same remainder when divided by . For the modulo operation itself, which yields the remainder such that and for some integer , the standard notation is .[3] The evolution of this notation traces back to Carl Friedrich Gauss's Disquisitiones Arithmeticae (1801), where he formalized modular arithmetic using the congruence relation originally expressed as for some integer , but innovated by introducing the triple-bar symbol to denote congruence "modulo ".[20] Prior to Gauss, such relations were described verbally or through divisibility statements like " divides ", without a dedicated symbolic form.[21] The abbreviated "mod" for "modulo" emerged later in the 19th and 20th centuries as a concise infix or prefix operator, standardizing the remainder notation in modern texts.[20] Conventions for typesetting the modulo notation emphasize clarity and consistency, particularly in professional mathematical publishing. The "mod" keyword is typically treated as an upright (roman) operator rather than italicized, distinguishing it from variables; for instance, in congruence, it appears as to ensure proper spacing after the equivalence symbol.[22] In LaTeX, commands like (for inline binary use) or (for parenthesized modulo in congruences) enforce thin spaces around "mod" to align with its role as a relational operator, avoiding the italic slant reserved for identifiers.[23] Some texts italicize "mod" only when functioning strictly as a binary operator in expressions like , but upright form predominates in congruence contexts per international standards.[22]Programming and Applied Notation
In programming languages, the modulo operation is frequently denoted by the % symbol, which computes the remainder after integer division. In C, the % operator yields a result with the same sign as the dividend (the left operand), for example, (-7) % 3 equals -1. Java follows the same convention, where the remainder inherits the sign of the dividend.[24] Python's % operator, however, implements floored modulo division, producing a non-negative result when the divisor is positive, such as (-7) % 3 equaling 2.[25] Some languages employ keywords rather than symbols for modulo. Pascal uses the mod keyword to calculate the remainder, behaving similarly to C's % for positive operands but extending to handle negative values consistently with standard division.[26] Variations exist in the semantics of these operations; Ruby's % operator adopts floored modulo like Python, ensuring the result's sign matches the divisor. In MATLAB, the built-in mod(a, b) function returns a remainder with the sign of the divisor b, always non-negative for positive b, as in mod(-7, 3) yielding 2. In applied contexts, modulo notation facilitates practical computations. Hash functions often use a % n to map a hash value a to one of n buckets in a hash table, distributing elements across storage slots.[27] In engineering fields like signal processing, phases are expressed modulo 2π to wrap angular values into the interval [0, 2π), representing periodic cycles on the unit circle. For floating-point arithmetic under the IEEE 754 standard, dedicated functions handle modulo-like operations to ensure precision and consistency. The remainder function computes the IEEE remainder, defined as x - n * y where n is the nearest integer to x / y (ties rounding to even), differing from truncating divisions in languages like C's fmod. The modf function decomposes a floating-point number into its signed integer part (stored via pointer) and fractional part (returned), effectively isolating the component modulo 1. These draw briefly from mathematical notation for remainder but prioritize computational rounding modes and edge-case handling in hardware implementations.Properties and Identities
Fundamental Properties
The modulo operation, denoted as for integers and positive integer , yields the non-negative remainder such that and for some integer , as established by the division algorithm.[2] This remainder is always non-negative when , ensuring a consistent range for representatives in the residue classes.[3] A key property is the periodicity of the modulo operation with period : for any integer , . This follows directly from the division algorithm; if with , then , yielding the same remainder .[28] The operation is compatible with addition: . To see this, suppose and where and ; then , and applying the modulo again gives the remainder of the sum.[3] The same holds for subtraction: , proved analogously since if and , then .[2] Regarding zero divisors, because , fitting the division algorithm with remainder 0. Likewise, as . These properties underscore the role of multiples of as equivalents to zero in the modulo system.[28]Key Identities and Theorems
One fundamental identity in modular arithmetic is the multiplicative congruence property, which states that for any integers , , and positive integer , This identity follows from the distributive property of integers and the definition of congruence, enabling efficient computation of products modulo by reducing operands first.[3] Another key identity concerns the existence of modular multiplicative inverses. For integers and positive integer , an integer exists such that if and only if . This condition ensures is coprime to the modulus, allowing unique invertibility in the multiplicative group of integers modulo .[3] Related properties include the additive inverse, where and the inverse multiplication property, where assuming and are coprime. Additionally, modular division is defined as when and are coprime, and undefined otherwise.[3] The Chinese Remainder Theorem provides a powerful result for systems of congruences with coprime moduli. Specifically, if and are coprime positive integers and are any integers, then the system has a unique solution modulo . This theorem decomposes problems modulo composite numbers into independent subproblems modulo their prime power factors.[29] Fermat's Little Theorem states that if is a prime number and is an integer not divisible by , then Originally stated by Pierre de Fermat in 1640, this theorem forms the basis for many primality tests and cryptographic algorithms.[30] Euler's theorem generalizes Fermat's Little Theorem to composite moduli. If , then where is Euler's totient function, counting the integers up to that are coprime to . First proved by Leonhard Euler in the 18th century, this identity underpins efficient exponentiation in modular arithmetic.[31] Wilson's Theorem offers a characterization of primes via factorials: for a prime , Proposed by John Wilson in the 18th century and first proved by Joseph-Louis Lagrange in 1773, this theorem provides a primality criterion based on factorial congruences.[32]Applications in Mathematics
Modular Arithmetic
Modular arithmetic provides a foundational framework for performing arithmetic operations on integers under the equivalence relation defined by the modulo operation. The set of integers modulo , denoted ℤ/nℤ, consists of the equivalence classes for , where two integers are equivalent if their difference is divisible by . This structure forms a commutative ring with unity under addition and multiplication defined modulo : and , both taken modulo .[33] The basic operations in ℤ/nℤ mirror those in the integers but wrap around at . For example, consider ; the addition table is as follows:| + | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| 0 | 0 | 1 | 2 | 3 | 4 |
| 1 | 1 | 2 | 3 | 4 | 0 |
| 2 | 2 | 3 | 4 | 0 | 1 |
| 3 | 3 | 4 | 0 | 1 | 2 |
| 4 | 4 | 0 | 1 | 2 | 3 |
| × | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | 2 | 3 | 4 |
| 2 | 0 | 2 | 4 | 1 | 3 |
| 3 | 0 | 3 | 1 | 4 | 2 |
| 4 | 0 | 4 | 3 | 2 | 1 |
Number Theory Uses
In number theory, the modulo operation facilitates efficient divisibility tests for specific integers, allowing determination of whether a number is divisible by another without full division. For divisibility by 10, a number is divisible if its last digit is 0, equivalent to the number being congruent to 0 modulo 10, since powers of 10 are multiples of 10.[35] For divisibility by 11, the alternating sum of the digits must be congruent to 0 modulo 11; this follows from the fact that , so the number's decimal expansion simplifies to .[36] The modulo operation plays a crucial role in primality testing and integer factorization. Wilson's Theorem states that for a prime , , providing a primality criterion: compute the factorial modulo and check if it equals ; this is exact but computationally intensive for large .[37] In factorization, the RSA cryptosystem relies on the difficulty of factoring a modulus where and are large primes; encryption uses modular exponentiation , and decryption requires the private key derived from the factorization.[38] Solving linear congruences of the form is a fundamental application, where solutions exist if divides . The extended Euclidean algorithm finds such solutions by computing integers such that , then scaling to solve for ; the general solution is for integer , where .[39] Modulo is essential in studying quadratic residues, where an integer is a quadratic residue modulo an odd prime (with ) if there exists such that . The Legendre symbol indicates this: , equaling 1 if is a quadratic residue, -1 if not, and 0 if divides .[40]Computing and Implementation
In Programming Languages
In programming languages, the modulo operation is commonly implemented via the% operator for integers and dedicated functions for floating-point or specialized types, with semantics that can differ across languages, especially regarding the handling of negative numbers.
In C and C++, the % operator yields the remainder from truncated division toward zero, such that for operands a and b, the result satisfies a == (a / b) * b + (a % b). For negative dividends, the remainder inherits the sign of the dividend; for instance, -5 % 3 equals -2 since -5 / 3 truncates to -1.[41]
Python's % operator, in contrast, pairs with floored division (//), producing a remainder with the sign of the divisor to align with mathematical modulo conventions. Thus, -5 % 3 yields 1, as -5 // 3 floors to -2 and -5 - (-2) * 3 = 1. This ensures the result is non-negative when the divisor is positive.[42]
For floating-point numbers, Java's Math.fmod(a, b) computes the remainder congruent to a modulo b, with the sign matching a and absolute value less than |b|, akin to truncated division. By comparison, Math.IEEEremainder(a, b) adheres to IEEE 754 by rounding the quotient to the nearest integer (ties to even), also signing the result like a but prioritizing minimal magnitude. Both handle edge cases consistently, such as 0.0 % n == 0.0 for finite nonzero n, and n % n == 0.0 for finite nonzero n.[43]
Specialized libraries enhance modulo capabilities beyond built-in types. The GNU Multiple Precision Arithmetic Library (GMP) offers mpz_mod for arbitrary-precision integers, setting the result r such that 0 ≤ r < |b| and a ≡ r \pmod{b}, with r always non-negative regardless of the sign of b.[44]
NumPy extends Python's modulo to arrays via the % operator or numpy.mod/numpy.remainder functions, performing element-wise computation with broadcasting support and inheriting Python's floored semantics, where the remainder's sign matches the divisor.[45]
In SQL, the MOD function computes the remainder of division. In standard implementations like Oracle and MySQL, it uses truncated division toward zero, yielding a remainder with the sign of the dividend; for example, MOD(-5, 3) returns -2.[46] Variations exist across DBMS; for instance, PostgreSQL uses floored division, yielding a positive remainder such that MOD(-5, 3) returns 1.[47]
Performance and Optimization
In hardware implementations, the modulo operation is frequently obtained as a byproduct of integer division instructions. On x86 architectures, the unsigned DIV instruction divides the dividend in the appropriate register pair (e.g., EDX:EAX) by the divisor and stores the quotient in EAX and the remainder (modulo result) in EDX, enabling efficient computation without separate modulo hardware.[48] For divisions by constant values, optimization techniques employ "magic numbers"—precomputed multipliers that transform the operation into a series of multiplications, shifts, and subtractions, reducing reliance on the slower division unit; this approach, originating from early compiler optimizations, can achieve near-multiplication speeds for fixed moduli. Software optimizations further enhance modulo performance for specific cases. When the modulus is a power of 2, the operation simplifies to a bitwise AND with , masking the lower bits of and avoiding division entirely; this bitwise trick executes in a single cycle on most processors, offering substantial speedup over general modulo.[49] For small constant moduli, lookup tables precompute remainders for input ranges, trading memory for reduced computation; multi-level table designs minimize access latency while supporting modular reductions up to certain bit widths.[50] For big-integer arithmetic, particularly in cryptographic applications, advanced algorithms integrate modulo with multiplication. The Karatsuba algorithm accelerates large multiplications by reducing elementary operations from quadratic to , often combined with Montgomery reduction, which avoids explicit division by representing numbers in a Montgomery form and performing reductions via shifts and adds.[51] This pairing yields efficient modular multiplication for elliptic curve cryptography and RSA, with implementations showing 20-50% latency improvements over naive methods on 64-bit platforms.[52] On modern CPUs (e.g., Intel Raptor Lake and AMD Zen 5 as of 2024), the latency of a general 64-bit integer modulo operation typically ranges from 12-90 cycles depending on the divisor, signed/unsigned operation, and architecture (e.g., ~12-36 cycles on Zen 5; 20-92 cycles on Raptor Lake), contrasting sharply with the sub-cycle throughput of addition, which underscores the need for these optimizations in performance-critical code.[53] While AVX-512 provides vectorized floating-point division, integer modulo requires custom implementations (e.g., using reciprocal multiplication approximations), enabling SIMD processing across multiple lanes but without native instructions, achieving up to 8x speedup for batched operations in polynomial evaluations with careful alignment to avoid scalar fallbacks.[54] These hardware and software techniques build upon baseline modulo implementations in programming languages to deliver scalable efficiency.Common Challenges and Generalizations
Frequent Pitfalls
One common pitfall in using the modulo operation arises from differing behaviors with negative numbers across mathematical definitions and programming implementations. In mathematics, the modulo operation typically yields a non-negative remainder between 0 and for divisor , such that for with ; for example, because .[55] However, in languages like C, the % operator computes the remainder with the sign of the dividend using truncated division toward zero, resulting in .[56] This discrepancy can lead to incorrect assumptions about positive outputs, causing bugs in algorithms expecting mathematical modulo, such as hashing or cyclic indexing. Variant implementations in other languages, like Python's positive remainder for negatives, further contribute to confusion during cross-platform development.[56] Division by zero in modulo operations is undefined and triggers runtime errors in most programming environments. Attempting results in a floating-point exception (SIGFPE) in C/C++, or a ZeroDivisionError in Python, halting execution and requiring explicit checks to prevent crashes. In loops using modulo for conditions, such as checking multiples with , failing to handle edge cases like can propagate errors unexpectedly. Off-by-one errors frequently occur when using modulo for array indexing or cycling in loops, where the condition identifies multiples but may be misinterpreted at boundaries. For instance, in a loop from to , maps to index 0, potentially skipping or duplicating the first element if the loop intent excludes the endpoint, leading to incorrect iterations.[57] Floating-point modulo introduces precision issues due to binary representation limitations, where numbers like 0.1 cannot be exactly stored. For example, should ideally be 0 but computes as approximately 0.09999999999999995 in double precision, causing failures in equality checks or accumulations.[58] Operations with non-integer divisors exacerbate this, as rounding errors in the underlying division propagate to the remainder. In cryptography, incorrect modulo implementations, particularly non-constant-time modular reductions in exponentiation, enable side-channel timing attacks that leak private keys. For RSA, variations in execution time during modular multiplications reveal bit patterns of the exponent, as demonstrated in attacks recovering full keys from measured timings.[59]Extended Forms and Implementations
Extended forms of the modulo operation allow for adjustments to the standard remainder computation, accommodating shifted ranges through the inclusion of an offset. A common generalization is the offset modulo, expressed as , where represents the desired shift in the representative set of remainders. This form preserves the periodic nature of the operation while relocating the zero point, ensuring remainders fall within a customized interval such as . For example, in determining days of the week, the standard yields remainders from 0 to 6, but applying an offset of 1—via —produces values from 1 to 7, aligning with conventional labeling from Sunday to Saturday.[1][60] Variants of the modulo operation can be implemented from the floored version by post-processing the remainder to achieve desired truncation behaviors, such as symmetry. The symmetric modulo, also called centered or balanced modulo, returns values in the approximate interval , which is useful for applications requiring centered residues around zero, like balanced ternary systems or error analysis. One implementation derives it from the floored modulo as follows: For even , adjustments may be needed at the midpoint to resolve ambiguity, ensuring the result aligns with the centered definition . Beyond these adaptations, the modulo operation generalizes to more advanced mathematical structures. Modular exponentiation, denoted , efficiently computes large powers modulo using algorithms like binary exponentiation, reducing intermediate values through repeated squaring and multiplication modulo ; this is foundational in cryptography for operations like RSA encryption. In p-adic analysis, modulo extends to p-adic numbers , where congruences modulo powers of a prime (i.e., ) define the topology and completion of the rationals under the p-adic valuation, enabling interpolation and continuity in number-theoretic contexts.[61][62] In computational environments, particularly on graphics processing units (GPUs), the modulo operation for non-integers is adapted for efficiency in specialized hardware. The CUDA programming model implements floating-point modulo via thefmod function (or fmodf for single precision), which computes the remainder of according to IEEE-754 standards with zero ULP error, making it suitable for periodic simulations such as molecular dynamics where positions are wrapped using offsets to enforce boundary conditions.[63][64]




