Stack algorithm
07-12-2016, 12:36 PM
Post: #1
 deetee Junior Member Posts: 33 Joined: May 2016
Stack algorithm
Hello all!

To write a program that emulates a "real" HP-stack is more complicated than I thought - anyway I am convinced that the solution should be simple.

I don't want to bother you with C-code so I try to formulate my algorithm in common:

Code:
loop  read character key  if key is bigger than 0 and less than 9 than concatenate key to string and print it  else // no digit entered   if stringlength>0 x=atof(string) // convert string to register X   switch key    case ENTER: t=z z=y y=x // push stack if ENTER was pressed    case +: x=x+y y=z z=t // calculate operation and pull stack   print z,y,x   string=""

It doesn't work like on my HP35s.
When I have a value in X only and then press ie "2+" it overwrites the value in X.
Where is my mind mistake and how did it HP on most calculators?
Any improvement of my algorithm or a link to a simple program (I want to do it with an input-string) are highly welcome.

Regards
deetee
07-12-2016, 04:32 PM
Post: #2
 Namir Senior Member Posts: 591 Joined: Dec 2013
RE: Stack algorithm
I was in Vienna a few days ago. Missed meeting you! We could have talked about emulators. :-(

Namir
07-12-2016, 09:55 PM
Post: #3
 Paul Dale Senior Member Posts: 1,394 Joined: Dec 2013
RE: Stack algorithm
You need to implement a stack lift flag. Sometimes when you enter a new number you need to raise the stack before putting the value in X, other times you don't. You need a flag to distinguish the two cases. Enter disables stack lift on entry, + enables it.

Of course it is more complex than this.

This is a reside of a decision made in the early 1970's if not before because the calculators then didn't have enough RAM to store the number being entered separately -- instead they used the x register for this purpose.

- Pauli
07-13-2016, 02:28 AM
Post: #4
 Dwight Sturrock Member Posts: 122 Joined: Dec 2013
RE: Stack algorithm
Here are a few stack functions I wrote as part of a larger C++ program. The function names and comments are fairly self explanatory. My approach was fairly straightforward. I discovered there are many special cases that have to be accounted for when emulating RPN stack dynamics.

PHP Code:
void enter_pressed(bool *enter_was_pressed_)    {    t=z;    z=y;    y=x;    //x=x    write_stack();    *enter_was_pressed_=1;    //after an enter I should be able to overwrite x    }

PHP Code:
void add_pressed(bool *a_function_was_executed_, bool *decimal_fraction_)    {    //z=z    x=y+x;    //perform math first    y=z;    z=t;    *a_function_was_executed_=1;    //after a function is executed, stack lift must be enabled    *decimal_fraction_=0;            //since a function has been executed, we are back on the left side of the decimal point    write_stack();    }

PHP Code:
void space_pressed (bool *decimal_fraction_, bool *a_function_was_executed_, bool *enter_was_pressed_, bool *decimal_point_just_pressed_)        //space is the CLEAR STACK key    {        t=0;        z=0;        y=0;        x=0;        w=0;        place_value=10;        *decimal_fraction_=0;            //clear all flags:        *a_function_was_executed_=0;         *enter_was_pressed_=0;        *decimal_point_just_pressed_=0;        write_stack();    }

PHP Code:
void tab_pressed()    //tab is the CHS key    {    x=x*(-1);    write_stack();    }

PHP Code:
void roll_up_pressed(bool *a_function_was_executed_)    {    w=t;    t=z;    z=y;    y=x;    x=w;    *a_function_was_executed_=1;    //rolling the stack requires the a_function_was_executed flag to be set for proper stack lift    write_stack();    }
07-13-2016, 09:54 AM (This post was last modified: 07-13-2016 09:55 AM by Dieter.)
Post: #5
 Dieter Senior Member Posts: 2,176 Joined: Dec 2013
RE: Stack algorithm
(07-13-2016 02:28 AM)Dwight Sturrock Wrote:  Here are a few stack functions I wrote as part of a larger C++ program.

About 20 years ago I did something similar with an RPN calculator written in Pascal.

(07-13-2016 02:28 AM)Dwight Sturrock Wrote:  The function names and comments are fairly self explanatory. My approach was fairly straightforward. I discovered there are many special cases that have to be accounted for when emulating RPN stack dynamics.

It's not that complicated. Essentially it all boils down to the question whether stacklift is enabled or not. So a simple boolean variable "stacklift" will do. It is true after an operation or function call (except Σ+/Σ–) and false after ENTER and CLX. If a digit key (including dot/comma, CHS and EEX) is pressed, start a new number entry (resp. change sign) if stacklift is true resp. append to the current entry if not. Essentially, that's all you have to handle.

Dieter
07-13-2016, 02:13 PM (This post was last modified: 07-13-2016 02:28 PM by deetee.)
Post: #6
 deetee Junior Member Posts: 33 Joined: May 2016
RE: Stack algorithm
Thank you very much for this expert help and many hints (and even thanks for inviting to meet in Vienna to exchange ideas).

I really was desperated and felt close to the solution but couldn't reach. And to handle a stack the right way is probably tho most fundamental HP topic.

It makes much sense (or at least made it in the 70's) to save RAM and use the X-register to enable inputs - and use a one bit flag in addition (unfortunately my compiler uses one byte for a boolean variable).

Here is my C-code (on which I am going to build up) - note that SPACE (' ') emulates ENTER:
Code:
void loop() {key='\0'; key=inchar();  if(key>0)  {if((key>='0')&&(key<='9')||(key=='.')||(key==',')||(key=='E')||(key=='e'))   {if(key==',') key='.';    if(strlen(s)<STRLEN)     {strcat(s," "); s[strlen(s)-1]=key;}    display(s);   }   else //no digit entered   {if(strlen(s)>0)    {if(stacklift) {u=z; z=y; y=x; x=atof(s);}     else x=atof(s);     }    switch(key)    {case ' ': u=z; z=y; y=x; stacklift=false; break; // ENTER     case '+': x=x+y; y=z; z=u; stacklift=true; break; // operation    }    draw(x,y,z,fix);    s[0]='\0';   }  } }

Regards
deetee
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)