Every IF, DOW, DOU, and WHEN in RPGLE depends on the same underlying thing: a boolean condition built from comparisons and, often, AND/OR logic. IBM documents that the result of a comparison, or of an AND/OR operation, is a value of type indicator.1 That indicator is the same true/false currency the rest of the language consumes. Writing that condition well is a separate skill from choosing the control structure around it.
This is a reference article. It does not re-teach IF/ELSE/ELSEIF, SELECT/WHEN, or guard-clause control flow — those are covered elsewhere in this series. It covers the comparison and logical-composition rules those structures rely on, and how to keep compound conditions readable as they grow.
Quick Summary
- A comparison such as
onHandQty < reorderPointproduces an indicator result: true or false.1 - RPGLE’s relational operators are
=,<>,>,>=,<, and<=.1 ANDrequires every operand to be true;ORrequires at least one operand to be true.1- Parentheses have the highest precedence in an expression and are always evaluated first.2
- Without explicit parentheses, relational operators bind tighter than
AND, andANDbinds tighter thanOR.2 - Neither of IBM’s documented operator references specifies short-circuit evaluation for RPG expressions; this article makes no such claim.
- A negative condition (
<>) is sometimes clearer than a positive one, and sometimes the reverse — the deciding factor is which phrasing matches the business question. - Naming a compound condition’s parts, and grouping them explicitly, keeps a correct expression readable.
Reader Prerequisites
This reference assumes you can already read the conditions and controlled blocks from RPGLE IF, ELSE, and ELSEIF Decisions (ARTICLE-064). That article owns IF/ELSEIF/ELSE/ENDIF syntax; this one owns the comparisons and logical composition written inside the condition.
It complements RPGLE Nested Decisions and Guard Clauses (ARTICLE-066), which addresses how to arrange several decisions for readability once the conditions themselves are written. The broader sequence is collected in RPGLE for Beginners: A Practical IBM i Learning Path (ARTICLE-046).
Learning Outcomes
By the end, you should be able to:
- Name RPGLE’s relational operators and state that a comparison produces an indicator result.
- Write equality, inequality, and ordering comparisons across common typed operands.
- Combine conditions with
ANDandORand state their documented relative precedence. - Use parentheses deliberately instead of relying on default precedence to be “obviously right.”
- Choose between a positive and a negated condition based on readability, not habit.
- Recognize comparison mistakes that compile cleanly but mislead a reader.
- Refactor a dense compound condition into named intermediate conditions without changing its outcome.
What a Boolean Condition Does in RPGLE
A boolean condition in RPGLE is an expression that evaluates to an indicator value. IBM’s ILE RPG expression reference states this directly: the result of any comparison operation, or of an AND or OR operation, is a value of type indicator.1 That indicator result is what IF and the other conditioning operations consume — IBM documents IF as accepting an indicator expression and controlling its block when that expression is true.3
That framing matters because it separates two questions that are easy to blur:
- Is the condition correct? Does it compute the right true/false value for every input you care about?
- Is the condition readable? Can a maintainer confirm that without re-deriving the logic from scratch?
A condition can be entirely correct and still be a maintenance risk if its grouping, negation, or operator choice makes the reader do unnecessary work. The rest of this reference works through both concerns.
Comparison Patterns
RPGLE’s relational operators compare two operands and produce an indicator result:1
| Operator | Meaning | Example |
|---|---|---|
= | Equal | itemStatus = 'A' |
<> | Not equal | itemStatus <> 'A' |
> | Greater than | onHandQty > reorderPoint |
>= | Greater than or equal | orderTotal >= 100.00 |
< | Less than | onHandQty < reorderPoint |
<= | Less than or equal | orderAmount <= creditLimit |
Each operator works the same way regardless of the operand types involved, as long as the operands are comparable — character codes, numeric quantities, and packed amounts all use the same six symbols. A comparison can be used directly inside a conditioning group, or its result can be captured first:
dcl-s isBelowReorderPoint ind;
isBelowReorderPoint = (onHandQty < reorderPoint);
if isBelowReorderPoint;
return 'reorder-required';
endif;
Capturing the result in a named indicator field does not change what the comparison computes. It gives the value a business name before it is used, which becomes more valuable as conditions combine. The complete member is basic-comparison-patterns.rpgle. It checks an item’s status and stock position with <>, =, and <, and its initialized inputs produce reorder-required.

