![]() |
HP41C: Factorial (kind of) in MCODE - Printable Version +- HP Forums (https://archived.hpcalc.org/museumforum) +-- Forum: HP Museum Forums (https://archived.hpcalc.org/museumforum/forum-1.html) +--- Forum: Old HP Forum Archives (https://archived.hpcalc.org/museumforum/forum-2.html) +--- Thread: HP41C: Factorial (kind of) in MCODE (/thread-222851.html) |
HP41C: Factorial (kind of) in MCODE - Frido Bohn - 05-24-2012 This is a routine in MCODE I developed to overcome the situation that an HP41C can only calculate factorials of up to 69 as this is <10^100. 08D "M" This little FOCAL program renders a legible result in decimal representation, which however cannot be used for further calculations: Listing of FOCAL program "XFACT" 01*LBL "XFACT" I entered a set of numbers and calculated the factorial using XFACT at normal speed and 50x turbo on a 41CL. XFACT was compiled and transferred to HEPRAM. XFACT 1x Speed 50x Speed Result A linear regression resulted in RR of >0.9999 and the 1x-speed slope was about 48-fold larger than the 50x-speed slope. By elimination of the overhead (y-axis intersection), supposedly the key read out and output onto display of about 1 second, I got a 49.5-fold difference of the slope which matches pretty exactly 50x TURBO. Disclaimer: This code may be used at your own responsibility. I will not be responsible for any kind of inconveniences caused by its use. Re: HP41C: Factorial (kind of) in MCODE - Ángel Martin - 05-25-2012 Way to go Frido, you should post it as an article as well.
I noticed you use the "hard-coded" Ln(2) in the final division step. One alternative could've been calling [LN10] with "2" in C, shorter code but of course a tad slower. 04E C=0 ALL 'Clear C Since the result of [LN10] is also available as 13-digit form, this method would allow a 13-digit division next - done as multiplication by its inverse:
239 ?NC XQ This is an interesting way to overcome inherent limitations of the numeric range in the 41. There are a few other great examples in JM-Baillard's pages, you and others may be interested to check them out: http://hp41programs.yolasite.com/factorial.php
Cheers,
Edited: 25 May 2012, 5:29 a.m.
Re: HP41C: Factorial (kind of) in MCODE - Frido Bohn - 05-25-2012 Dear Ángel, 377 JC -12 'End of loop, see my posting The solution you offered by calculating the inverse (1/x) of ln(10) and multiplying would of course work too. However, an interesting, but also annoying point about the entry points of HP41 MCODE routines is that one cannot simply figure out where the operands have to be put in. For example, the 1/x function (->188E, [ON/X13]) wants its argument in CPU register B, for the multiplication (->184F, [MP1_10]) these are A and C, and for divide (->106F, [DIVIDE] or [/]) the dividend is in A and the divisor is in N. Then you have to consider where the result will be delivered. Sometimes directly into the stack (this is the case with [DIVIDE]), but also into C only from where you have to do an additional step to write it into the stack. This is not very straightforward, and I wish there would be documentation about this. Also, the preparation of the registers before feeding a function costs a lot of code, so that one has to consider about using an HP41 routine or if it would result in less code designing your own routine. I will put this contribution with a few extensions into the articles section, as you suggested. Re: HP41C: Factorial (kind of) in MCODE - Ángel Martin - 05-25-2012 Believe me, I'm quite far from being a MCODE guru - not an appropriate term, I can hardly read 50% of the OS code without stumbling! W.r.t. the input/output conventions for the MATH routines, I think reading the 13-digit writeup I did some time ago will help - available at TOS. http://hp41.claughan.com/file/13-digit%20OS%20Routines.pdf The first distinction is whether you're using 10-digit or 13-digit forms, then it all falls logically. Sorry I got it wrong, of course it's not Ln(2). In fact there's one entry point in the OS that returns Ln(10) in 13-digit form to register B - so you could just call it:
2B5 ?NC XQ Here using [ON/X13] is just a work-around to keep the 13-digit form of Ln(10). There are a couple of examples about that in the mini-paper. Keep up the good work! ÁM
Edited: 25 May 2012, 10:02 a.m.
Re: HP41C: Factorial (kind of) in MCODE - Frido Bohn - 05-25-2012 Ángel, 2B5 ?NC XQgives ln(10)*10^-6 as a result in B. If 239 ?NC XQis executed directly thereafter the result is 1/ln(10). 1/ln(10) multiplied with a natural logarithm results in the corresponding decadic logarithm (log). It appears that HP designed the [LNC10*] function for this purpose. Thus, log would be calculated primarily by the code for the natural logarithm. This confirms my previous observation that a sum of log is less precise than a sum of ln. Obviously, because the error of the conversion adds up in a chain. Thank you for the link. I will dive into your document and see which new insights it will give to me. Saludos Frido
Re: HP41C: Factorial (kind of) in MCODE - Frido Bohn - 05-25-2012 Quote:
What a fool I am, this was a 13-digit precision ln(10). Re: HP41C: Factorial (kind of) in MCODE - Ángel Martin - 05-26-2012
Quote: exactly! it´s a little confusing at the beginning but once you get the knack of it is actually easier than the 10-digit routines. In fact I´d go as far as saying that the math routines were designed to be 13-digit from the scratch, and the 10-digit truncation came later as the way to interact with the input/output values.
Have fun!
Re: HP41C: Factorial (kind of) in MCODE - Frido Bohn - 05-26-2012 Ángel, |