HP Forums
(32S) Accurate TVM with direct solutions - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Software Libraries (/forum-10.html)
+--- Forum: General Software Library (/forum-13.html)
+--- Thread: (32S) Accurate TVM with direct solutions (/thread-3871.html)



(32S) Accurate TVM with direct solutions - Dave Britten - 05-17-2015 12:55 AM

Total size: 183 bytes

This TVM solver uses direct solutions to compute n, PV, PMT, and FV. Solutions for i% must be obtained using the built-in numeric solver. The multiple direct solutions account for its size, although common expressions have been moved to subroutines where possible. Results are obtained very quickly by using direct solutions.

Most of the math in this program is based on discussion in this thread.

Usage
Store values in appropriate registers:
N - n (Number of periods)
I - i% (Periodic interest rate, NOT i%/yr)
P - PV (Present value)
M - PMT (Payment)
F - FV (Future value)

Set flag 0 for begin period payments, or clear for end period payments.

Execute the desired routine to compute the remaining variable:
XEQ N - Compute n
XEQ I - Compute i% (Periodic interest rate, NOT i%/yr)
XEQ P - Compute PV
XEQ M - Compute PMT
XEQ F - Compute FV

Use XEQ V to view/input the TVM variables interactively. Press R/S to cycle through variables. Omit this label if you don't need this feature, and wish to use STO/VIEW directly.

Example:
31536000 STO N
10 RCL N / STO I
0 STO P
0.01 CHS STO M
CF 0
XEQ F

Result: 331,667.006689

Code:
V01 LBL V - 010.5, 5FF1
V02 INPUT N
V03 INPUT I
V04 INPUT P
V05 INPUT M
V06 INPUT F
V07 GOTO V

N01 LBL N - 022.5, 72C8
N02 XEQ D
N03 RCL* M
N04 RCL+ P
N05 1/x
N06 RCL P
N07 RCL+ F
N08 +/-
N09 *
N10 XEQ L
N11 XEQ C
N12 XEQ L
N13 /
N14 STO N
N15 RTN

I01 LBL I - 006.0, 277C
I02 FN= Q
I03 SOLVE I
I04 RTN

P01 LBL P - 016.5, A973
P02 XEQ K
P03 RCL* M
P04 XEQ D
P05 *
P06 RCL+ F
P07 XEQ J
P08 /
P09 +/-
P10 STO P
P11 RTN

M01 LBL M - 016.5, C07D
M02 XEQ J
M03 RCL* P
M04 RCL+ F
M05 XEQ K
M06 XEQ D
M07 *
M08 /
M09 +/-
M10 STO M
M11 RTN

F01 LBL F - 016.5, B348
F02 XEQ K
F03 RCL* M
F04 XEQ D
F05 *
F06 XEQ J
F07 RCL* P
F08 +
F09 +/-
F10 STO F
F11 RTN

C01 LBL C - 009.0, B7DD
C02 RCL I
C03 2
C04 10^x
C05 /
C06 RTN

D01 LBL D - 009.0, 494A
D02 XEQ C
D03 1/x
D04 XEQ B
D05 +
D06 RTN

B01 LBL B - 007.5, 8973
B02 0
B03 FS? 0
B04 10^x
B05 RTN

L01 LBL L - 022.5, FA05
L02 ENTER
L03 ENTER
L04 1
L05 +
L06 LN
L07 x<>y
L08 *
L09 LASTx
L10 1
L11 +
L12 1
L13 -
L14 /
L15 RTN

J01 LBL J - 009.0, B0C2
J02 XEQ C
J03 XEQ L
J04 RCL* N
J05 e^x
J06 RTN

K01 LBL K - 021.0, 8759
K02 XEQ C
K03 XEQ L
K04 RCL* N
K05 2
K06 /
K07 STO T
K08 e^x
K09 2
K10 *
K11 RCL T
K12 SINH
K13 *
K14 RTN

