The HP48 Homepage  
 

 
News My Programs Software Programming Articles Links Sitemap Search Feedback    
   
 

Programming in User RPL - Conditional tests

One of the most powerful habilities of the HP is that programs can take decisions, and execute actions based on that decisions. Of course it can't, for example, choose a good wine for you, but it can recomend the type of wine based on the type of meat. This is what we call conditional, and what will be the object of study of this lesson. But before we start studing HP commands, let's study boolean algebra.

Trues, Falses, 0's and 1's

We'll now study some operations of logical data types. A logical may contain two values: False (zero) or True (non-zero, normally 1). The HP does not have special support for logicals, real numbers are used. A 0 is a False and any other value a True.

There are four basic operations with logicals: NOT, AND, OR and XOR. All of them are very important (except perhaps XOR, which is only important). Let's start by the easiest of them, NOT, and also the only unary one (takes only one argument.) In the HP it is represented by 'NOT a', but formely it is -|a. Basically, it inverts the value. A True becames a false, and vice-versa. See the table:

a-|a
01
1
0

Another operator is AND. It takes two arguments, and is represented by a^b (on the HP 'a AND b'). It returns True only if both a and b are true.

aba^b
000
010
100
1
11

The third function is OR. In HP form, it is 'a OR b', and formely it is aVb. It will return True if at least one of the inputs is true:

abaVb
000
010
100
1
11

And last, but not less important them the other, is XOR, eXclusive OR. It returns true if both inputs are different. You'll see 'a XOR b' on your HP, and ab on math books.

abaV_b
000
011
101
1
10

That was all. It didn't hurt, did it? But before really start the programming thing, let's see a little more theory.

Flags

A flag is like a reminder. If you had to remember to say, pick up dinner on the way home, you would do something to remeber you, like tie a string to your finger. OK, you would never do that, but that's a classical example situation, and I can't think of anything better to say at the moment.

Sometimes a program also needs to remember something. But a program can't tie string to his finger. Alas, a program doesn't have fingers. But since I hate anatomy lessons, let's stop that. So, what can he do to remember something?

One solution is to store a value in a variable that can later be compared to see what he needed to remember. A flag is like such variable. It can contain two values: set or clear. Like the true/false thing above, isn't it? Yes.

The HP has a little less than 64 flags that are reserved for its use. They are the system flags. You can change the value of them, like any other, but that yould change the form the HP operates. For example, system flag 40 (represented by -40 - positive flags will be seen later) contros the clock. Your program can use it, but if the value of the flag is changed, the clock visibility will also be changed.

Because of this, there is another kind of flag: the user flags. This 64 flags (represented by 1 to 64, the positive flags) aren't used by the HP. You can use them without any problem.

OK, but what can I do with the flags? Simple, instead of tying a string to your finger to remember to pick up dinner, set flag 4. Then, later, see if the flag is set. If it is set, then you must pick up dinner. A program does that, but to remember more important things (OK, I know your dinner is important to you, but the HP does not mind starving.)

There are several commands to work with flags. They set flags, clear flags, and check wheter they are set or not. Here they are:

CommandAction
SFSets the flag specified on level 1
CFClears the flag specified on level 1
FS?Returns 1 if the flag is set, else 0
FC?Returns 1 if the flag is clear, else 0
FS?CReturns 1 if the flag is set, else 0; also clears flag
FC?CReturns 1 if the flag is clear, else 0; also clears flag
RCLFPuts a list with the value of all flags on the stack
STOFSets the flags according to the list (generated by RCLF on the stack)

Basic Conditionals: IF ... THEN ... ELSE

The above commands let's you check whether a flag is set or not. Now, we need to do some action if it is set, and some other if not. Or, we want to do something in case a generic condition is met, and some other thing if not. That's what conditional structures are for. The simplest one is IF. It's form is:

    << IF test condition THEN
          actions to be taken if condition is true
       END
    >>
    

First, the HP will evaluate the test condition. If the result is true (ie, non-zero), then the commands between THEN and END will be executed. Otherwise, execution will continue after END.

This structure can be improved so that it can execute actions only if the test condition is false. The new form is:

    << IF test condition THEN
          actions to be taken if condition is true
       ELSE
          actions to be taken if condition is not true
       END
    >>
    

OK, in theory it's easy to understand. But in practice, how that happens? Basically, we use comparison commands. They are == (yes, to check equality you must use ==, and not only =). <, >, , and . There are no hidden meanings. They take one or two arguments from the stack, and return 1 if the condition is true, and 0 if false. Ready for THEN. You can use AND and the like to check multiple conditions.

