Multiplies two numbers and returns their product.
1. Description
The mul operator pops two numbers from the operand stack, multiplies them together, and pushes the result back onto the stack. If both operands are integers and the result fits within the integer range, the result is an integer. Otherwise, the result is a real number.
This is a Level 1 operator, available in all PostScript implementations.
4. Return Values
product-
The product of num1 × num2. Type depends on operands:
-
Integer if both operands are integers and result fits in integer range
-
Real otherwise
-
5. Examples
5.1. Basic Multiplication
% Integer multiplication
3 4 mul % → 12 (integer result)
% Real multiplication
2.5 4.0 mul % → 10.0 (real result)
% Mixed types
5 2.5 mul % → 12.5 (real result)
% Negative numbers
-3 4 mul % → -12 (integer result)
-2.5 -4 mul % → 10.0 (real result)
5.2. Scaling Operations
% Scale a coordinate by a factor
100 1.5 mul % → 150.0 (scale by 1.5)
% Scale percentage to decimal
15 0.01 mul % → 0.15 (15% as decimal)
% Convert inches to points (1 inch = 72 points)
8.5 72 mul % → 612.0 (8.5 inches in points)
6. Advanced Examples
6.1. Vector Scaling
/scaleVector { % [x y] scalar -> [x' y']
% Scale a 2D vector
exch aload pop % scalar x y
2 index mul % scalar x (y*scalar)
3 1 roll % (y*scalar) scalar x
mul exch % (x*scalar) (y*scalar)
2 array astore % [x' y']
} def
[10 20] 2.5 scaleVector % → [25.0 50.0]
6.2. Matrix Scalar Multiplication
/scaleMatrix { % [a b c d tx ty] scalar -> [a' b' c' d' tx' ty']
% Multiply all matrix elements by scalar
[
7 -1 roll aload pop % scalar a b c d tx ty
8 -1 roll % a b c d tx ty scalar
dup 8 1 roll % scalar a b c d tx ty scalar
mul % scalar a b c d tx (ty*scalar)
7 1 roll mul % scalar a b c d (tx*scalar) (ty*scalar)
6 1 roll mul % scalar a b c (d*scalar) (tx*scalar) (ty*scalar)
5 1 roll mul % scalar a b (c*scalar) (d*scalar) (tx*scalar) (ty*scalar)
4 1 roll mul % scalar a (b*scalar) (c*scalar) (d*scalar) (tx*scalar) (ty*scalar)
3 1 roll mul % (a*scalar) (b*scalar) (c*scalar) (d*scalar) (tx*scalar) (ty*scalar)
]
} def
7. Edge Cases and Common Pitfalls
| Integer overflow results in a real number, not an error. |
7.1. Integer Overflow
% Large integers overflow to real
1000000 1000000 mul % → 1.0e12 (real, exceeds integer range)
% Maximum integer multiplication
46340 46341 mul % → 2147488340 (still integer)
46341 46341 mul % → 2147534481.0 (real, overflow)
7.2. Multiplying by Zero
% Zero multiplication
100 0 mul % → 0 (integer)
100.5 0 mul % → 0.0 (real)
% Sign is preserved in reals
-5.0 0 mul % → -0.0 or 0.0 (implementation dependent)
8. Type Requirements
Both operands must be numeric (integer or real). Other types will cause a typecheck error:
% BAD: Non-numeric operands
(hello) 5 mul % ERROR: typecheck
10 [1 2] mul % 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 mul % ERROR: stackunderflow (need 2 operands) typecheck-
One or both operands are not numbers.
5 (text) mul % ERROR: typecheck undefinedresult-
The result is outside the representable range for real numbers.
1.0e308 1.0e308 mul % ERROR: undefinedresult
12. Performance Considerations
Multiplication is a fast primitive operation:
-
Integer multiplication is faster than real multiplication
-
For repeated multiplication by the same factor, consider pre-calculating
-
Use bit-shifting (
bitshift) for multiplication by powers of 2 when working with integers
% Multiply by powers of 2 using bitshift (integers only)
10 1 bitshift % → 20 (same as 10 2 mul)
10 2 bitshift % → 40 (same as 10 4 mul)
13. Best Practices
-
Use integer arithmetic when possible for better precision
-
Be aware of type promotion - one real operand makes real result
-
Check for overflow in applications with large numbers
-
Use appropriate precision for the application domain
14. See Also
-
Arithmetic and Math - All arithmetic operators