Q01 LBL Q - 016.5, F432
Q02 INPUT I
Q03 XEQ D
Q04 XEQ K
Q05 *
Q06 RCL* M
Q07 XEQ J
Q08 RCL* P
Q09 +
Q10 RCL+ F
Q11 RTN



HP 35s - TVM from Gene Wright - PedroLeiva - 12-03-2015 12:39 PM

Here a TVM program for HP 35s adapated from the original of Gene Wright (1997). It does not calculate interest rate.
Includes program steps, instructions and examples
Pedro

EDIT: I changed the attachment because a minimum error in the instructions


RE: (32S) Accurate TVM with direct solutions - Jeff_Kearns - 12-26-2015 11:24 PM

Dave,

In a previous discussion in March 2014, Thomas Klemm recommended that you follow the links to find a formula in Miguel Toro's post about a program for the HP 35s.

Instead of the 13 Label, 122-line program you posted, I would recommend this short (extremely ACCURATE) 38 line program that only uses 1 label, which is essentially Miguel Toro's program for the 35s...

T001 LBL T
T002 INPUT N
T003 INPUT I
T004 INPUT B
T005 INPUT P
T006 INPUT F
T007 INPUT E
T008 RCL I
T009 100
T010 /
T011 ENTER
T012 ENTER
T013 1
T014 +
T015 LN
T016 x<>y
T017 LASTx
T018 1
T019 X<>Y? !x not equal to y?
T020 -
T021 /
T022 *
T023 RCL* N
T024 e^x
T025 RCL* B
T026 LASTx
T027 1
T028 -
T029 RCL* P
T030 RCL I
T031 100
T032 /
T033 1/X
T034 RCL+ E
T035 *
T036 +
T037 RCL+ F
T038 RTN

Usage: Select Function (FN= T), then SOLVE for the unknown variable (N, I, B, P, or F). The program prompts for other variables, and E is for Begin/End mode - where E=0 is END MODE.

Jeff Kearns


RE: (32S) Accurate TVM with direct solutions - Dieter - 12-30-2015 08:22 AM

(12-26-2015 11:24 PM)Jeff_Kearns Wrote:  Instead of the 13 Label, 122-line program you posted, I would recommend this short (extremely ACCURATE) 38 line program that only uses 1 label, which is essentially Miguel Toro's program for the 35s...

Jeff, please take a look at the thread title: it says "Accurate TVM with direct solutions". That's the point here: Except the routine for the interest rate (which cannot be calculated directly) Dave's program returns the results immediately by direct calculation – no solver and no iterations required, and the user also does not have to provide two initial guesses.

Maybe the program even is a tiny bit more accurate since it seems to include implementations of both an ex–1 and a ln(1+x) function, while the version you suggested only does the latter.

So both versions have their benefits. Yours is very short and compact while Dave's is faster and returns directly calculated results immediately.

Dieter


RE: (32S) Accurate TVM with direct solutions - Dave Britten - 12-30-2015 12:13 PM

(12-30-2015 08:22 AM)Dieter Wrote:  
(12-26-2015 11:24 PM)Jeff_Kearns Wrote:  Instead of the 13 Label, 122-line program you posted, I would recommend this short (extremely ACCURATE) 38 line program that only uses 1 label, which is essentially Miguel Toro's program for the 35s...

Jeff, please take a look at the thread title: it says "Accurate TVM with direct solutions". That's the point here: Except the routine for the interest rate (which cannot be calculated directly) Dave's program returns the results immediately by direct calculation – no solver and no iterations required, and the user also does not have to provide two initial guesses.

Maybe the program even is a tiny bit more accurate since it seems to include implementations of both an ex–1 and a ln(1+x) function, while the version you suggested only does the latter.

So both versions have their benefits. Yours is very short and compact while Dave's is faster and returns directly calculated results immediately.

Dieter

Right, this one is built for speed (which is often important when making quick financial decisions). As such, it makes quite a few sacrifices on size. I do have a one-label solver-based version kicking around for when I only need to run a few numbers, and don't want to type in a large program. Or better yet, I just grab my 17BII. Smile


