Enter RPN

R47: Looping
Login

R47: Looping

History

HP’s first RPN calculator was their 1968 HP-9100A/B, a desktop-bound beast. Even with all its might, it lacked a single-instruction looping method. Instead, it required the programmer to repeatedly pull a stored counter from a register onto the stack, where the program could test X against Y and use the result to effect a conditional GTO, but doubtless not until it stored the changed counter back where it got it.

HP tried several other alternatives in the following years:

These alternatives cost precious program steps, but that was okay because HP was happy to sell outboard core memory units, tape drives, and hard disks for these mini monsters.

In a classic case of constraints driving innovation, 1974’s HP-65 changed all that. This being their first programmable handheld, there wasn’t room for a QWERTY keyboard or all the wall-powered storage devices. They were forced to introduce to the RPN world the first modern single-instruction looping feature, DSZ. That, and naught else on that model.

Even then, it was a tentative move. The DSZ feature went MIA in the following year’s scaled-back HP-55, relegating its programmers to the looping limitations of the HP-9100. The feature did not reappear until the groundbreaking HP-67/97 pair came out, where DSZ was joined by the world debut of the complementary ISZ instruction. This then made its way down the line the following year in the HP-29C/19C.

Notice that we’re now in 1977, nearly a decade past the introduction of the HP-9100A, and we still have not seen what is now taken to be the foundational ISG/DSE formulation. That was not introduced until late 1979 in the fancy new HP-41C series, the R47’s oldest spiritual ancestor. Only ISG had a spot on the front panel; calling DSE required either going into alpha mode and typing it out, or picking it from the catalog, or assigning it to a User key. The HP-34C came out a few months later, with both ops on the front panel.

It took another few years for that op pair to drop into HP’s mid-range RPN line, with 1981’s groundbreaking HP-11C.

Foundations

We start in the R47’s 🟧 PRGM 🟧 LOOP menu, where we will remain until near the end of this article.

ISG

The Increment and Skip if Greater instruction (ISG) provides count-up logic in a single instruction. Its behavior is based on a given starting value, an ending value, and a step size. Consider this program, based on the one starting on p.153 of the HP-42S Owner’s Manual:

LBL ‘LOOP’
  1.010
  STO ‘COUNTER’

  LBL 01
    VIEW ‘COUNTER’
    PAUSE 02
    ISG ‘COUNTER’
      GTO 01
    ‘DONE’
  RTN

Over the space of about 2 seconds, that counts up from 1 to 10, then shows DONE on the stack.1

The key is in the setup value for that COUNTER variable, formatted as:

cccccccc.fffii

This packs three separate values into a single real-valued variable:

The initial counter part (cccccccc) can start out zero or negative.

Because the fff part is 010 in this example and the counter starts at 1, the loop iterates 10 times. You may input the starting COUNTER value as 1.01 in this example, but I added the trailing zero to make the meaning clearer.

Leaving off that final value (fff) part would cause the example program to finish shortly after execution hit ISG. The calculator would increment the starting 1 counter value to 2, find that this is indeed greater than the zeroed final value, and then skip the GTO 01 instruction, considering its work DONE.

DSE

The Decrement and Skip if Less-Than or Equal instruction (DSE)3 is the other foundational looping construct in HP-style RPN, one I find more useful because it makes counting down to zero easy. This then allows giving it a count of iterations as an integer, without needing to include an explicit ending value. Here is that same example recast in terms of DSE:

LBL ‘LOOP’
  10
  STO ‘COUNTER’

  LBL 01
    VIEW ‘COUNTER’
    PAUSE 02
    DSE ‘COUNTER’
      GTO 01
    ‘DONE’
  RTN

I don’t know about you, but I find that more readable, since I don’t need to think about the specially-formatted fractional part. The sole downside relative to ISG is that DSE is equivalent only in contexts where counting down gives the same result as counting up, as occurs in math with commutative operations. When it makes a material difference to count upward, you will find yourself pushed into the arms of ISG or the increment-based alternatives below.

The counter format for DSE is best conceptualized as:

cccccccc.fffdd

That is, the 2-digit step size value dictates how much to decrement the integer part on each iteration. The same 00 = decrement-by-1 rule applies here as for ISG.

