![]() |
|
|
|
AutoBahned
|
13 is not a lucky number...
but which of the 13 is the easiest to pgm in RPN? do that one first |
||
![]() |
|
Still here
|
The 42CV rules.
|
||
![]() |
|
Registered
|
I remember so little about calculator programming. But seems I should start with the most basic building block. For bond stuff, it would be present value of an arbitrary set of future cash flows (PV of CF), each cash flow defined by $ and # days from now, with discount rate r. Then you can calculate yield to maturity by generating cash flows and trying different r until PV CF = price. And yield to call/put and yield to worst similarly. By iterating PV CF you can also calculate duration and convexity. So seems like write a PV CF subroutine and a recursive goal seek subroutine, and use those over and over.
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? |
||
![]() |
|
AutoBahned
|
Just think about the stack - you push something onto it and everything else moves up a notch (until it falls off into a nihilistic death at #5)
then you enter an operator on the last 2 things in the stack above is based on my long ago memories which ended with a 41C |
||
![]() |
|
Back in the saddle again
Join Date: Oct 2001
Location: Central TX west of Houston
Posts: 55,752
|
Quote:
4x5+8x6= 4 5x (stack1) I think on my old calc, they'd call stack 1 and 2 (or was that really 3 and 4) x and y. Because there were buttons to do things to/with x and/or y including swapping them. 8 6x (stack1 and 20 moves to stack2) + (adds stack 1 and stack 2) It really clicked to me. It seemed genious and so much better than standard notation.
__________________
Steve '08 Boxster RS60 Spyder #0099/1960 - never named a car before, but this is Charlotte. '88 targa ![]() |
||
![]() |
|
Registered
|
Quote:
I also figured out, I think, that the program to be Solved doesn’t have to be a predetermined formula. It can be a process that leads to a number, and Solver can repeat that process until the number is zero. For the bond thing, I’ll need to enter as menu variables (MVARs): current date (DATE), maturity date (MAT), call date (CALL), face (FACE, or just default to 1000), coupon (CPN), coupons/yr (C/YR), price (PRIC). Write one program to get value if held to MAT and have Solver use that to find yield to maturity (YTM), another to get value if held to CALL and have Solver use that to find yield to call (YTC). Hopefully I won’t have to reenter the MVARs for each yield solution. I think I’m not going to fuss with variations on basis, just use 30/360. Just thinking out loud... The Free42 emulator allows simply typing the program in a text document on the computer, then copy/paste into the emulator to test. When its working, upload to the DM42 using USB. This should be faster than poking at the keys for dozens of lines.
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? |
||
![]() |
|
![]() |
Registered
|
My recollection is that MVAR's are retained in memory just like any other variable between solver runs.
You don't have to call the solver from another program. You might write a simple program (a^2 + b^2 = c^2) for trial and practice with the solver directly. |
||
![]() |
|
Registered
|
Quote:
The other cool thing about the DM42 is that it has a largish screen. One could potentially graph stuff. I don’t plan to but it’d be cool if I could figure out how to save an image that has instructions on how to use each program and is called by a HELP menu - not sure that’s doable but maybe. I think you should get one. They’re not particularly expensive. The keys are okay.
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? |
||
![]() |
|
Registered
|
I just might. I would use it mostly at work. I still have my HP42s (just don't take it to work anymore...)
|
||
![]() |
|
Registered
|
It is interesting programming this thing. The first thing I need to do involves dates. Take a bond maturing 7/15/2027 with semi-annual coupons, today’s date is 10/7/2020, what’s the next coupon date? How to get 1/15/2021? Well, it stores dates as MM.DDYYYY. So you have to decompose 07.152027 to 7, 0.15, and 0.002027, and 10.072020 to 10, .07, and 0.002020. Then create 07.152020 and test if 07.152020 is greater or less than 10.072020. If less, add six months. Which means add 06 to 07 = 13, test if > 12, if yes then subtract 06 from 07 = 01 and add 0.000001 to 0.002020 = 0.002021, create 01.152021 and test if that date is before or after 10.072020, and so on and so on. And also need to be able to handle quarterly or annual coupons, or zero coupons. The HP42S had no real date functions as far as I know. The DM42 has added a few date (and time) functions, but still kinda limited. https://thomasokken.com/free42/#doc I guess HP figured engineers don’t need to work with dates much?
You’re right about “ Math is a tool to gain insight to the problem - it's not just about the numbers...” and this is forcing me to actually learn the subject. I’m used to simply reading a number from a screen and even if I know what that number means, I don’t know - or have long since forgotten - how that number is determined.
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? Last edited by jyl; 10-07-2020 at 11:23 PM.. |
||
![]() |
|
Registered
|
As an ME, I never really ever had need to have a real-time clock or calc dates on my HP42s. Component life always got calc'd in number of stress reversals and then figure how many hours/days/years of service life from that. 365.25 days in a standard year...
I looked at the Free42 doc. I see that there is a mode to report time in YYYY.MMDD and I would think that easier to deal with (just how my head works). I would attempt to write logic in which you've entered either a start date or an end date, compute number of days to the event of interest, and then calc forward/back with the DDAYS and DATE+ functions. I wasn't aware those functions existed (but have now found them on Free42 that I run on my Android tablet). |
||
![]() |
|
Registered
|
Those Free42 functions will do most of what I need, I just need the equivalent of EDATE in Excel (add or subtract a given number of months, but keep the same day of the month) to deal with the Gregorian calendar in which from 04.142030 to 04.142020 isn’t actually 10*365 days, and going forward “6 months” from 10.022020 is 04.022020 not 03.312020 so 10.022020 180 DATE+ won’t work. That is needed to determine when the coupon dates are. Once that is known, DDAYS will work fine to get number of days to compound interest.
Interestingly, DOW will tell you the day of the week for any date, which suggests there must some calendar logic behind that function? It is supposedly based on the Time module of the HP41 but I don’t know how that worked. Oh wait, here is a possible process: https://artofmemory.com/blog/how-to-calculate-the-day-of-the-week-4203.html And https://en.m.wikipedia.org/wiki/Determination_of_the_day_of_the_week
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? Last edited by jyl; 10-08-2020 at 09:19 PM.. |
||
![]() |
|
Registered
|
Pricey
In 1973 or 74 my boss at the surveying company where I worked bought an HP calculator with scientific notation and one memory. Cost him about $325! Now, that was pricey! On a couple of occasions he let me use it to work on an engineering design project (college class) over the weekend.
__________________
FEC3 1980 911SC coupe "Zeus" 3.3SS god of thunder and lightning |
||
![]() |
|
Registered
|
Here's one way to figure out the same date of the month six months from now. Remember that the "date" value is just a regular decimal number within the calculator. This uses the IP (integral part) and FP (fractional part) functions from the original 42s instruction set. I'm also going to use the YYYY.MMDD date format (makes the calcs easier). This also assumes your date of the month is between ~6 and 28 (prevents rollover in February or getting into the previous month accidentally).
Store your starting date in reg 01 (or wherever) - I'm going to use 2020.1009 for the starting example. RCL 01 (2020.1009) 100 X (now you have 202010.09) FP (drops the stuff left of the decimal point yielding 0.09) 100 X (now you have 9.) STO 02 (your day of the month is stored in reg 02) RCL 01 (your original date again - 2020.1009) 180 DATE+ (now yields 2021.0407) 100 X (now you have 202104.07) IP (drops the fractional part and gives you 202104.) 100 X (now have 20210400.) RCL+ 02 (brings the day of the week back and adds to the stack and you have 20210409.) 10000 / (divide and get 2021.0409) STO 03 (and you've put the date in register 03) (You're welcome.) A more robust method would be to extract the month, add 6, test the result to see if it exceeds 12, add one to the year and adjust the month if it does, and then recompile the date code value. The native 42s instruction set has all kinds of "flag" functions for logical tests and can get messy. Another thought is to build yourself a matrix array of date data for your program and manipulate the years / months / days individually within the matrix stack. (Envision a matrix of 3 columns and x rows - assign each row a specific function/meaning - extract and manipulate individual elements of the matrix.) Looked at a couple of videos last night of the DM42. I don't NEED one (I have a real 42s and a real 41CX and I have Free42 on my tablet and PC) but I'm beginning to want one... Last edited by fanaudical; 10-09-2020 at 07:08 AM.. Reason: keep adding comments... |
||
![]() |
|
Registered
|
I decided I need a general program to add or subtract any number of months from any date, and am trying to do it with as few tests as possible, seems more efficient. Turns out that by using IP FP and MOD, you can minimize the number of tests.
I need to get better at using tests and the stack. Like if and only if [number in X register] is negative, I want to add 0.000001 to variable “YR2”. It feels like I need to pre-load 0.000001 in register Z and 0 in register Y, then have X<0? R down arrow R down arrow RCL+ “YR2” So if X<0, the stack rolls twice and 0.00001 is in the X register for the RCL+ command, but if X>=0, the stack only rolls once and 0 is in the X register for the RCL+ command. Is that a good way? Seems cumbersome! The examples in the manual all seem to resort to branching or subroutines after a test. It seems silly to do all that for such a teeny step.
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? Last edited by jyl; 10-09-2020 at 05:53 PM.. |
||
![]() |
|
Registered
|
To clarify for others (just in case), the program will only execute the one line immediately following the logic test if the logic test is true and will ignore it otherwise. That's why you see all the branching and subroutines in the program examples.
I'm not sure it that's a good way or not; in the past I always tried to minimize stack height and usually relied on manipulating registers to achieve something like that. It made it easier to control and I didn't have to worry about what was in the stack to start. |
||
![]() |
|
Still here
|
Math modules.
|
||
![]() |
|
Registered
|
Quote:
Maybe it doesn’t matter with the DM42 (or the HP42S). Back in the day I remember having to worry about resources. Of course, that was in the late 70s / early 80s and calculators were a lot slower.
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? |
||
![]() |
|
![]() |
Registered
|
My opinion - I'm guessing there are no serious implications regarding processing speed on a DM42 or within Free42. There were a couple tricks from "back in the day" on a real 42s that did affect memory and execution speed:
- Using the number registers didn't involve extra memory (those are fixed in memory whereas a custom named variable consumes additional memory). Probably not a problem with the DM42. My HP42s had "only" 7200 bytes of memory for programs/data storage. I usually used the upper range of numbered registers as scratch/temporary/working variables and transferred results to the custom-named variables at the end of the program. - Programs that use local labels and goto's run faster than branching to a subroutine or a label stored in another program. Keep the local label close to where you use it; it will search down from the point of the call looking for that label before it moves to the top. The 42s searches for global labels from the bottom of the program memory and moves up. Memory is a funny thing - I had forgotten about most of this stuff until this thread... |
||
![]() |
|
Registered
|
Thanks!
Man, I am feeling old and stupid. I just have a hard time keeping the stack and other registers straight in my head. I’ve actually built an Excel sheet that has columns for each stack level and each register, and rows for each line of code. As I type each line of code, I simulate the effect in the spreadsheet. This makes it fast to test the code and see what isn’t working. For no good reason I am still trying to do things by rolling the stack, LASTX, and so on. Anyway the date manipulation code is mostly working now. I can’t decide if I want to complicate it to deal with leap years and so on. Failing to do so will mean I’m potentially compounding a day or two more or less than the correct compounding period, which actually could be problematic.
__________________
1989 3.2 Carrera coupe; 1988 Westy Vanagon, Zetec; 1986 E28 M30; 1994 W124; 2004 S211 What? Uh . . . “he” and “him”? |
||
![]() |
|