09-15-2014, 11:22 PM (This post was last modified: 09-16-2014 01:34 AM by Jeff_Kearns.)
Post: #1
 Jeff_Kearns Member Posts: 147 Joined: Dec 2013
The "Cadillac Quadratic Solver" by Palmer O. Hanson, Jr. for the HP-33s seems like a straight-forward port to the HP-32Sii. Simply replace as follows:

HP33S: B0015 SGN with HP-32Sii: B0015 x<0?; B0016 -1; and B0017 1.

The program works well on the 33S (haven't tried it on the 35S yet) but does not perform as well on the 32Sii when comparing the test case results with those posted at the bottom of the article. Of the eight test cases in the article, I get two incorrect results: test cases '1' and '6' only have one correct root, and there is a minor variation on test case '7'. I can't figure out the problem.

Isn't the replacement code for SGN above applicable? I have double-checked the code and that is the only difference between the 32Sii and 33S programs.

Thanks,

Jeff K
09-15-2014, 11:32 PM
Post: #2
 Paul Dale Senior Member Posts: 1,491 Joined: Dec 2013
(09-15-2014 11:22 PM)Jeff_Kearns Wrote:  HP33S: B0015 SGN with HP-32Sii: B0015 x<0?; B0016 -1; and B0017 1.

These two do different things.

This sequence might work better:
Code:
x<0? -1 x>0? 1

Although the stack action is somewhat different.

Pauli
09-15-2014, 11:55 PM (This post was last modified: 09-16-2014 12:02 AM by Jeff_Kearns.)
Post: #3
 Jeff_Kearns Member Posts: 147 Joined: Dec 2013
(09-15-2014 11:32 PM)Paul Dale Wrote:  This sequence might work better:
Code:
x<0? -1 x>0? 1
Pauli

Same behaviour...
Interestingly, it solves rather difficult equations correctly like: a = 4,877,361,379, b = -9,754,525,226, c = 4,877,163,849, that give Re = 0.999979750 ; Im = 2.8995463E-10 as answers, but not a simple one like 5x² + 6x + 1 = 0. Instead of x = -0.2 or x = -1, I get x = 0.2 or x = -1.66666667.

--- Jeff
09-16-2014, 12:03 AM
Post: #4
 Gerson W. Barbosa Senior Member Posts: 1,199 Joined: Dec 2013
(09-15-2014 11:55 PM)Jeff_Kearns Wrote:
(09-15-2014 11:32 PM)Paul Dale Wrote:  This sequence might work better:
Code:
x<0? -1 x>0? 1
Pauli
Same behaviour... --- Jeff

I would suggest

ABS
LASTx
x=0?
x!
/

Assuming SGN(0) = 0 on the hp 35s, which I haven't checked.

Gerson
09-16-2014, 12:06 AM
Post: #5
 Jeff_Kearns Member Posts: 147 Joined: Dec 2013
(09-16-2014 12:03 AM)Gerson W. Barbosa Wrote:  I would suggest
ABS
LASTx
x=0?
x!
/

Gerson

Same result... -- Jeff
09-16-2014, 12:22 AM
Post: #6
 Gerson W. Barbosa Senior Member Posts: 1,199 Joined: Dec 2013
(09-16-2014 12:06 AM)Jeff_Kearns Wrote:
(09-16-2014 12:03 AM)Gerson W. Barbosa Wrote:  I would suggest
ABS
LASTx
x=0?
x!
/

Gerson

Same result... -- Jeff

Notice your code keeps the argument on the stack. Perhaps you should get rid of it ( x<>y Rv ). Depending on how the stack is being used, this might not help either.
09-16-2014, 12:31 AM
Post: #7
 Paul Dale Senior Member Posts: 1,491 Joined: Dec 2013
(09-16-2014 12:22 AM)Gerson W. Barbosa Wrote:  Notice your code keeps the argument on the stack. Perhaps you should get rid of it ( x<>y Rv ). Depending on how the stack is being used, this might not help either.

This is like the problem. The code snippet from the original article is:

Code:
B0015 SGN B0016 X B0017 + B0018 STO J B0019 x<>y B0020 /

Leaving rubbish in Y isn't good at step B0020.

- Pauli
09-16-2014, 12:43 AM (This post was last modified: 09-16-2014 12:44 AM by Jeff_Kearns.)
Post: #8
 Jeff_Kearns Member Posts: 147 Joined: Dec 2013
(09-16-2014 12:31 AM)Paul Dale Wrote:
(09-16-2014 12:22 AM)Gerson W. Barbosa Wrote:  Notice your code keeps the argument on the stack. Perhaps you should get rid of it ( x<>y Rv ). Depending on how the stack is being used, this might not help either.

This is like the problem. The code snippet from the original article is:

Code:
B0015 SGN B0016 X B0017 + B0018 STO J B0019 x<>y B0020 /

Leaving rubbish in Y isn't good at step B0020.

- Pauli
Found the following archived discussion but the suggested workarounds starting at message #8 do not work either... What gives?

Jeff
09-16-2014, 12:59 AM
Post: #9
 Gerson W. Barbosa Senior Member Posts: 1,199 Joined: Dec 2013
(09-16-2014 12:43 AM)Jeff_Kearns Wrote:
(09-16-2014 12:31 AM)Paul Dale Wrote:  This is like the problem. The code snippet from the original article is:

Code:
B0015 SGN B0016 X B0017 + B0018 STO J B0019 x<>y B0020 /

Leaving rubbish in Y isn't good at step B0020.

- Pauli
Found the following archived discussion but the suggested workarounds starting at message #8 do not work either... What gives?

Jeff

The ENTER instruction (LSTx in my suggestion) makes the content of the stack register T to be lost, unlike the original SGN function. Any SGN replacement you choose should preserve the stack.
09-16-2014, 01:02 AM
Post: #10
 Paul Dale Senior Member Posts: 1,491 Joined: Dec 2013
RE: Cadillac Quadratic Solver behaving like an Edsel - Assistance requested with SGN
(09-16-2014 12:43 AM)Jeff_Kearns Wrote:  What gives?

You'll probably have to track the code through and examine the stack usage at each step.

- Pauli
09-16-2014, 01:07 AM
Post: #11
 Jeff_Kearns Member Posts: 147 Joined: Dec 2013
RE: Cadillac Quadratic Solver behaving like an Edsel - Assistance requested with SGN
(09-16-2014 01:02 AM)Paul Dale Wrote:  You'll probably have to track the code through and examine the stack usage at each step.
- Pauli
Agreed. But where's Thomas Klemm when I need him?? He's a master at stack-tracking. -- Jeff
09-16-2014, 01:20 AM
Post: #12
 Gerson W. Barbosa Senior Member Posts: 1,199 Joined: Dec 2013
RE: Cadillac Quadratic Solver behaving like an Edsel - Assistance requested with SGN
You can try
RCLx F
RCL F
ABS
/

RCLF
SGN
x

starting at step B0014, assuming F is never zero.
09-16-2014, 01:33 AM
Post: #13
 Jeff_Kearns Member Posts: 147 Joined: Dec 2013
RE: Cadillac Quadratic Solver behaving like an Edsel - Assistance requested with SGN
(09-16-2014 01:20 AM)Gerson W. Barbosa Wrote:  You can try
RCLx F
RCL F
ABS
/

RCLF
SGN
x

starting at step B0014, assuming F is never zero.

WOW Thanks Gerson! I can't say I readily follow the logic (will have to think about it...) and I end up with two consecutive /'s but it works like a charm now. What, therefore, is the 'general' substitute for SGN on a 32sii? Might make for a separate thread/article.

Jeff K
09-16-2014, 02:24 AM
Post: #14
 Gerson W. Barbosa Senior Member Posts: 1,199 Joined: Dec 2013
(09-16-2014 01:33 AM)Jeff_Kearns Wrote:
(09-16-2014 01:20 AM)Gerson W. Barbosa Wrote:  You can try
RCLx F
RCL F
ABS
/

RCLF
SGN
x

starting at step B0014, assuming F is never zero.

WOW Thanks Gerson! I can't say I readily follow the logic (will have to think about it...) and I end up with two consecutive /'s but it works like a charm now. What, therefore, is the 'general' substitute for SGN on a 32sii? Might make for a separate thread/article.

Jeff K

Although it works for all test cases, I fear it won't work when B is zero. In this case the following might be a fix:

RCL*F
RCL F
ABS
x=0?
x!
/

Notice this is not the replacement for SGN, rather for RCL F SGN x.

Gerson.
09-16-2014, 02:49 AM
Post: #15
 Paul Dale Senior Member Posts: 1,491 Joined: Dec 2013
This subroutine should substitute for SGN, change register Z to something you're happy to lose.

Code:
        LBL S         x=0?         x^2             Get Last X correct for a zero input         x=0?         RTN             Finished with zero input         R^         STO Z           Save T in a register         Rv         ABS             |x| / x is SGN(x) for x not zero         Last X         /         R^              Now restore T from the register         CLx             Disable stack lift         RCL Z         Rv         RTN             Finished

This routine doesn't damage the stack and returns with the correct result and the correct value in Last X. I'm sure someone will be able to improve this.

Then replace SGN with XEQ S in you program.

Pauli
09-16-2014, 09:38 AM
Post: #16
 Jeff_Kearns Member Posts: 147 Joined: Dec 2013
Thanks Pauli and Gerson
Jeff
09-16-2014, 11:26 AM
Post: #17
 Didier Lachieze Senior Member Posts: 1,143 Joined: Dec 2013
(09-16-2014 02:49 AM)Paul Dale Wrote:  This subroutine should substitute for SGN, change register Z to something you're happy to lose.

Code:
        LBL S         x=0?         x^2             Get Last X correct for a zero input         x=0?         RTN             Finished with zero input         R^         STO Z           Save T in a register         Rv         ABS             |x| / x is SGN(x) for x not zero         Last X         /         R^              Now restore T from the register         CLx             Disable stack lift         RCL Z         Rv         RTN             Finished

A little shorter, using a user flag instead of register Z, same stack & Last X management:

Code:
S01   LBL S S02   CF 4    Clear flag 4 S03   x<0? S04   SF 4    Set flag 4 if X < 0 S05   ABS     Set lastX S06   x=0? S07   RTN     If X = 0 stop there, SGN(0)=0 S08   CLx     Disable stack lift S09   1       Prepare answer SGN(X) = 1 S10   FS? 4    S11   +/-     If X was negative, SGN(X) = -1 S12   CF 4    Clear flag 4 S13   RTN
09-16-2014, 11:46 AM
Post: #18
 Paul Dale Senior Member Posts: 1,491 Joined: Dec 2013
(09-16-2014 11:26 AM)Didier Lachieze Wrote:  A little shorter, using a user flag instead of register Z, same stack & Last X management:

Nice effort. I knew it could be improved.

Another step forward would be to preserve the flag as well by using an extra label and another subroutine level:

Code:
LBL T FS? 4 GTO S GSB S CF 4 RTN

And change the sign function to always set flag 4 at the end instead of clearing it.

Pauli
09-16-2014, 11:56 AM
Post: #19
 Didier Lachieze Senior Member Posts: 1,143 Joined: Dec 2013
(09-16-2014 11:46 AM)Paul Dale Wrote:  Another step forward would be to preserve the flag as well by using an extra label and another subroutine level:

[...]

And change the sign function to always set flag 4 at the end instead of clearing it.

Good idea!

Otherwise if you're ready to loose register Z (or another one), you can do even shorter with:
Code:
S01   LBL S S02   STO Z S03   ABS S04   x=0? S05   RTN S06   STO/ Z S07   X<> Z S08   RTN
09-16-2014, 12:33 PM
Post: #20
 Dieter Senior Member Posts: 2,398 Joined: Dec 2013
(09-16-2014 01:20 AM)Gerson W. Barbosa Wrote:  You can try
RCLx F
RCL F
ABS
/

RCLF
SGN
x

starting at step B0014, assuming F is never zero.

If I understand correctly, the sequence

RCL F
SGN
x

shall be replaced by something that does not require a sign function and that also does not use more than one stack level. Your suggestion will do so, but the combination of a multiplication and a subsequent division may degrade accuracy, and, more important, it will not work for F = 0.

RCL F
ABS
X≠0?
RCL/ F
x

Dieter
 « Next Oldest | Next Newest »

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