Returns the absolute value (magnitude) of a number.

1. Description

The abs operator pops a number from the operand stack and pushes its absolute value back onto the stack. The type of the result is the same as the type of the operand, unless the operand is the most negative integer (-2147483648), in which case the result is a real.

This is a Level 1 operator, available in all PostScript implementations.

2. Syntax

num1 abs num2

2.1. Stack Effect

Table 1. Before Execution
Position Content

Top

num1 (integer or real) - Number to get absolute value of

Table 2. After Execution
Position Content

Top

num2 (integer or real) - Absolute value of num1

3. Parameters

num1

Any number (integer or real), positive, negative, or zero

4. Return Values

num2

The absolute value of num1:

  • Same type as num1 (integer or real)

  • Exception: Most negative integer returns real

5. Examples

5.1. Basic Usage

% Positive numbers unchanged
5 abs          % → 5
4.5 abs        % → 4.5

% Negative numbers become positive
-3 abs         % → 3
-4.5 abs       % → 4.5

% Zero unchanged
0 abs          % → 0
-0.0 abs       % → 0.0

5.2. Distance Calculation

% Distance between two points (1D)
/distance {  % x1 x2 -> dist
    sub abs
} def

10 3 distance  % → 7
3 10 distance  % → 7 (always positive)

5.3. Range Validation

% Check if value is within tolerance
/withinTolerance {  % value target tolerance -> bool
    3 -1 roll sub abs  % |value - target|
    le                 % <= tolerance?
} def

5.1 5.0 0.2 withinTolerance  % → true
5.3 5.0 0.2 withinTolerance  % → false

5.4. Magnitude Comparison

% Compare magnitudes regardless of sign
/absCmp {  % num1 num2 -> -1|0|1
    % Returns -1 if |num1| < |num2|
    %          0 if |num1| = |num2|
    %          1 if |num1| > |num2|
    exch abs exch abs  % |num1| |num2|
    2 copy eq {
        pop pop 0
    } {
        lt { -1 } { 1 } ifelse
    } ifelse
} def

-5 3 absCmp    % → 1 (|-5| > |3|)
3 -5 absCmp    % → -1 (|3| < |-5|)

6. Advanced Examples

6.1. Vector Magnitude (2D)

/vectorMagnitude {  % [x y] -> magnitude
    aload pop           % x y
    dup mul exch        % y² x
    dup mul add         % y² + x²
    sqrt                % √(x² + y²)
} def

[3 4] vectorMagnitude  % → 5.0

6.2. Normalize to Range

% Clamp value to range by absolute distance
/clampSymmetric {  % value limit -> clamped
    % Clamp value to [-limit, +limit]
    exch dup abs       % limit value |value|
    2 index gt {       % If |value| > limit
        pop            % limit value
        dup 0 lt {     % If value < 0
            neg        % -limit
        } if           % else +limit
    } {
        exch pop       % value (within range)
    } ifelse
} def

150 100 clampSymmetric  % → 100
-150 100 clampSymmetric % → -100
50 100 clampSymmetric   % → 50

6.3. Maximum Absolute Value

% Find element with largest absolute value
/maxAbs {  % [num1 num2 ... numn] -> num
    dup 0 get abs         % Initial max magnitude
    exch                  % maxMag array
    dup 0 get             % maxMag array firstValue
    3 1 roll              % firstValue maxMag array
    {
        dup abs           % ... value |value|
        2 index gt {      % If |value| > maxMag
            exch pop      % value maxMag
            dup abs       % value |value|
            exch          % |value| value
        } {
            pop           % Keep current max
        } ifelse
    } forall
    exch pop              % Return value with max magnitude
} def

[3 -7 5 -2] maxAbs  % → -7

6.4. Difference Comparison

% Check if two values are approximately equal
/approxEqual {  % num1 num2 epsilon -> bool
    3 -1 roll sub abs  % epsilon |num1-num2|
    exch               % |num1-num2| epsilon
    le                 % Is difference <= epsilon?
} def

0.1 0.2 add 0.3 0.0001 approxEqual  % → true

7. Edge Cases and Common Pitfalls

Most negative integer (-2147483648) returns a real number.

7.1. Most Negative Integer

% Special case: most negative 32-bit integer
-2147483648 abs  % → 2147483648.0 (real!)

% This is because positive equivalent exceeds integer range
% All other integers preserve type
-2147483647 abs  % → 2147483647 (still integer)

7.2. Zero Handling

% Zero has no sign in integers
0 abs          % → 0

% Real zero may preserve sign (implementation dependent)
-0.0 abs       % → 0.0 or -0.0

7.3. Type Preservation

% Type is preserved
-5 abs         % → 5 (integer)
-5.0 abs       % → 5.0 (real)

% Unless overflow
-2147483648 abs % → 2147483648.0 (real)

8. Type Requirements

The operand must be numeric (integer or real). Other types will cause a typecheck error:

% BAD: Non-numeric operands
(hello) abs    % ERROR: typecheck
[1 2] abs      % ERROR: typecheck
  • neg - Negate a number

  • add - Add two numbers

  • sub - Subtract two numbers

  • sqrt - Square root

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 is empty.

abs            % ERROR: stackunderflow (need 1 operand)
typecheck

The operand is not a number.

(text) abs     % ERROR: typecheck

12. Performance Considerations

The abs operator is extremely fast:

  • Implemented as a simple sign check and negation

  • O(1) constant time complexity

  • No overhead for positive numbers in some implementations

13. Best Practices

  1. Use for distance and magnitude calculations

  2. Understand type preservation - maintains integer/real type

  3. Remember special case for most negative integer

  4. Combine with comparisons for magnitude-based logic

13.1. Common Patterns

% Get sign of number
/sign {  % num -> -1|0|1
    dup 0 eq {
        pop 0
    } {
        dup 0 lt { pop -1 } { pop 1 } ifelse
    } ifelse
} def

% Ensure positive
/ensurePositive {  % num -> positiveNum
    abs
} def

% Maximum magnitude
/maxMagnitude {  % num1 num2 -> maxNum
    2 copy abs exch abs gt {
        exch
    } if
    pop
} def

-10 7 maxMagnitude  % → -10

13.2. Safe Absolute Difference

% Absolute difference between two numbers
/absDiff {  % num1 num2 -> diff
    sub abs
} def

10 3 absDiff   % → 7
3 10 absDiff   % → 7 (same result)
-5 5 absDiff   % → 10

14. See Also


Back to top

Copyright © 2025 Ribose. PostScript is a trademark of Adobe. Distributed under the MIT License.