See my Project Euler Problem 1 article for a case where count-down works better than count-up. This is because the core of the loop is based on addition, and because having a special fractional part would require integer truncation at every step.

Additions

Via its WP34s ancestry, the R47 gains four more looping instructions along these same lines:

Oddly, the 34s lacked the classic ISG/DSE ops. Those did not reappear until the WP43.

DSZ

This is functionally identical to DSE when the fff part is zero, but it differs in two key ways:

  1. The final value is always 0; it does not come from the (fff) part of the referent.
  2. The step size is always 1, irrespective of any dd part you may give.

This means that when you give it a real-valued counter like 10.9, it will not exit on the first test due to `10 < 900` but will instead iterate down to 9.9, then 8.9, and so forth until it reaches 0.9, where it truncates the counter and decides it has reached ”zero,” close enough.

These properties make DSZ more sensible when dealing with integer counters, since there is none of the fff=000 = dd=00 = 1 special-casing brought up above that the programmer must keep in mind. This doubtless is why HP chose to provide DSZ/ISZ on the HP-16C even though its family-mates the HP-11C and 15C featured the more powerful DSE/ISG pair: the 16C’s default mode operates on integers only. This in turn is why the inspiration to bring DSZ/ISZ into the WP34s came from the HP-16C, not via the older wedge-style handhelds where these instructions were actually born.

DSL

This is the same as DSE but with a single difference: the relation operator used in the test is `<`, not `<=`. That’s it.

ISE

Same situation as with DSL vs DSE, but with increment instead of decrement and with different relational operations.

The ISE skip condition check uses `=` between the counter and the final value, whereas ISG uses `>=`.

ISZ

This is the increment equivalent to DSZ; it increments by 1 until it hits zero, without treating the fractional part of the counter value specially.

With an implicit end target of 0, this means ISZ is best used when starting from a negative counter value.

Hand-Rolling It

The above operations are compact, expressing the core logic of a loop in a single R47 instruction. Sometimes you may find yourself needing to build your own out of primitives, however, and for this case, the 🟧 PRGM 🟧 LOOP menu also offers the INCR and DECR instructions. They take as arguments the same type of values as the instructions above, but they do not affect program flow. It is therefore up to you to add that.

An overly complicated way of expressing the DSE example is:

LBL ‘LOOP’
  10
  LBL 01
    VIEW X
    PAUSE 02
    DECR X
    𝑥>? 0.
      GTO 01
    ‘DONE’
  RTN

Getting FORTHy

One of the many attempts to improve on the above situation was by HP, in their ambitious RPL redesign of RPN. A common criticism of RPL is that it overcomplicates things that did not need to be complicated, and for this reason, I created RePIG, a simpler way of getting the same basic effects. I will leave it to you to decide if this:

«
  1 10 FOR ‘COUNTER’
    VIEW ‘COUNTER’
    PAUSE 02
  NEXT
» ‘LOOP’ STO
‘DONE’

…is an improvement on the ISG example that led this article off.

(Spoiler: It is not 100% equivalent.)

(You may now wish to return to my R47 article index.)

License

This work is © 2026 by Warren Young and is licensed under CC BY-NC-SA 4.0


  1. ^ The original took ~10 seconds since its PSE instruction is fixed at a 1-second delay, and it had to lean on its weak alpha register feature to show the completion message via an AVIEW instruction. The formatting rejig applies to the examples given in this article also has the benefit of making clear which instructions are in do-if-true context and thus might be skipped depending on the logic state of the prior instruction. The GTO 01 above is one such, indicated by being indented under the ISG test.
  2. ^ Otherwise, it would increment by 0 each time, creating an infinite loop.
  3. ^ Often mischaracterized as Decrement and Skip if Equal, though that is not how it actually behaves, as may be seen when the final value (fff) is greater than the starting value. Try DSE on 10.9 if you wish to see that only one iteration occurs, since the initial test is `(10-1) <= 900`, thus true, triggering the skip. If instead it was checking `(10-1) = 900` it would have to decrement until it ran past the integer underflow limit to get back to the desired final value of 900!