Combining Conditions
A single comparison often is not enough to express a business rule. RPGLE combines comparison results with AND and OR, and IBM defines both directly in terms of indicator operands.1
AND Logic
AND returns true only when both of its operands are true.1 Use it when a rule genuinely requires every condition to hold:
qualifiesExpedite = isExpedited and (loyaltyTier = 'G');
qualifiesExpedite is true only when the order is marked expedited and the customer’s loyalty tier is 'G'. Either condition failing makes the whole expression false.
OR Logic
OR returns true when at least one of its operands is true.1 Use it when any one of several conditions is sufficient:
qualifiesTier = (loyaltyTier = 'G' or loyaltyTier = 'S');
qualifiesTier is true if the tier is 'G', 'S', or both comparisons happen to match — OR does not require exclusivity, only that at least one side is true.
Grouping Compound Conditions
Combining AND and OR in the same expression makes default precedence matter. IBM’s operation-precedence reference places parentheses first, then places relational operators above AND, and AND above OR.2 Concretely, from highest to lowest for the operators used in this article: parentheses, relational operators (=, <>, >, >=, <, <=), AND, then OR.
That ordering means an ungrouped expression does not read left to right the way prose does:
// AND binds tighter than OR, so this is:
// (orderTotal >= 100.00 and loyaltyTier = 'G') or loyaltyTier = 'S'
qualifiesFreeShipping = orderTotal >= 100.00 and loyaltyTier = 'G' or loyaltyTier = 'S';
A customer with tier 'S' qualifies regardless of orderTotal, because the OR sits outside the AND grouping by default — probably not the intended rule. Writing the grouping explicitly makes the intended rule the only rule the expression can express:
qualifiesFreeShipping = (orderTotal >= 100.00) and (loyaltyTier = 'G' or loyaltyTier = 'S');
Since parentheses have the highest precedence and are always evaluated first, this version cannot be misread the way the ungrouped one can.2 The complete member is compound-boolean-conditions.rpgle; with its initialized inputs it returns eligible-standard.

