Beginner

Operators in RPG

Learn arithmetic, comparison, logical, and assignment operators in modern free-form RPG IV, including the %DIV and %REM built-in functions and operator precedence

Operators are the verbs of expression-based programming: they take values and combine them into new ones. Modern free-form RPG IV evaluates expressions much like any other procedural language, using familiar infix operators (+, -, *, /) inside EVAL-style assignments. This is a significant departure from classic fixed-format RPG, where arithmetic was expressed through operation codes like ADD, SUB, and MULT spread across factor columns.

Because RPG was built for business data processing, its operator set is tuned for precise decimal arithmetic. The language leans on packed and zoned decimal types to avoid the rounding surprises of binary floating point, and it provides built-in functions (BIFs) such as %DIV and %REM for integer division and remainders rather than a dedicated % operator. This tutorial covers arithmetic, comparison, logical, assignment, and string operators, plus how RPG resolves operator precedence.

All examples use fully free-form syntax (the **FREE directive on line 1). As with every RPG program on this site, the code is shown and explained here, but running it requires access to an IBM i system — there is no open-source RPG compiler or Docker image.

Arithmetic Operators

RPG supports the standard arithmetic operators in expressions: + (add), - (subtract), * (multiply), / (divide), and ** (exponentiation). Integer division and remainder are handled by the %DIV and %REM built-in functions rather than operators.

Create a file named arithmetic.rpgle:

**FREE
dcl-s a int(10) inz(17);
dcl-s b int(10) inz(5);
dcl-s realDiv packed(7:3);
dcl-s power int(20);

// Basic arithmetic operators
dsply ('a + b  = ' + %char(a + b));     // addition
dsply ('a - b  = ' + %char(a - b));     // subtraction
dsply ('a * b  = ' + %char(a * b));     // multiplication

// True division keeps decimal places in a packed field
realDiv = a / b;
dsply ('a / b  = ' + %char(realDiv));

// Integer division and remainder use BIFs, not operators
dsply ('%div   = ' + %char(%div(a:b)));
dsply ('%rem   = ' + %char(%rem(a:b)));

// Exponentiation
power = b ** 2;
dsply ('b ** 2 = ' + %char(power));

*inlr = *on;

Notes on RPG’s arithmetic model:

  • %char converts a numeric value to its character form so it can be concatenated into the dsply message. RPG has no implicit number-to-string coercion.
  • a / b stores 3.400 because the result field realDiv is packed(7:3) — the decimal positions of the result field control the precision, not the operands.
  • %div(a:b) truncates toward zero, giving 3, while %rem(a:b) returns the remainder 2.
  • ** is exponentiation; b ** 2 is 25.

Comparison and Logical Operators

Comparison operators produce a true/false result used in IF, DOW, DOU, and WHEN conditions. RPG uses = for equality (not ==) and <> for “not equal”. The logical operators are the keywords AND, OR, and NOT rather than symbols.

Create a file named comparison.rpgle:

**FREE
dcl-s x int(10) inz(10);
dcl-s y int(10) inz(20);
dcl-s age int(10) inz(25);
dcl-s hasLicense ind inz(*on);

// Relational operators: =  <>  <  >  <=  >=
if x < y;
  dsply 'x is less than y';
endif;

if x <> y;
  dsply 'x is not equal to y';
endif;

// Logical AND
if age >= 18 and hasLicense;
  dsply 'Can drive';
endif;

// Logical OR / NOT
if age < 18 or not hasLicense;
  dsply 'Cannot drive';
else;
  dsply 'All requirements met';
endif;

*inlr = *on;

Key points:

  • Equality is a single =. Because RPG uses = for both assignment and comparison, context (an IF condition vs. a free-form assignment statement) determines the meaning.
  • ind is RPG’s indicator (boolean) type. An indicator evaluates directly in a condition, so and hasLicense needs no = *on.
  • *on and *off are the boolean literals (equivalent to '1' and '0').

Assignment and Compound Operators

The = operator assigns a value. Free-form RPG also supports compound assignment operators — +=, -=, *=, /=, and **= — which update a variable in place.

Create a file named assignment.rpgle:

**FREE
dcl-s total int(10) inz(100);

total += 50;   // total = total + 50
dsply ('After += 50: ' + %char(total));

total -= 30;   // total = total - 30
dsply ('After -= 30: ' + %char(total));

total *= 2;    // total = total * 2
dsply ('After *= 2:  ' + %char(total));

total /= 4;    // total = total / 4
dsply ('After /= 4:  ' + %char(total));

*inlr = *on;

