Subtracts the second number from the first and returns the difference.
1. Description
The sub operator pops two numbers from the operand stack, subtracts the top number (num2) from the second number (num1), 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.
3. Parameters
num1-
The minuend - the number to subtract from (integer or real)
num2-
The subtrahend - the number to subtract (integer or real)
4. Return Values
difference-
The difference 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 Subtraction
% Integer subtraction
10 3 sub % → 7 (integer result)
% Real subtraction
9.5 2.3 sub % → 7.2 (real result)
% Mixed types
10 2.5 sub % → 7.5 (real result)
% Negative results
5 10 sub % → -5 (integer result)
5.2. Order Matters
% Subtraction is not commutative
10 3 sub % → 7
3 10 sub % → -7 (different result!)
% Stack order is crucial
5 2 sub % Computes 5 - 2 = 3
2 5 sub % Computes 2 - 5 = -3
6. Advanced Examples
6.1. Vector Subtraction
/subtractVectors { % [x1 y1] [x2 y2] -> [x3 y3]
% Subtract vector 2 from vector 1
aload pop % x2 y2
3 -1 roll aload pop % y2 x2 x1 y1
3 -1 roll exch % y2 x1 y1 x2
sub % y2 x1 (y1-x2)
3 1 roll % (y1-x2) y2 x1
exch sub % (y1-x2) (x1-y2)
exch % (x1-y2) (y1-x2)
2 array astore % [x3 y3]
} def
[100 200] [30 50] subtractVectors % → [70 150]
6.2. Range Checking
% Check if value is within range
/inRange { % value min max -> bool
% Returns true if min <= value <= max
2 index % value min max value
2 index % value min max value min
ge % value min max (value>=min)
3 1 roll % (value>=min) value min max
3 -1 roll % (value>=min) min max value
le % (value>=min) (value<=max)
and % bool
} def
50 0 100 inRange % → true
150 0 100 inRange % → false
7. Edge Cases and Common Pitfalls
Order of operands is critical - sub is not commutative.
|
7.1. Operand Order
% WRONG: Operands in wrong order
% Want to compute x - 5
/x 10 def
5 x sub % → -5 (computed 5 - 10)
% CORRECT: Proper order
/x 10 def
x 5 sub % → 5 (computed 10 - 5)
8. Type Requirements
Both operands must be numeric (integer or real). Other types will cause a typecheck error:
% BAD: Non-numeric operands
(hello) 5 sub % ERROR: typecheck
10 (world) sub % ERROR: typecheck
[1 2] 3 sub % 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 sub % ERROR: stackunderflow (need 2 operands) typecheck-
One or both operands are not numbers.
(text) 5 sub % ERROR: typecheck undefinedresult-
The result is outside the representable range for real numbers (extremely rare).
12. Performance Considerations
The sub operator is a primitive operation with O(1) constant time complexity. Performance is excellent and comparable to add.
13. Best Practices
-
Remember operand order: The top of stack is subtracted FROM the second element
-
Use integer arithmetic when possible for precision and performance
-
Check for underflow/overflow in critical applications
-
Be careful with real precision in financial or scientific calculations
13.1. Safe Subtraction with Bounds
% Subtract with minimum bound
/subWithMin { % num1 num2 min -> result
3 copy % num1 num2 min num1 num2 min
pop sub % num1 num2 min (num1-num2)
2 copy lt { % If result < min
exch pop % Use min
} {
exch pop % Use result
} ifelse
} def
10 15 0 subWithMin % → 0 (10-15=-5, but min is 0)
14. See Also
-
Arithmetic and Math - All arithmetic operators