RE: (32S) Accurate TVM with direct solutions - Jeff_Kearns - 12-30-2015 03:05 PM

(12-30-2015 12:13 PM)Dave Britten Wrote:  
(12-30-2015 08:22 AM)Dieter Wrote:  Dave's program returns the results immediately by direct calculation – no solver and no iterations required, and the user also does not have to provide two initial guesses.

Maybe the program even is a tiny bit more accurate since it seems to include implementations of both an ex–1 and a ln(1+x) function, while the version you suggested only does the latter.

So both versions have their benefits. Yours is very short and compact while Dave's is faster and returns directly calculated results immediately.

Dieter

Right, this one is built for speed (which is often important when making quick financial decisions). As such, it makes quite a few sacrifices on size. I do have a one-label solver-based version kicking around for when I only need to run a few numbers, and don't want to type in a large program. Or better yet, I just grab my 17BII. Smile

Gents ~

While I applaud Dave for including his 'direct solutions' program, I have to disagree with a number of statements you each made. First of all, the accuracy of the 38-line, single-label SOLVER program is on par with that of any financial calculator. It includes both functions (e^(x–1) and ln(1+x)) to which you refer. Just test it with the example in the 15C Advanced Function Handbook, repeated here, or with any other TVM problem.

"...and the user also does not have to provide two initial guesses": Believe it or not, this is not (or perhaps seldom) required with the solver program. It works just fine without ever providing initial guesses - except perhaps if one is trying to torture test the program with an extremely high 'N' or a very, very small 'I'.

"...Dave's program returns the results immediately": You mean after entering all the variables (unprompted), and looking up which of the routines to execute? If you find waiting a second or two for an answer to a TVM problem, 'on the fly', onerous, then I have no comment. FYI, when solving Dave's example, above - I get the same answer in less than one second.

"So both versions have their benefits...Dave's is faster and returns directly calculated results immediately": Dave's 13 label, 122 line program has no practical advantages whatsoever. It is not faster to use at all (especially when you have to set flags...), uses up almost all the available memory, and still requires the solver for interest rate calculations. The calculator has a SOLVER; it is meant to be used!

"...I do have a one-label solver-based version kicking around for when I only need to run a few numbers, and don't want to type in a large program": I think you should type in the 38-line program and test it. You will see that it meets all your TVM needs, especially speed and accuracy ;-).

Jeff


RE: (32S) Accurate TVM with direct solutions - Dieter - 12-31-2015 12:23 PM

(12-30-2015 03:05 PM)Jeff_Kearns Wrote:  While I applaud Dave for including his 'direct solutions' program, I have to disagree with a number of statements you each made. First of all, the accuracy of the 38-line, single-label SOLVER program is on par with that of any financial calculator. It includes both functions (e^(x–1) and ln(1+x)) to which you refer.

Jeff, I see there is code for a ln(1+x) function (line T008 ff.), but I cannot find something similar for an e^x–1 function (NB: not e^(x-1), as you posted). Line T026 ff. simply takes the e^x result and subtracts 1 from it. ;-)

That's why the solver program will produce errors for very small interest rates. For instance consider this example:

N = 10
I  = 1E–5 %
B = 0
P = 1
E = 0
F = ?

Since the interest rate is nearly zero, solving for F correctly returns F=–10,0000045 (i.e. ten times the 1,- payment plus with virtually nothing on top because of a near-zero interest rate). Fine.

Now replace "I" with 1E–15% and see what you get... The solver will return F=0, which is obviously wrong. This happens because in step T026 the e^x command returns 1 and the following subtraction of 1 yields exactly zero. This is exactly what a dedicated e^x–1 command avoids.

"But that's not a real world problem, nobody deals with interest rates that low". Well, the solver program is not able to handle zero interest rates (this causes a division by zero), so using a near-zero interest rate like 1E–20 or 1E–50 is required to handle this case. And here is where the current solver code fails.