Positive and Negative Conditions
The same rule can usually be written as a positive check or its negation:
if custStatus = 'A';
// active-customer path
endif;
if custStatus <> 'A';
// not-active-customer path
endif;
Neither form is universally correct. A positive check (= 'A') reads naturally when the block that follows is the case you are primarily explaining. A negative check (<> 'A') reads naturally when the block is a guard against an exceptional case — “if the customer is not active, stop” is closer to how that rule is usually described out loud.
NOT is available for negating an indicator directly rather than restating a comparison.1 Prefer the direct relational operator (<>) over not (x = y) when one exists; it is shorter and does not ask the reader to mentally invert a comparison. Reserve NOT for negating an already-named condition, such as not isEligible, where restating the underlying comparison would be redundant.
Avoid stacking negatives. if not (custStatus <> 'A') is logically identical to if custStatus = 'A', but it forces the reader to cancel out two negations to find that out. If a condition needs a NOT in front of another negative comparison, rewrite it as a direct positive comparison instead.
Readable Comparison Patterns
- Give a compound condition’s parts business names (
isWithinCreditLimit,qualifiesFreeShipping) before combining them, especially once more than oneAND/ORis involved. - Group with parentheses even in places where default precedence would already produce the correct grouping. The cost is a few characters; the benefit is that the reader never has to check the precedence table.
- Prefer a direct relational operator over a negated comparison wrapped in
NOTwhen one exists (<>instead ofnot (x = y)). - Keep each comparison free of side effects, so reading a condition never requires wondering what it changed.
- Order the operands in a comparison to match how the rule is normally described (
onHandQty < reorderPoint, not the reverse), so the comparison reads like the sentence a business user would say. - When a compound condition grows past two or three comparisons, name intermediate results instead of extending one expression further.
These are editorial recommendations for keeping correct code easy to re-verify. None of them are IBM language rules, and none of them change what a given expression computes.
Worked Examples
readable-condition-refactor.rpgle puts a dense compound condition next to a named-condition equivalent for the same order-approval rule:
// Dense
if (custStatus = 'A' and orderAmount <= creditLimit)
or (custStatus = 'A' and isManagerOverride);
return 'approve-order';
endif;
// Named
isActiveCustomer = (custStatus = 'A');
isWithinCreditLimit = (orderAmount <= creditLimit);
hasManagerOverride = isManagerOverride;
if isActiveCustomer and (isWithinCreditLimit or hasManagerOverride);
return 'approve-order';
endif;
The two conditions compute the same result for every input. That follows from ordinary boolean algebra rather than any RPG-specific behavior: (A and W) or (A and O) is the same expression as A and (W or O), because AND distributes over OR. Reading the named version does not require noticing that distribution. isActiveCustomer gates everything, and the OR clearly offers two ways to satisfy the remaining requirement.
| Customer active | Within credit limit | Manager override | Dense result | Named result |
|---|---|---|---|---|
| Yes | Yes | No | approve-order | approve-order |
| Yes | No | Yes | approve-order | approve-order |
| Yes | No | No | hold-order | hold-order |
| No | Yes | Yes | hold-order | hold-order |
With the member’s initialized inputs ('A', 450.00, 500.00, override off), both procedures display approve-order. In this workspace the members are documentation-reviewed rather than compiled or executed on IBM i; the table is an intended-behavior check, not captured runtime evidence.
Common Mistakes
Relying on default precedence for a mixed AND/OR expression. a and b or c does not group the way it reads in prose. Group explicitly whenever both operators appear in the same expression.2
Assuming short-circuit evaluation. Neither the 7.5 nor the 7.4 expression-operator or precedence references document that RPG stops evaluating a compound condition once its result is already determined. Keep every comparison in a compound condition free of side effects, and do not depend on evaluation order.
Wrapping a comparison in NOT instead of using the direct operator. not (x = y) and x <> y compute the same result, but the second is shorter and does not require the reader to invert anything.
Double-negating a condition. not (x <> y) is x = y; write the positive form directly.
Comparing operands that do not represent the same fact. A comparison compiles as long as the operands are comparable types — it does not verify that comparing them means anything. Checking orderAmount <= creditLimit is meaningful only if both values are already in the same unit and currency.
Repeating a comparison already implied by an enclosing guard. If an outer IF already established custStatus = 'A', re-checking it inside is redundant and suggests the two blocks are not as related as they look.
Treating a comparison result as anything other than true or false. The result of a comparison, or of AND/OR, is a value of type indicator — not a count, not a numeric difference.1
How This Fits IF, SELECT, and Guard-Clause Logic
This article supplies the vocabulary that the rest of the decision-logic series consumes. RPGLE IF, ELSE, and ELSEIF Decisions (ARTICLE-064) uses an indicator expression to choose a block. The comparisons and AND/OR composition described here are how that expression gets built.
RPGLE Select and When Logic (ARTICLE-065) evaluates a series of WHEN conditions in order. Each condition is typically a comparison like the ones in this reference.
RPGLE Nested Decisions and Guard Clauses (ARTICLE-066) is about arranging several conditions for readability. Named, well-grouped conditions written using this reference’s patterns are what makes a guard clause easy to verify at a glance.
None of those articles’ control-flow syntax is re-taught here, and this article does not choose among IF, SELECT/WHEN, or guard-style exits on your behalf — it only covers how to write the condition once you know which structure you need.
FAQ
What type of value does an RPGLE comparison return?
An indicator value — true or false. IBM’s expression-operator reference states that the result of any comparison operation, or of AND/OR, is a value of type indicator.1
Does RPG use EQ, NE, GT, and similar alphabetic comparison codes?
Those forms belong to earlier fixed-form RPG. This reference covers the symbolic relational operators (=, <>, >, >=, <, <=) documented for free-form expressions.1
Does AND bind tighter than OR in RPGLE?
Yes. IBM’s operation-precedence reference ranks relational operators above AND, and AND above OR, with parentheses always evaluated first.2 Group mixed AND/OR expressions explicitly rather than relying on that order being obvious to a reader.
Does RPG short-circuit AND/OR evaluation?
Neither the IBM i 7.5 nor 7.4 expression-operator and operation-precedence references document short-circuit evaluation for RPG expressions. This article makes no claim about evaluation order, and its examples keep every comparison free of side effects so the question does not matter for their correctness.
Is NOT the same as using <>?
For a direct comparison, prefer <> — it is shorter and does not require negating a positive comparison mentally. NOT is documented as negating an indicator operand and is more useful for negating an already-named condition.1
When should I name an intermediate condition instead of writing one long expression?
Once a compound condition combines more than two or three comparisons, or mixes AND and OR, naming the parts (as in readable-condition-refactor.rpgle) usually costs little and makes the rule easier to re-verify later.
Key Takeaways
- A comparison, or an
AND/ORcombination, produces an indicator result in RPGLE.1 - The relational operators are
=,<>,>,>=,<, and<=.1 - Parentheses have the highest precedence; without them, relational operators bind tighter than
AND, andANDbinds tighter thanOR.2 - No IBM reference used here documents short-circuit evaluation for RPG expressions; do not depend on one.
- Choose a positive or negative condition based on which phrasing matches the business question, not by default.
- Naming and explicitly grouping compound conditions preserves correctness while making the rule easier to re-verify.
- This reference supplies condition-writing patterns for ARTICLE-064, ARTICLE-065, and ARTICLE-066; it does not replace any of their control-flow guidance.
Continue Your Learning
- Pillar: RPGLE for Beginners: A Practical IBM i Learning Path (ARTICLE-046)
- Foundation: RPGLE IF, ELSE, and ELSEIF Decisions (ARTICLE-064)
- Related: RPGLE Select and When Logic (ARTICLE-065)
- Related: RPGLE Nested Decisions and Guard Clauses (ARTICLE-066)
- Current: RPGLE Boolean Logic and Comparison Patterns (ARTICLE-067)
- Recommended next: RPGLE DO Loops Explained (ARTICLE-068)
ARTICLE-068 is named from the canonical cluster registry but is intentionally not linked because this repository does not yet provide a publishable destination for it.
IBM Evidence Used
The IBM i 7.5 ILE RPG expression reference documents the relational operators (=, <>, >, >=, <, <=) and the logical operators AND, OR, and NOT, and states that the result of any comparison or AND/OR operation is a value of type indicator.1 The operation-precedence reference documents that parentheses have the highest precedence and are always evaluated first, and that relational operators rank above AND, which ranks above OR.2 The IF reference is reused only for the contextual point that IF consumes an indicator expression.3
The IBM i 7.4 expression-operator and operation-precedence topics were cross-checked for the same operator definitions and precedence order.45 No publication date is assigned to any IBM Docs page. Neither reference documents short-circuit evaluation; this article makes no such claim. The recommendations about naming, grouping, and choosing between positive and negative conditions are editorial guidance from this tutorial, not IBM language rules.
References
IBM, Expression Operators, IBM i 7.5, accessed 2026-09-12. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
IBM, Operation Precedence, IBM i 7.5, accessed 2026-09-12. ↩↩↩↩↩↩↩↩
IBM, IF (If), IBM i 7.5, accessed 2026-09-12. ↩↩
IBM, Expression Operators, IBM i 7.4, accessed 2026-09-12. ↩
IBM, Operation Precedence, IBM i 7.4, accessed 2026-09-12. ↩
References
- Expression Operators — IBM
- Operation Precedence — IBM
- IF (If) — IBM
- Expression Operators — IBM
- Operation Precedence — IBM