Returns the remainder from dividing two integers.
1. Description
The mod operator pops two integers from the operand stack, divides int1 by int2, and pushes the remainder back onto the stack. The sign of the result is the same as the sign of the dividend (int1). Both operands must be integers, and the result is always an integer.
This is a remainder operation, not a true modulo operation in the mathematical sense, because the sign follows the dividend rather than the divisor.
This is a Level 1 operator, available in all PostScript implementations.
3. Parameters
int1-
The dividend - the integer to be divided
int2-
The divisor - the integer to divide by (must be non-zero)
4. Return Values
remainder-
The remainder when int1 is divided by int2. The sign matches int1’s sign.
5. Examples
5.1. Basic Modulo
% Simple remainders
5 3 mod % → 2 (5 = 3×1 + 2)
7 4 mod % → 3 (7 = 4×1 + 3)
8 4 mod % → 0 (8 = 4×2 + 0, exact division)
10 7 mod % → 3 (10 = 7×1 + 3)
5.2. Sign Behavior
% Positive dividend → positive remainder
5 3 mod % → 2
5 -3 mod % → 2 (sign follows dividend)
% Negative dividend → negative remainder
-5 3 mod % → -2 (sign follows dividend!)
-5 -3 mod % → -2
% Comparison with mathematical modulo
% PostScript mod is remainder, not true modulo
-7 3 mod % → -1 (remainder)
% True modulo would be 2
5.3. Quotient and Remainder Together
% Get both quotient and remainder
/divAndMod { % int1 int2 -> quotient remainder
2 copy idiv % int1 int2 quotient
3 1 roll mod % quotient remainder
} def
17 5 divAndMod % → 3 2 (17 = 5×3 + 2)
23 7 divAndMod % → 3 2 (23 = 7×3 + 2)
6. Advanced Examples
6.1. RGB Color Cycling
% Cycle through colors
/colorFromIndex { % index -> r g b
% Generate different colors based on index
dup 3 mod 0 eq { pop 1 0 0 } if % Red
dup 3 mod 1 eq { pop 0 1 0 } if % Green
dup 3 mod 2 eq { pop 0 0 1 } if % Blue
} def
0 colorFromIndex % → 1 0 0 (red)
1 colorFromIndex % → 0 1 0 (green)
2 colorFromIndex % → 0 0 1 (blue)
3 colorFromIndex % → 1 0 0 (red again)
6.2. Checksum Calculation
% Simple checksum (sum mod 256)
/checksum { % string -> checksum
0 exch % Accumulator
{
add % Add each character code
} forall
256 mod % Keep in byte range
} def
(Hello) checksum % → 244
6.3. Circular Buffer
% Implement circular buffer indexing
/circularIndex { % currentIndex increment bufferSize -> newIndex
3 -1 roll add % increment bufferSize (currentIndex+increment)
exch mod % (currentIndex+increment) mod bufferSize
dup 0 lt { % Handle negative results
2 index add
} if
exch pop
} def
5 3 10 circularIndex % → 8 (5+3 in buffer of size 10)
8 5 10 circularIndex % → 3 (wraps around: 8+5=13, 13 mod 10=3)
6.4. Digit Extraction
% Extract individual digits
/getDigit { % number position -> digit
% Position 0 is ones, 1 is tens, etc.
1 exch {
10 mul
} repeat
2 copy idiv % number divisor quotient
10 mod % number divisor (quotient mod 10)
3 1 roll pop pop
} def
12345 0 getDigit % → 5 (ones place)
12345 2 getDigit % → 3 (hundreds place)
7. Edge Cases and Common Pitfalls
mod is a remainder operation, not true mathematical modulo.
|
7.1. Remainder vs. Modulo
% PostScript mod is remainder (sign follows dividend)
-5 3 mod % → -2 (remainder)
% True mathematical modulo would give: 1
% To get true modulo:
/truemod { % int1 int2 -> modulo
2 copy mod % int1 int2 remainder
dup 0 lt { % If remainder is negative
add % Add divisor to make positive
} {
exch pop % Just use remainder
} ifelse
} def
-5 3 truemod % → 1 (true modulo)
5 3 truemod % → 2 (same as mod for positive)
8. Type Requirements
Both operands must be integers. Real numbers or other types will cause a typecheck error:
% BAD: Non-integer operands
7.5 3 mod % ERROR: typecheck
10 3.0 mod % ERROR: typecheck
(text) 5 mod % ERROR: typecheck
10. PostScript Level
Available in: PostScript Level 1 and higher
This is a fundamental arithmetic operator available in all PostScript implementations.
11. Error Conditions
stackunderflow-
The operand stack contains fewer than two elements.
5 mod % ERROR: stackunderflow (need 2 operands) typecheck-
One or both operands are not integers.
5.5 2 mod % ERROR: typecheck (must be integers) 7 2.0 mod % ERROR: typecheck undefinedresult-
The divisor is zero.
10 0 mod % ERROR: undefinedresult (division by zero)
12. Performance Considerations
The mod operator is fast, typically implemented as a single hardware instruction:
-
Similar performance to
idiv -
Often paired with
idivfor efficiency -
Useful for array wraparound and cyclic operations
13. Best Practices
-
Combine with
idivwhen you need both quotient and remainder -
Remember sign behavior - result sign matches dividend
-
Validate divisor is non-zero in user-facing code
-
Use for cyclic operations - wraparound, rotation, etc.
14. See Also
-
Arithmetic and Math - All arithmetic operators