(12-30-2015 03:05 PM)Jeff_Kearns Wrote:  I think you should type in the 38-line program and test it. You will see that it meets all your TVM needs, especially speed and accuracy ;-).

Well... not quite. ;-)

Addendum:
Here is a version that includes both ln(1+x) – using a different method that IHMO performs even better than the original one – as well as an e^x–1 implementation and some slight general improvements.

Code:
T001 LBL T
T002 INPUT N
T003 INPUT I
T004 INPUT B
T005 INPUT P
T006 INPUT F
T007 INPUT E
T008 1
T009 RCL I
T010 %
T011 +
T012 ENTER
T013 ENTER
T014 LASTx
T015 x<>y
T016 1
T017 -
T018 -
T019 x<>y
T020 ÷
T021 LASTx
T022 LN
T023 +
T024 RCLx N
T025 ENTER
T026 e^x
T027 RCLx B
T028 x<>y
T029 2
T030 ÷
T031 e^x
T032 LASTx
T033 SINH
T034 x
T035 ENTER
T036 +
T037 RCLx P
T038 100
T039 RCL÷ I
T040 RCL+ E
T041 x
T042 +
T043 RCL+ F
T044 RTN

This code implements this method for ln(1+x) and that one for e^x–1.

Dieter


RE: (32S) Accurate TVM with direct solutions - Dave Britten - 12-31-2015 01:37 PM

Just for comparison's sake, this is the one-label solver version that I keep in my pocket 32S notebook "just in case". It's a couple steps longer than Dieter's; I don't know if there are any meaningful differences between the two.

Code:

LBL T
INPUT N
INPUT I
INPUT P
INPUT M
INPUT F
INPUT B
2
10^x
RCL/ I
RCL+ B
RCL I
2
10^x
/
ENTER
ENTER
1
+
LN
x<>y
*
LASTx
1
+
1
-
/
STO L
RCL* N
2
/
STO T
e^x
2
*
RCL T
SINH
*
*
RCL* M
RCL L
RCL* N
e^x
RCL* P
+
RCL+ F
RTN



RE: (32S) Accurate TVM with direct solutions - Dieter - 12-31-2015 01:49 PM

(12-31-2015 01:37 PM)Dave Britten Wrote:  Just for comparison's sake, this is the one-label solver version that I keep in my pocket 32S notebook "just in case".

Are you sure this code is correct? What does the RCL L do – this variable is not used anywhere else.
Edit: it seems that L is supposed to hold ln(1+i), but this value is not calculated anywhere in this program.

And why don't you just use 100 instead of 2 10^x resp. 200 ÷ instead of 2 10^x ÷ 2 ÷...? ;-)
Also, there is no need for a temporary register T during the e^x–1 calculation as x/2 is saved in LastX.

Dieter


RE: (32S) Accurate TVM with direct solutions - Jeff_Kearns - 12-31-2015 02:04 PM

Dieter,

You are correct! I failed to modify the code for the Pioneers after correcting the same mistake in my HP-15 code. It now uses using the more accurate e^x-1 formula: 2 * sinh(x / 2) * e ^ (x / 2).

Corrected 43-line code for Accurate TVM in HP-32S / HP-32sii / HP-33s / HP-35S

T001 LBL T
T002 INPUT N
T003 INPUT I
T004 INPUT B
T005 INPUT P
T006 INPUT F
T007 INPUT E
T008 RCL I
T009 100
T010 /
T011 ENTER
T012 ENTER
T013 1
T014 +
T015 LN
T016 x<>y switch x with y
T017 LASTx
T018 1
T019 X<>Y? x not equal to y?
T020 -
T021 /
T022 *
T023 RCLx N
T024 ENTER
T025 e^x
T026 RCLx B
T027 x<>y
T028 2
T029 /
T030 SINH
T031 LASTx
T032 e^x
T033 x
T034 2
T035 x
T036 RCLxP
T037 100
T038 RCL/I
T039 RCL+E
T040 x
T041 +
T042 RCL+F
T043 RTN