Compound operators are purely shorthand: total += 50 is identical to total = total + 50. They were added with free-form calculations and are unavailable in fixed-format RPG, which relied on the ADD, SUB, MULT, and DIV operation codes instead.

String Operators

In RPG the + operator concatenates character strings as well as adding numbers. Because fixed-length char fields are blank-padded to their full size, you typically combine + with the %TRIM built-in function to remove trailing blanks. Variable-length varchar fields concatenate cleanly without padding.

Create a file named strings.rpgle:

**FREE
dcl-s firstName varchar(20) inz('Hello');
dcl-s lastName varchar(20) inz('World');
dcl-s message varchar(50);

dcl-s padded1 char(10) inz('Hello');
dcl-s padded2 char(10) inz('World');

// varchar concatenation needs no trimming
message = firstName + ', ' + lastName + '!';
dsply message;

// char fields are blank-padded, so trim before joining
dsply (%trim(padded1) + ' ' + %trim(padded2));

*inlr = *on;

Without %trim, the fixed char(10) fields would concatenate as 'Hello World ' (with embedded blanks). %trim strips the leading and trailing spaces so the result is Hello World.

Operator Precedence

When an expression mixes operators, RPG evaluates them in a defined order. Exponentiation (**) binds tightest, followed by unary minus, then multiplication and division, then addition and subtraction, and finally the comparison and logical operators. Use parentheses to override the default order.

Create a file named precedence.rpgle:

**FREE
dcl-s result int(10);

// * binds tighter than +
result = 2 + 3 * 4;
dsply ('2 + 3 * 4   = ' + %char(result));   // 14

// Parentheses force addition first
result = (2 + 3) * 4;
dsply ('(2 + 3) * 4 = ' + %char(result));    // 20

// ** binds tighter than +
result = 2 ** 3 + 1;
dsply ('2 ** 3 + 1  = ' + %char(result));    // 9

*inlr = *on;

From highest to lowest precedence in RPG expressions:

  1. ** (exponentiation)
  2. unary - and +, NOT
  3. * and /
  4. binary + and -
  5. = <> < > <= >= (comparison)
  6. AND
  7. OR

Running on IBM i

RPG runs exclusively on IBM i — there is no open-source compiler and no Docker image is available, so these examples cannot be run on Linux, macOS, or Windows. If you have access to an IBM i system, compile and run each source file with CL (Control Language) commands. For example, to build and run arithmetic.rpgle:

1
2
CRTBNDRPG PGM(MYLIB/ARITH) SRCSTMF('/home/user/arithmetic.rpgle')
CALL PGM(MYLIB/ARITH)

Repeat for the other files (comparison.rpgle, assignment.rpgle, strings.rpgle, precedence.rpgle), changing the program name and source path. Options for getting IBM i access include the free public PUB400.COM system, IBM Power Virtual Server cloud instances, and IBM i Access Client Solutions.

Expected Output

Each dsply sends one message to the program message queue (shown plainly below; in a batch job log each line is prefixed with DSPLY).

arithmetic.rpgle:

a + b  = 22
a - b  = 12
a * b  = 85
a / b  = 3.400
%div   = 3
%rem   = 2
b ** 2 = 25

comparison.rpgle:

x is less than y
x is not equal to y
Can drive
All requirements met

assignment.rpgle:

After += 50: 150
After -= 30: 120
After *= 2:  240
After /= 4:  60

strings.rpgle:

Hello, World!
Hello World

precedence.rpgle:

2 + 3 * 4   = 14
(2 + 3) * 4 = 20
2 ** 3 + 1  = 9

Key Concepts

  • Free-form expressions replaced classic operation codes — total = a + b is the modern equivalent of fixed-format ADD, SUB, MULT, and DIV.
  • Equality uses a single =, and “not equal” is <>; the same = symbol serves for both assignment and comparison depending on context.
  • %DIV and %REM provide integer division and remainder — RPG has no % modulo operator.
  • The result field’s decimal positions control arithmetic precision, which is why business-grade packed decimals avoid floating-point rounding errors.
  • Compound assignment operators (+=, -=, *=, /=, **=) are free-form-only shorthand for updating a variable in place.
  • Logical operators are keywordsAND, OR, NOT — and indicators (ind) evaluate directly in conditions without comparing to *on.
  • + concatenates strings, and pairing it with %TRIM removes the blank padding inherent to fixed-length char fields.
  • Precedence runs ** → unary → * /+ - → comparison → ANDOR; use parentheses to make intent explicit.

Running Today

All examples can be run using Docker:

docker pull none
Last updated:

Comments

Loading comments...

Leave a Comment

2000 characters remaining