From the look of the tracking info, my 15c LE will be showing up this afternoon. I noticed from staring at photos of a 15c keyboard, that it's lacking Mod, nCr, and nPr functions, which I do use on a fair basis on my 48SX. Are there any good implementations of these functions for a 15c? I'd like something that will produce results without overflowing during an intermediate step if one of the inputs is relatively large (the 48SX will compute COMB(3000, 4) with ease, for example, and that won't fly with a naive implementation). Speed won't be an issue with the LE model, I presume. :)
15c: Need good programs for Mod, nCr, nPr
|
09-15-2011, 11:15 AM
09-15-2011, 11:20 AM
The 15c has them. Cy,x Py,x. "+" key.
09-15-2011, 11:44 AM
Ah, excellent. Can't believe I missed that. It appears I'm still in need of a Mod function, however.
09-15-2011, 01:22 PM
Here is a small 15C MOD routine that works if both arguments have the same sign. / LSTx x<>y FRAC * It was verified against 48GX results. If the signs of both arguments do not match, it does not return the correct result. If you are like me, and only use arguments of the sign sign, it will be fine. I suspect that a proper algorithm uses the Floor function, or something similar that is also not natively available on the 15C.
09-15-2011, 01:23 PM
HP-15C has INT(IP) and FRAC(FP). So, X MOD Y could be X-Y*IP(X/Y) (depending on modulo function definition).
09-15-2011, 01:53 PM
Yes. Only missing the MOD function which may be easy to program.
# -------------------------------------------- Thank you to Torsten for pointing me out to his HP-15C emulator (it makes easy to copy-paste program listing). Please note that this code use no register and leave the contents of t and z register intact in the stack (only moved down one step).
Edited: 15 Sept 2011, 2:30 p.m.
09-15-2011, 01:58 PM
Just found the Mod routine I made for the 32s/32sii (and had forgotten about). It's got the interesting quality that it preserves stack contents, and only needs one storage register. It's also a little more impervious to precision issues than the implementations that use FRAC *. This ought to work with only minimal conversion effort.
M01 LBL M Anybody want to take a stab at making it better?
09-15-2011, 02:43 PM
You'll need to FIX 0 first, e.g. 10 3 MOD is not 1, its .9999999999.
09-15-2011, 02:44 PM
Quote:# Note: accuracy is only a result of display rounding process !
001 LBL B This needs some simplification and stack preserving, but you've got the idea.
09-15-2011, 02:47 PM
LBL 0This will just subtract off until it cannot. Slow, but short, no registers, probably very fast on 15LE. y > x. Edited: 15 Sept 2011, 2:54 p.m.
09-15-2011, 03:11 PM
Very impressive demonstration of the beauty of RPN (and your knowledge of it).
09-15-2011, 03:21 PM
Quote: You are right, but FIX 4 may give in most cases the right integer result. Only FIX 9 may encounter a wrong result in rare occasions (like the one you give in your exemple). Since there is no STD display format, most FIX n may be OK with n less than 9.
09-15-2011, 03:29 PM
I came up with this one on the 32sii a long while back, it's not so obvious but is short and sweet and doesn't need more than the stack. for y mod x:
0 -Katie
Edited: 15 Sept 2011, 3:30 p.m.
09-15-2011, 03:39 PM
Hi, Yes, you are right, the first version of my code return an approximate y MOD x since it is not (or in rare situation) an integer, as expected. So, I propose a second version which returns the correct integer result as long as both arguments are both positives. My new version use one register to store a the small value eps = 5× 10-7 used to correctly round-up results. This eps constant have to be adjusted for larger result than 10000.
# --------------------------------------------USAGE : Initiate register R0 with a small positive value (i.e. 5× 10-7), Enter integer y and x into the HP-15 LE stack, Press [ f ][ A ] to run the code. The integer result y MOD x is return and displayed.
Edited: 15 Sept 2011, 4:07 p.m.
09-15-2011, 03:50 PM
Quote:
Really nice, thank you, much better thant the one I proposed !
# -------------------------------------------- But, don't try 789456123 MOD 9 on an original HP-15c, it's so loooooong for a really expected result !
Edited: 15 Sept 2011, 4:06 p.m.
09-15-2011, 04:31 PM
Quote:This is even a bit shorter: RCL YI hope the 32s has RCL Y and RCL/ Y, I don't know this calculator. ;-)
09-15-2011, 04:40 PM
Quote: I wish it did, but no it doesn't have those operations.
09-15-2011, 04:44 PM
Quote:That's strange, because in message #6 Dave has used STO T and RCL- T in a 32s program, so I couldn't imagine that such commands won't exist for register Y !?
09-15-2011, 04:52 PM
But your Y is stack Y. Dave's T is regular register T (of A-Z).
09-15-2011, 04:55 PM
Quote:Ahhh, now I got it: then this 32s doesn't have the usual 4 register stack XYZT !?
09-15-2011, 05:01 PM
Better use INT instead of FRAC, no need to round.
09-15-2011, 05:06 PM
Wow this is an unnecessarily confusing discussion. Let's call x,y,z,t the stack and the non-stack registers A, B, C, .... X, Y, Z. The routine I wrote uses the x,y,z,t stack registers only. The routine that Dave wrote uses the stack resisters plus register T. Although it preserves the stack registers, while mine does not. On the 32s/ii there are no STO/RCL functions that allow you directly address x,y,z,t like there are in the 42s, for example. Does that clear things up?
09-15-2011, 05:19 PM
Quote:
09-15-2011, 05:56 PM
Quote:
Well, maybe "queen" enough would be more appropriate!
09-15-2011, 06:03 PM
If I understand it correctly, 0 ENTER pushes a complex zero to X,Y and the arguments for mod to Z,T. The COMPLX+ just adds 0 to Z and 0 to T, placing the "sum" in X, Y without dropping Z and T. So the result of the operation is that you have the arguments twice on the stack. In RPL you would do DUP2 instead.
09-15-2011, 06:12 PM
Exactly how I think of it: 0, ENTER, CMPLX+ is the DUP2 operation, a function in RPL and often defined in Forth. I wish it would have been an RPN function too, I'd certainly use it more than roll-up.
09-15-2011, 06:26 PM
It is there on the 34S :-) - Pauli
09-15-2011, 08:48 PM
001 LBL A MOD(y,x) = x - y * Floor(x/y) Perhaps someone might want to do some optimization.
Edited: 15 Sept 2011, 8:55 p.m.
09-15-2011, 09:10 PM
Quote: You are right. Some Floor function implementations for the HP-32SII here. They might work on the HP-15C as well.
09-16-2011, 01:45 AM
Simply use CENTER on the WP 34S. And yes, it's RPN :-)
09-16-2011, 01:55 AM
Thanks for that guys! But I did say
Quote: I really needed this for the past 39 years, every since I had my HP-35.
09-16-2011, 02:10 AM
Quote: No problem! Set up a loop with the 34S AT (alter time) function. Decrement the current date until you reach the desired time, leave off a 34S (not the one you are using!) for your former self, and execute BTF (back to future.) There's very little RPN isn't capable of. :)
09-16-2011, 02:11 AM
Apologize I didn't have the knowledge then already d:-)
09-16-2011, 02:15 AM
No need for loops - the counterpart of BTF is ATP (Advance To Past, please see page -17 of the well known manual) :-)
Edit: Almost forgot - there's also a command Stay At Present time ;-) Edited: 16 Sept 2011, 2:28 a.m.
09-16-2011, 02:38 AM
Quote: How does that differ from the 41C stop time (STOPT) x function?
09-16-2011, 02:52 AM
AFAIK you cannot compare SAP with anything else ...
09-16-2011, 04:47 AM
Thank you Katie and Marcus. It’s now clear for me, and I realize that there is no chance that complex-calculus capabilities of the HP-15c will help there.
Katie’s code translate to RPL will be same sort of : « DUP2 / IP * -» Here follow illustration of the various clever stack moves induce by RPN and RPL code:
At first consider the clever stack manipulation from Katie’s contribution: [ 0 ][ Enter ][Cmplx][ + ][ / ][ IP ][ * ][ - ]
Suppose we have y = x.q + r,
I like the clever way of managing the RPN stack: t: ~ | ~ | y | y | y | y | y | y |
It’s really close to what may be done in RPL (without the built-in MOD function. 4: | y | | | | | The version proposed by flsh, which look really close to a HP-41C style with stack register manipulation.It spare one step through memory recall and operation combine in one [ RCL/ IND Y ] instruction.
t: ~~~ | ~ | ~ | ~ | ~ | ~ | But as RPL devices, the HP-41C (and HP-42S) calculator has built-in MOD function.
Here a version for the great WP-34S which have no built-in MOD function (or I am missing something?): t: ~ | y | y | y | y | y | How to produce with short code the same stack manipulations on the HP-15C is another storie. Here is for comparison the way proposed by Gerson:
l: ~ | ~ | ~ | ~ | ~ | x | x | x | x | x | y/x | y/x | y/x | Obviously HP-15C lacks same stack manipulation command. But that’s what makes the charm of this old-style true RPN calculator. In daily use of it, did this lack of complex stack manipulations miss any users? A way to mimic the DUP2 stack manipulation style will be to use statistic function. But, even if this is short, this solution will clear (and use) registers R2 to R7. Perhaps it is not a convenient way ?
R2: ~ | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Since this last solution use so much memory register and clearing statistic also clear the stack, it is not a valid code. I greatly prefer not to try to manipulate stack on an HP-15c, and using an approximative MOD function, only valid for y and x both positive :
l: ~ | x | x | x | y/x | y/x |
Edited: 16 Sept 2011, 4:51 p.m. after one or more responses were posted
09-16-2011, 04:59 AM
For the 34S:
cmplx ENTER Which is a direct copy of the 32sii version changing IP for FLOOR (the 34S having both). The 34S has a remainder function that is the same as MOD for positive arguments but slightly different for negative.
09-16-2011, 05:21 AM
Some incarnations of the 34S software have a bug that make cENTER unreachable from the keyboard. It's fixed in both the zip and SVN now.
09-16-2011, 05:59 AM
Thank you.
I just revised my previous post incorporating the WP34S version.
09-16-2011, 06:10 AM
The 34S RMDR operation (h-shift divide) behaves the same as C's MOD operator (for both integer and real modes). For example:
7 3 RMDR = 1 There was mention a while ago of this not being the correct behaviour for MOD. I don't remember the exact details though. What should the values be here?
- Pauli
Edited: 16 Sept 2011, 6:13 a.m.
09-16-2011, 06:57 AM
Quote:
Hepp!
7 3 RMDR = 1 RMDR is MOD correct since 7 = 2 × 3 + 1 and 0 < 1 < 3 7 3 MOD = 1 Sametime I wonder myself, why and how simple idea became so complicated in the mathematic world ?
09-16-2011, 07:34 AM
My (outdated) wp34s manual says: RMDR Equals MOD on HP-42S and RMD on HP-16C.
However, on the HP-42S we have: 7 3 MOD = 1 Gerson.
09-16-2011, 07:48 AM
Isn't the code above doing the remainder instead of MOD then? -7 mod 3 is -1 according to the code above:
[RCl ST Y][RCL/ ST Y] [IP] [*] [-]
You need FLOOR instead of IP or INT to get a MOD don't you?
09-16-2011, 07:52 AM
The manual is incorrect. It is the same as RMD on the 16C. It honours the sign of the numerator. To get MOD, add the denominator to the result if the signs of the two numbers are different. Maybe I should just implement MOD as well although it will eat up a bit of space to do so. RMDR works with integers, reals and complex numbers and double precision integers -- MOD should also.
09-16-2011, 08:50 AM
Quote: Katie's code kind of 'ported' to the 15C:
001 LBL A A bit longer but an implementation of the same idea... ;)
Edited: 16 Sept 2011, 9:19 a.m. after one or more responses were posted
09-16-2011, 09:21 AM
This is the remainder of the integer division, however, not the modulus function. MOD can be defined as
MOD(x,y) = x - y * Floor(x/y)
where Floor(x) = INT(x) + INT(FRAC(x) + 1) - 1
09-16-2011, 09:28 AM
As I wrote, my code was just an implementation of Katie's very elegant 32s-idea ported to the 15c, whether it yields modulo or remainder - I didn't investigate. After I read the modulo article on wikipedia I'm not sure if I still know the difference between modulo and remainder... ;)
09-16-2011, 09:36 AM
Yes, there is some confusion. On the HP-33s, for instance, they have implemented the modulus function, and yet they name it Rmdr. When the signs of the arguments are the same, they are equivalent:
7 3 RMDR = 1
09-16-2011, 02:13 PM
Of course there must be no RCL IND Y commands in any of these routines. This would recall the register whose address is in y. RCL YAlthough not required on a HP-41 (MOD is available), a double RCL Y will match the DUP2 of RPL: RCL YOf course you can also do it on a classic HP machine. The following code is two steps shorter than Gerson's and uses the t-duplication on stack drop: ENTER^The HP35s finally has a RMDR function and can also access the stack registers directly. It features both IP as well as INTG. It even offers a command for integer division, similar to DIV in some programming languages. Very handy in many cases. Using equation mode one could do it this way: REGY-REGX*IDIV(REGY,REGX)Dieter
09-16-2011, 02:27 PM
Well... Quote:
...the 35s has them both: IP and INTG. And RMDR, of course. ;-) REGY-REGX*IP(REGY/REGX)resp. REGY-REGX*INTG(REGY/REGX)will return the one or the other result. The second version is equivalent to the 35s RMDR function. Dieter
09-16-2011, 04:04 PM
Thank you for your attentive reading and pointing out the “IND” error. Of course, there’s no indirect access there. My intention was to make HP-41C "STO Y - where Y is in stack " notation not confused with HP-32 alphabetic name f register (where "STO Y" means store in register named Y). Using reserved keyword IND is my own mistake. I have to correct this in my post. I like your code using a dump zero addition " Clx + " to realize the DUP2 style algorithm on classic. It is a triky way.
t: ~ | ~ | y | y | y | x | x | x | x | x | x | Nice shot ! Achievable on all the classic !
Edited: 16 Sept 2011, 4:24 p.m.
09-16-2011, 04:59 PM
By the way... Quote:FLOOR (or INTG on the 35s) really is a very useful function. However, most devices only offer INT or IP which simply cuts off the decimals.
But there is a way - for instance on the '41: ENTER^You can also try this with -1 and see what you get. Dieter
Edited: 16 Sept 2011, 5:01 p.m.
09-16-2011, 05:03 PM
Let make a table to check which fonction for which result :
y x : y MOD x y RMDR x : y-x.INT(y/x) y-x.FLOOR(y/x) y-x.CEIL(y/x)Obviously, MOD is obtained from FLOOR and RMDR from IP or INT. CEIL lead to a third type of modulus.
09-18-2011, 06:53 AM
I think it's important to say which MOD or RMDR you refer to. For instance, the results of MOD on the 41 and RMDR on the 35s are exactly the same.
Regarding CEIL: usually this is an easy one as CEIL(x) = -FLOOR(-x). ENTER^On a 35s, use RDMR instead. ;-) Or simply CHS INTG CHS. That's one of the things I like on the 35s. Dieter
Edited: 18 Sept 2011, 6:54 a.m.
09-18-2011, 07:12 AM
C.Ret wrote: Quote:There indeed is a special keyword on those calculators that feature both lettered registers and stack access, e.g. the 42s. Here, a simple "ST" distinguishes between stack and variables:
Recall variable (data register) "Y": RCL YRecall stack register y: RCL ST YOn other calculators RCL Y is unambiguous since it can have only one meaning: There are no lettered data registers or variables on the 41, so RCL Y refers to the stack. On the 32s, there is no direct stack access, so it's clear that RCL Y refers to the variable (data register) with that name. BTW, the 34s does it in a very special way: the content of the stack registers is stored in registers with the same letter. So RCL Y means both "recall variable Y" and "recall stack register Y". ;-) Dieter
Edited: 18 Sept 2011, 7:21 a.m. |
« Next Oldest | Next Newest »
|