Let's see a simple example of a program using IF structures. The program reads three numbers on the stack, and outputs the smallest of them.

    << -> a b c     @ Store the numbers in variables for easy acess
       << IF a b < a c < AND THEN
             a  @ If a is smaller than b and c, it's the wanted number
          ELSE
             IF b c < THEN
                b  @ If b is smaller than c, it's the number
             ELSE
                c  @ Otherwise, it's c
             END
          END
       >>
    >>
    

(Here, @ represents a comment. The rest of the line is ignored.

CASE Structures

Now, le'ts write a program that reads a number and outputs its name. Let's restrict it to numbers up to four, so that our program doesn't get too complicated.

    << -> x
       << IF x 1 == THEN
             "One"
          ELSE
             IF x 2 == THEN
                "Two"
             ELSE
                IF x 3 == THEN
                   "Three"
                ELSE
                   IF x 4 == THEN
                      "Four"
                   ELSE
                      "Other"
                   END
                END
             END
          END
       >>
    <<
    

The method used above works, but is quite unnefficient. There is a structure that makes this program more efficient: CASE. The program, rewritten with CASE, would be:

    << -> x
       << CASE
             x 1 == THEN
                "One"
             END
             x 2 == THEN
                "Two"
             END
             x 3 == THEN
                "Three"
             END
             x 4 == THEN
                "Four"
             END
             "Other"
          END
       >>
    >>
    

The form of the structure is:

    CASE
       test clause 1 THEN
          set of actions 1
       END
       test clause 2 THEN
          set of actions 2
       END
       .
       .
       .
       test clause n THEN
          set of actions n
       END
       default set of actions
    END
    

You can have any number of test clauses. When it evaluates True, the corresponding set of actions is executed until END and all the rest is skipped until another END. If it evaluates False, then the set of actions is skipped until the END and the next clause is evaluated. If none of the clauses evaluate True, then the default actions are taken. It isn't necessary to include a default set of actions.

Exercises

  1. What's the value of each of the following expressions?
    1. 010
    2. 110 0
    3. (11) (11)
    4. (1(1 (0 (01)))) (1 (0 1))
  2. Assuming a=0, b=1, c=1 and d=0, what is the value of the expressions?
    1. a(b)
    2. a( (bd))
    3. c(d (a(c (ad))))
    4. (bc) ( c (abc))
  3. Supposing a=127, b=10, c=5, d=0 and e=1, which value does each of the following statments give?
    1. d NOT
    2. d e AND
    3. a b > b c < OR
    4. a b < NOT
    5. d e AND a b == OR
    6. d e XOR a b < AND
    7. a b + c < d AND e XOR d NOT AND
    8. a b + c b / * 3 == a b OR NOT AND
  4. Which value will be returned when the this program is run?
    << 0 1 0 2.5 3.5 -> a b c x y
       << IF c x y + 5 > a NOT b AND OR OR THEN
             0
          ELSE
             1
          END
       >>
    >>
    
  5. Given the program below:
    << -> a b c
       << IF a THEN
             Command1
          ELSE
             IF b THEN
                IF c THEN
                   Command2
                ELSE
                   Command3
                   Command4
                END
             END
          END
          Command5
       >>
    >>
    
    1. Which commands will be executed if the stack contains 1, 1 and 0?
    2. Which commands will be executed if the stack contains 0, 1 and 0?
    3. What should be the values on the stack so that only Command5 is executed?
    4. Which commands will be executed if the stack contains 0, 1 and 1?
  6. After running this program, what will be output?
    << 32 2 5 -> a c h
       << a 5 XROOT c 3 4 / * -> b j
          << IF b j > THEN
                8 h 6 SQ c / / *
             ELSE
                a h a / + h -
             END
          >>
       >>
    >>
    
  7. Write a program that toggles the value of a flag (ie, if it is set it is cleared, and vice-versa) specified on level 1.
  8. Write a program that reads a flag number and a True/False from the stack. If it's a true, then it sets the flag, otherwise it clears.
  9. Write a program that reads three numbers from the stack and outputs them in crescent order.
  10. Write a program that, given the month, day and year, in this order, calculates the day of the week, and outputs it in a human form. Use the formula


    where
    • m is the month. January and February are months 11 and 12 of the previous year. March is month 1, and December is month 2.
    • d is the day of the month.
    • a are the two last digits of the year.
    • s are the two first digits of the year.
    • dw is the day of the day. Sunday is 0, Monday is 1 and so on.


Answers to exercises


Previous Page Next Page
 
 

This page was created by Eduardo M Kalinowski