It now solves correctly for the VVL (very, very, low ;-) interest rate example you gave.

Regards,

Jeff Kearns

Dieter wrote:
Addendum:
Here is a version that includes both ln(1+x) – using a different method that IHMO performs even better than the original one – as well as an e^x–1 implementation and some slight general improvements.

I missed that post of yours but presume that my program, being one step shorter than yours, is OK.


RE: (32S) Accurate TVM with direct solutions - Dave Britten - 12-31-2015 02:08 PM

(12-31-2015 01:49 PM)Dieter Wrote:  
(12-31-2015 01:37 PM)Dave Britten Wrote:  Just for comparison's sake, this is the one-label solver version that I keep in my pocket 32S notebook "just in case".

Are you sure this code is correct? What does the RCL L do – this variable is not used anywhere else.
Edit: it seems that L is supposed to hold ln(1+i), but this value is not calculated anywhere in this program.

And why don't you just use 100 instead of 2 10^x resp. 200 ÷ instead of 2 10^x ÷ 2 ÷...? ;-)
Also, there is no need for a temporary register T during the e^x–1 calculation as x/2 is saved in LastX.

Dieter

Whoops, I mis-transcribed it in my haste. I'll correct it above.

The 100 vs. 10^2 thing is a peculiarity of the way the 32S stores numbers. Integers from 0-99 take up 1.5 bytes. Anything else is 9.5 bytes. So 100 is 9.5 bytes, whereas 2 10^x is only 3 bytes.


RE: (32S) Accurate TVM with direct solutions - Dieter - 01-01-2016 02:11 PM

(12-31-2015 02:08 PM)Dave Britten Wrote:  Whoops, I mis-transcribed it in my haste. I'll correct it above.

It still isn't perfect. The ln(1+x) code does not work for very small arguments where 1+x rounds to 1. In this case x+1–1 becomes zero and the following division throws an error. That's why the original (Kahan) code included a x≠y? test.This consumes one more stack level, but it doesn't hurt as the initial calculation of 100/I + B can be done later so this value does not have to be saved on the stack.

In general, there is no need for any temporary registers (here T and L), all this can be done on the stack.

(12-31-2015 02:08 PM)Dave Britten Wrote:  The 100 vs. 10^2 thing is a peculiarity of the way the 32S stores numbers. Integers from 0-99 take up 1.5 bytes. Anything else is 9.5 bytes. So 100 is 9.5 bytes, whereas 2 10^x is only 3 bytes.

I see. But still 10 x^2 is faster than 2 10^x, and there also is a percent function that returns x/100 with a simple 1 %. ;-)

Edit:
I could not believe the 0...99 limit, so I wanted to know what the 32s II manual says. Here is what I found on page 12-20/21:
"Numbers use 9.5 bytes, except for integer numbers from 0 through 254 which use only 1.5 bytes".

There you are: you can safely use "100" and "200" in your program and they still won't require more than 1.5 bytes.

Addendum:
Here is what I got – I hope there are not too many errors. ;-)

Code:
LBL T
INPUT N
INPUT I
INPUT P
INPUT M
INPUT F
INPUT B
1
RCL I
%
+
LastX
x<>y
LN
x<>y
LastX
1
x≠y?
-
/
x
RCL* N   ' = n * ln(1+i)
2
/
e^x
LastX
SINH
x
ENTER
+         ' = e^(n * ln(1+i)) - 1  =  (1+i)^n - 1
ENTER
RCL* P
RCL+ P    ' = pv * [(1+i)^n - 1] + pv =  pv * (1+i)^n
x<>y
RCL* M    ' = pmt * [(1+i)^n - 1]
100
RCL/ I
RCL+ B
x         ' = pmt * [(1+i)^n - 1] * (1/i + b)
+         ' + pv * (1+i)^n
RCL+ F    ' + fv
RTN       ' = tvm

At least it's shorter than the previous version (42 lines) and does not require any additional registers.

Dieter