# HP Forums

Full Version: Quadratic formula program help
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

I found this short program here:

Q001 LBL Q

Q002 CF 10

Q003 INPUT A

Q004 INPUT B

Q005 INPUT C

Q006 -B÷(2xA) <---the "divided by" symbol I input here seems to have been changed to a "?" by the forum's system

Q007 ENTER

Q008 ENTER

Q009 B^2-4xAxC

Q010 x>=0?

Q011 GTO Q017

Q012 +/-

Q013 sqrt ;press k key

Q014 i

Q015 x

Q016 GTO Q018

Q017 sqrt

Q018 2xA

Q019 ÷ <---the "divided by" symbol I input here seems to have been changed to a "?" by the forum's system

Q020 +

Q021 x<>y

Q022 LASTx

Q023 -

Q024 RTN

It keeps erroring out on line Q006. It seems to have a problem with using the negative/minus sign to make B negative in the line. I've tried everything I can think of. It runs fine after I remove the negative/minus sign from that line. How should I enter this line?

Also, line Q014 is just the the "i" key, right?

Thanks!

Edited: 14 June 2012, 11:46 p.m.

I'm no expert but I would suggest:

1- check syntax for the calc being used

2- maybe it needs apostrophes '-b/(2*a)'

3- be sure a not= 0 of course

Same may apply to other lines as well.

Hi there.

If you're writing an HP-35S app, my suggestion is to put 0i1 (keystrokes-- '0,' 'i,' '1') in line Q014 if you're trying to put the value of 1i (1 * 1) on the stack. I think just 'i' on line Q014 is what may be generating an execution or syntax error.

Secondly, for line Q006, the -B should be entered as using the +/- key as that is the negation function. Using the - key is only for the subtraction operation. So, to negate a value, the - symbol should be entered with the +/- key.

Edited: 15 June 2012, 1:35 a.m.

Thanks, Matt. All I had to do to make it work was use the +/- key for the negative sign. No other changes were necessary. Anyone know whey some of these quadratic equation solver programs are so long, but this one is tiny and works great (and even finds imaginary roots)?

I'm not sure why all these solvers are longer, however the 34S's is longer because it cares about numeric stability and avoids the cancellations inherent in the naïve formula. The 34S also uses complex multiplication to evaluate b^2 - 4ac in extra precision.

There have been several attempt to produce very short quadratic solvers. I don't remember the shortest anyone has produced, but it was very concise.

Palmer Hanson's Cadillac solver is instructive and has some nice examples at the end to validate your code with -- it is possible to get the correctly rounded answer to all of these with care.

- Pauli

My apologies to everyone. I neglected to specify that I am using a 35s, and so was asking about the programs for it...

But the reason I ask is because this program is very short compared to every other program for the 35s I've seen, that also found imaginary roots. (I've seen ones that didn't find imaginary roots that were short.) It's a single-function program, but it's goooood. My compliments to the author if he (you?) ever see this thread.

Quote:
There have been several attempt to produce very short quadratic solvers. I don't remember the shortest anyone has produced, but it was very concise.

The 16-step Quadratic Equation for the 42S in the Software Library is essentially Michael Harwood's very short quadratic solver for the HP-41C. Were the former labeled "Q" instead of "QUAD" it would be 26 bytes long (25 if the final RTN is replaced with END). Mine (Message #3 in this thread) is one step shorter and preserves the stack register X, but it is 28 bytes long.
Nothing beats SVLQ on the WP 34S, however :-)

Gerson.

Thanks. Just for the record, it's called SLVQ.

The 34S quadratic solver in full:

```		XLBL"QUAD"				/* Entry: QUADRATIC SOLVER */
xIN (xIN_ARGS(3, 3) | xIN_LASTX)
SSIZE4				/* Force the stack size to four levels */
RCL+ X				/* 2c b a . */
x[<->] Z			/* a b 2c . */
x=0?
ERR ERR_INVALID		/* Invalid arugment error */
RCL+ X				/* 2a b 2c . */
STO A
RCL Y				/* b 2a b 2c */
[cmplx][times]			/* b^2-4ac 2b(a+c) b 2c */
STO D
x<0?
[sqrt]				/* sqrt 2b(a+c) b 2c */
[<->] ZXTX			/* b sqrt 2c sqrt */
x[>=]0?
GSB cpx_conj
-				/* -b-sqrt 2c . . */
x[!=]0?
STO/ Y			/* -b-sqrt 2c/(-b-sqrt) 2c . */
RCL/ A				/* (b-sqrt)/2a 2c/(b-sqrt) 2c . */
z[<->] D			/* (b-sqrt)/2a 2c/(b-sqrt) b^2-4ac . */
xOUT xOUT_NORMAL
[sqrt]				/* sqrt ? b 2c */
RCL/ A				/* sqrt/2a ? b 2c */
RCL Z				/* b sqrt/2a ? b */
RCL/ A				/* b/2a sqrt/2a ? b */
+/-
SF Flag_complex
z[<->] D			/* b/2a sqrt/2a b^2-4ac b */
xOUT (xOUT_RET_SKIP | xOUT_NO_LASTY)
```

A total of 32 executable instructions five of which are dealing with the stack enter & exit so that this looks exactly like an internal command and two more are error handling. Not only is this algorithm competitive in terms of length, it is also numerically stable dealing with all of Palmer's test cases perfectly. This code is based on a quadratic solver for the 34S by Franz Huber, our original quadratic solver was not as sophicated.

- Pauli

Sorry for the typo. Won't happen agian!

Very nice piece of code! I especially like your clever use of the stack shuffle function, [<->]. This is one of the best features of this machine, I wish HP would have put this into their RPN calculators long ago, it's extremely powerful yet simple to use.

-Katie

The shuffle here is saving two instructions. e.g. x<>y DROP x<>y but I'm sure there are other sequences too.

Early on, I had a shuffle instruction that included L and shuffled XYZT and L. Probably better without the extra unnecessary complexity.

- Pauli

In late 2008 I was working with Rodger Rosenbaum on testing of quadratic solvers and wrote

Quote:
None of those cases [in the Cadillac writeup] actually test the capability to run 24 digits. I located the test case that I devised to test for 24 digits capability and ran it successfully. The details are:

a = 456,987,654,328 b = -913,975,308,642 c = 456,987,654,314

R1 = 1. ; R2 = 1 - 14/a = 0.9999999999693645...

Both the HP-33s and the HP-35s will display the solution as two equal roots of 1.000000000 in Fix 9, but use of the Show function will reveal that one of the roots is actually calculated as 0.999999999969

The discriminant for the standard quadratic formula is 196, but since the internal solution is made with the revised formula ax^2 - 2bx + c the discriminant calculated by these programs is 49 .

But I note that I never did add the test case to the article. Maybe that was an early indication of things to come where recently I was unable to remember that Grand Forks is in North Dakota not in Minnesota.

I was also doing some work with my TI-89 using the approximate and exact modes. Again, from some correspondence with Rodger:

Quote:
I have been doing a little work with my TI-89. If I enter

zeros(456987654328x^2+913975308642x+456987654314,x)

then in the approximate mode I get 9999999776328 and 1.00000022359 which is not correct. But in exact mode I get

228493827157/228493827164 and 1 which is correct.

I presume that the same thing can be done in the HP-49 and HP-50 which I believe also have exact mode.

So I conclude that machines which have exact mode don't need a special quadratic routine which will calculate an extended version of the discriminant. But for the other machines such as the HP-33s, HP-35s, HP-28 anf HP-48 whhich can't do exact calculations then one of the 24 digit discriminant calculation capabilities is appropriate.

It's the completeness of the shuffle function that I like. There are 256 combinations of stack arguments that a user might need and this instruction covers them all with a very readable syntax. Having L included in the mix is debatable as it's not really part of the stack. Did you not allow ABCD because the instruction would require 2 more bytes to encode?

A, B, C and D weren't part of the stack at the time.

- Pauli

Quote:
A, B, C and D weren't part of the stack at the time.

Hmmmh ... Anyway, the display does not feature sufficient pixels for a shuffle command <>XYZTABCD in full size.

And we don't have op-code space for eight or nine arguments :)

- Pauli

We would need 3 bits for each of the possible 8 destination positions, resulting in 24 bits as the argument. This is theoretically possible with the double length commands but there are restrictions which would make some combinations illegal. Walter has mentioned the argument entry and display restrictions which make an implementation complicated if not impossible. 128 KB of flash and the limited ASCII display are constraints we cannot overcome. (We've come a long way already.)