Post Reply 
Undocummented (?) limits for the HP50g
08-02-2021, 10:22 AM
Post: #1
Undocummented (?) limits for the HP50g
Experimentally, I found that the HP50g cannot convert binary numbers of more than about 38 bits correctly to and from decimal. Likewise, such numbers do not compare correctly nor sort correctly. MAX and MIN do seem to work as do addition and subtraction.

I'm doing more checking as most of the work I've done with large integers (for creating pseudo-random number generators) is suspect. I haven't yet checked things like POWMOD and its relatives using large moduli.

It appears that binary strings (supposedly up to 64 bits) are manipulated with floating-point procedures. Setting the binary length to 64 doesn't help.

I suppose I could use MAX and MIN and add and subtract to do comparisons (if the sign doesn't turn up with ? rather than 0 or 1.)

I'll probably just re-write my large integer Fortran package for the PC; it's several thousand times faster but Windows 10 doesn't run my programming assistants.
Find all posts by this user
Quote this message in a reply
08-02-2021, 11:50 AM
Post: #2
RE: Undocummented (?) limits for the HP50g
Can't reproduce on firmware 2.15.

# 1000000000001h (that's \(2^{48}+1\), i.e. a 49-bit number where rounding would definitely load to inaccuracy, regardless of whether rounding is performed in decimal or binary format) shows up in DEC mode as # 281474976710657d, which as far as I can tell is accurate.
SORT on that number and the 5 following numbers (that is \(\{2^{48}+1, ..., 2^{48}+6\}\)), manually brought into a random non-ascending order, sorts them correctly too.

Just don't try to convert them to reals, they only have 12 decimal digits of floating point precision. There is no direct way I know of to convert between CAS infinite-length (decimal) integers and user binary integers, but avoiding the route through reals (which you would encounter with B\->R R\->I and I\->R R\->B) is easy by going through strings: DEC 105. CF \->STR 3. OVER SIZE 1. - SUB OBJ\-> in one direction, \->STR "# " SWAP + "d" + OBJ\-> in the other. That should cover enough type juggling to do heavy calculations on long numbers originally expressed in a non-decimal base.
Find all posts by this user
Quote this message in a reply
08-02-2021, 02:15 PM
Post: #3
RE: Undocummented (?) limits for the HP50g
Going through strings is useful, I like it. The only problems seem to be with the relational operators and sorting (same problem probably.) The only real trouble is converting binary integers bigger than 2^38l. I do it in binary by separating the high and low-order bits and combining them later.

There can be some problems with the FLOOR and other functions. I found an ordering that doesn't cause CAS to convert internally. I have a really big fraction nnnnnn/dddddd which I wish to multiply by a big number and take the quotient. I split the formula into Top*Number then result/Bottom then FLOOR. IQUOT and IREMAINDER fail (I think).
Find all posts by this user
Quote this message in a reply
08-02-2021, 06:02 PM
Post: #4
RE: Undocummented (?) limits for the HP50g
(08-02-2021 02:15 PM)ttw Wrote:  There can be some problems with the FLOOR and other functions. I found an ordering that doesn't cause CAS to convert internally. I have a really big fraction nnnnnn/dddddd which I wish to multiply by a big number and take the quotient. I split the formula into Top*Number then result/Bottom then FLOOR. IQUOT and IREMAINDER fail (I think).
None of FLOOR, IQUOT and IREMAINDER accept binary integers, so you have to convert them anyway before calling these, which means we aren't even talking about binary integers anymore. (By the way, comparison and sorting works fine on binary integers over here.) Conversion through strings as I outlined sidesteps the reals entirely, so you don't need to chop up anything. I tested it and had no problems converting \(2^{63}+1\) that way. After that, all you need to worry about is staying with infinite-length integers for all calculations.
Also, your insistence on \(2^{38}\) is misleading: reals are decimal, \(10^{12}\) is the relevant threshold. And a well-documented one at that.

FLOOR is a command for real numbers which predates the CAS, so by calling it you're implicitly converting to real with all the 12-digit floating point implications. If you want to stay exact, IQUOT is exactly the right command for the job. It's a CAS command, and I checked its implementation with Nosy: the dispatch does use the dispatcher that would auto-convert to real, but before the "two real numbers" pattern it has a "two symbolic-class objects" pattern (symbolic class contains actual symbolic objects, but also real numbers). That means it won't get a chance to downgrade CAS integers. I checked with 2 128 ^ 2 64 ^ IQUOT, and the result was equal to 2 64 ^, as expected. (If there was a conversion to reals somewhere, it wouldn't have been accurate because the floating point format is decimal, not binary.)
That said, it's possible to accidentally bypass the symbolic-class case of the dispatch if you supply it with one integer and one real, because reals are not symbolic-class. Check your code, you might have some reals lurking in there if IQUOT fails to produce correct results.
Find all posts by this user
Quote this message in a reply
08-02-2021, 09:15 PM
Post: #5
RE: Undocummented (?) limits for the HP50g
Maybe these two little programs from Joe Horn can be useful: I->B and B->I. They avoid going through real numbers:
https://www.hpcalc.org/details/9194

Ramón
Valladolid, Spain
TI-50, Casio fx-180P, HP48GX, HP50g, HP Prime G2
Visit this user's website Find all posts by this user
Quote this message in a reply
08-03-2021, 12:43 AM
Post: #6
RE: Undocummented (?) limits for the HP50g
Thanks for all the suggestions. It looks like I can do what I need. Binary integers are secondary (I have a good workaround for a shift-register sequence using just lists). IQUOT and IREMANDER passed my tests so I can use them. MAX and MIN seem to work but Isorting failed in some cases (not as important). I try to do everything using big integers. I just have to keep the system from switching out of these (not too hard.)

I like the HP50G for these things because of the built-in POWMOD (though the results are not the same as MOD; POWMOD returns results symmetric about 0 but this is easily fixed.) FACTORS is nice so I can develop quadratic residues and primitive roots for primes of various types. (I built some wheels for searching; these are sieves with some pre-masking.)

I'm building a Random Number Generator Generator; it's not designed for cryptography but it should be OK for high accuracy other stuff. I haven't looked at this stuff in years as I concentrated on quasi-Random sequences; these are enough different that I need high-quality quasi-random generators too.
Find all posts by this user
Quote this message in a reply
08-03-2021, 11:52 AM (This post was last modified: 08-03-2021 11:58 AM by John Keith.)
Post: #7
RE: Undocummented (?) limits for the HP50g
A few random (pun intended) ideas:

If by lsorting you mean using the program LSORT, it will fail given a list containing both real numbers and exact integers. You need to make sure that no real numbers have crept into your list.

You might also want to look at IFACTOR, it is significantly faster than the built-in FACTOR but the list it returns is in a different format.

Many of the commands you are using, MAX, MIN, MOD, IQUOT, and IREMAINDER are annoyingly slow with exact integers. Don't expect your program to be particularly fast! Another (slow) command you may be able to use is IDIV2, which gives you the quotient on level 2 and the remainder on level 1. It is actually a bit faster than either IQUOT or IREMAINDER.

Another useful library is ListExt 1.3. Along with many useful commands for general list processing, you may be particularly interested in I->BL and BL->I which convert exact integers into lists of digits in any base and vice versa.

Lastly, if you post some examples of your code you may get more helpful suggestions.
Find all posts by this user
Quote this message in a reply
08-03-2021, 12:17 PM
Post: #8
RE: Undocummented (?) limits for the HP50g
(08-02-2021 02:15 PM)ttw Wrote:  Going through strings is useful, I like it. The only problems seem to be with the relational operators and sorting (same problem probably.) The only real trouble is converting binary integers bigger than 2^38l. I do it in binary by separating the high and low-order bits and combining them later.

There can be some problems with the FLOOR and other functions. I found an ordering that doesn't cause CAS to convert internally. I have a really big fraction nnnnnn/dddddd which I wish to multiply by a big number and take the quotient. I split the formula into Top*Number then result/Bottom then FLOOR. IQUOT and IREMAINDER fail (I think).

I have another suggestion for you: use newRPL and you'll have NONE of those issues.
Sorry if it sounds like a cheap advertising, but it's actually true. All these issues and quirks of the conversion of different types were resolved in newRPL internally, the user doesn't need to deal with these issues, just focus on your algorithm and everything should work as expected.
Integers up to 64 bit convert to binary just fine, no need to do any workarounds. FLOOR, IQUOT, etc. they all work just fine with numbers up to 2000 digits, real or integer doesn't matter., I see a post by John Keith explaining how SORT will fail, not going to happen in newRPL.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: