Post Reply 
HP 50g Binary Number Formatting
04-20-2022, 05:47 PM
Post: #1
HP 50g Binary Number Formatting
Is it possible to have binary numbers displayed in groups of 4 digits? e.g. 1110 1101
Find all posts by this user
Quote this message in a reply
04-23-2022, 01:38 PM (This post was last modified: 04-23-2022 10:14 PM by Gil.)
Post: #2
RE: HP 50g Binary Number Formatting
1) Place your binary digits as a string in the stack.

"1110 1101"

2) Execute —>BIN4
(file here included as "—>BIN4.Doc"
Note:
- The ending .Doc is not a Word document.
- You can simply download that file into your calculator
- and save it in your calculator as —>BIN4).

Code for —>BIN4:

« DUP DUP SIZE ""  str.ORIGIN size.ORIGIN str.NEW
« size.ORIGIN 4 MOD 4 SWAP - DUP  m m.ORIGIN
« size.ORIGIN m + 4 /  loop
«
WHILE m 0 ‹
REPEAT " " str.ORIGIN + 'str.ORIGIN' STO -1 'm' STO+
END 1 loop
FOR i str.NEW str.ORIGIN i 1 - 4 * 1 + DUP 3 + SUB + " " + 'str.NEW' STO
NEXT str.NEW m.ORIGIN 4 MOD 1 + str.NEW SIZE 1 - SUB
»
»
»
»

Or
\\<< DUP DUP SIZE \"\" \\-> str.ORIGIN size.ORIGIN str.NEW
\\<< size.ORIGIN 4 MOD 4 SWAP - DUP \\-> m m.ORIGIN
\\<< size.ORIGIN m + 4 / \\-> loop
\\<<
WHILE m 0 \\=/
REPEAT \" \" str.ORIGIN + 'str.ORIGIN' STO -1 'm' STO+
END 1 loop
FOR i str.NEW str.ORIGIN i 1 - 4 * 1 + DUP 3 + SUB + \" \" + 'str.NEW' STO
NEXT str.NEW m.ORIGIN 4 MOD 1 + str.NEW SIZE 1 - SUB
\\>>
\\>>
\\>>
\\>>

It's a rough solution that should work fine, though it could be bettered in terms of code.

Hope it might help.

Regards,

Gil Campart


Attached File(s)
.doc  —>BIN4.Doc (Size: 405 bytes / Downloads: 2)
Find all posts by this user
Quote this message in a reply
04-23-2022, 06:01 PM
Post: #3
RE: HP 50g Binary Number Formatting
Better add the bold instructions
4 MOD in the modified code below:

\<< DUP DUP SIZE "" \-> str.ORIGIN size.ORIGIN str.NEW
\<< size.ORIGIN 4 MOD 4 SWAP - 4 MOD DUP \-> m m.ORIGIN
\<< size.ORIGIN m + 4 / \-> loop
\<<
WHILE m 0 \=/
REPEAT " " str.ORIGIN + 'str.ORIGIN' STO -1 'm' STO+
END 1 loop
FOR i str.NEW str.ORIGIN i 1 - 4 * 1 + DUP 3 + SUB + " " + 'str.NEW' STO
NEXT str.NEW m.ORIGIN 4 MOD 1 + str.NEW SIZE 1 - SUB
\>>
\>>
\>>
\>>


Attached File(s)
.doc  —>BIN4b.Doc (Size: 410 bytes / Downloads: 2)
Find all posts by this user
Quote this message in a reply
04-23-2022, 06:50 PM
Post: #4
RE: HP 50g Binary Number Formatting
Easier to understand the following code, where we take every value and check if it is the 4th, the 8th,the 12th..., and when it is the case add a blank.

Code for —>BIN4c:

\<< \->STR DUP DUP SIZE \-> str.ORIGIN size.ORIGIN
\<< size.ORIGIN 4 MOD 4 SWAP - 4 MOD \-> m
\<< m m
WHILE m 0 \=/
REPEAT " " str.ORIGIN + 'str.ORIGIN' STO -1 'm' STO+
END size.ORIGIN + 1 SWAP "" UNROT
FOR i str.ORIGIN i i SUB + i 4 MOD 0 ==
IF
THEN " " +
END
NEXT DUP SIZE 1 - ROT 1 + SWAP SUB
\>>
\>>
\>>


Attached File(s)
.doc  —>BIN4c.Doc (Size: 321 bytes / Downloads: 4)
Find all posts by this user
Quote this message in a reply
04-23-2022, 11:42 PM
Post: #5
RE: HP 50g Binary Number Formatting
A somewhat different approach:

Code:

\<< \->STR 3. OVER SIZE 1. - SUB    @ Clean up binary string
  0. SWAP                           @ Initialize counter
  WHILE DUP SIZE                    @ Any bits left?
  REPEAT DUP 1. 4. SUB " " + UNROT  @ First 4 bits plus space
    5. OVER SIZE SUB                @ Rest of string
    SWAP 1. + SWAP                  @ Increment counter
  END DROP \->LIST "" + \GSLIST     @ Concatenate substrings
  1. OVER SIZE 1. - SUB             @ Remove final space
\>>

Note that the string in line 4 is one space, and the string in line 7 is an empty string. The reason for the empty string in line 7 is that \GSLIST (Sigma-list) can't handle lists with less than two elements.
Find all posts by this user
Quote this message in a reply
04-24-2022, 12:03 AM (This post was last modified: 04-24-2022 12:06 AM by Gil.)
Post: #6
RE: HP 50g Binary Number Formatting
It seems that, with the program suggested by John Keith, the 4 digits-block starts from the left.
So that we get with his program:
1234 5678
1234 5678 9
1234 5678 91
1234 5678 912

But I understood that we should get:
123 4567 8912
12 3456 7891
1 2345 6789
1234 5678

Besides, John Keith's program seems to cut off the first and last digits.

But really a great idea to play with the stack, not using — at all — intermediary variables.

Regards,
Gil
Find all posts by this user
Quote this message in a reply
04-24-2022, 10:40 AM
Post: #7
RE: HP 50g Binary Number Formatting
(04-24-2022 12:03 AM)Gil Wrote:  It seems that, with the program suggested by John Keith, the 4 digits-block starts from the left.
Correct. It'll have to work in reverse - replace
Code:
DUP 1. 4. SUB
with
Code:
DUPDUP SIZE DUP 3. - SWAP SUB
and
Code:
5. OVER SIZE SUB
with
Code:
1. OVER SIZE 4. - SUB
and reverse the list before concatenating its contents. There is a command for that (REVLIST) but an even easier (and probably faster) way is to forego the list entirely and replace
Code:
\->LIST "" + \GSLIST
with
Code:
2. SWAP START + NEXT

All of the above suggestions are untested, but should work. Otherwise, complain or get to work yourself. Wink

(04-24-2022 12:03 AM)Gil Wrote:  Besides, John Keith's program seems to cut off the first and last digits.
Incorrect, it merely cuts off the "# " prefix and "b" suffix.
(04-24-2022 12:03 AM)Gil Wrote:  But really a great idea to play with the stack, not using — at all — intermediary variables.
As do the majority of good RPL programs, because in most cases variables are both bulkier and slower. If readability is a concern, we can have comments instead of variable names - they can be preserved by encasing the whole program in a string. Stash a copy of that somewhere (the SD card should have plenty of space to spare), and use STR\-> to compile it. The ability to view and edit a compiled program was useful when our beloved calculators were short on memory, but now it has become a trap - embrace the standard software development process of keeping source and binary separate.

Anyway, back to topic...

I like a programming mini-challenge, so I've taken a swing at an implementation of my own. It's in SysRPL because of course it is, what else would you expect from a SysRPL enthusiast - and the trick at its center is definitely a bit unorthodox. Some may find it inspiring, others horrifying: instead of the string chopping of the previous programs, I'm slicing the number into 4-bit pieces with arithmetic and logic operations (so far, so normal), conducting further arithmetic and logic operations on each piece to construct the ASCII codes of the corresponding 5-character string in the binary number (uhhh...) and then charging ahead with string manipulation on it (what!?!).
That works because a user binary integer (or hex string, in SysRPL terms) has the same memory layout as a character string, just a different prolog. I used to have # 2A2C CHANGETYPE in there, but then I remembered it wasn't necessary because most SysRPL commands don't even check for correct types, they just assume the programmer did it already.
The rest is just putting the string pieces together and converting the most significant digit group using one of the normal convert-to-string commands because that one is allowed to omit leading zeroes.

Despite this deliberate type confusion inside, the program has proper type checking for user input, and it even switches to BIN mode and sufficient word size for the duration of the program, while restoring the original flags afterwards. It also adds the "# " prefix and "b" suffix - which means converting the string back into a usable number only requires stripping out the spaces (e.g. in UserRPL: " " "" SREPL) followed by OBJ\->.
Code:
::
  CK1&Dispatch
  BINT11
  ::
    "b"
    BEGIN
      SWAPDUP HXS 2 01 bit/
      UNROT HXS 1 F bitAND
      3PICK HXS 1 0 HXS#HXS %0<>
    WHILE
    ::
      HXS 9 020408001 bit*
      HXS 9 001010101 bitAND
      HXS A 0203030303 bitOR
      BINT6 1_#1-SUB$
      SWAP&$
    ;
    REPEAT
    RunSafeFlags
    :: DOBIN BINT4 dostws hxs>$ ;
    SWAP&$ SWAPDROP
  ;
;
134.5 bytes, checksum #A905.

However, no programming marvel can hide the fact that binary integers on the 50g do not support digit grouping natively. (Nor do any other number formats, for that matter. The only one that comes somewhat close is the engineering mode for real numbers, which coerces the decimal exponent into a multiple of 3.) We can write programs to convert the number into an appropriately formatted string, we could even write more programs to convert it back into a number you can calculate with, but as soon as you use these with any kind of regularity, you'll find that borderline unusable.
There is a different option, though. What is equivalent to four binary digits? A hexadecimal digit.
Yes, I do propose simply using HEX mode instead. Performing the conversion between a hex digit and its binary equivalent in your head takes some practice, but it won't take long before that gets handed off to the subconscious. In addition to the restored calculator usability, there's another bonus: no more scrolling through obnoxiously long numbers on the small screen, because even a 64-bit number (the longest allowed) will just fit.
Find all posts by this user
Quote this message in a reply
04-24-2022, 11:34 AM (This post was last modified: 04-24-2022 11:36 AM by Gil.)
Post: #8
RE: HP 50g Binary Number Formatting
Great indeed all the refined solutions proposed.

Beyond my basic level, indeed.

About mine, for which it seems easier to follow the steps:

I considered a string of digits only such as
"1111001".

If you have instead a character at the beginning and another one at the end,
such as "A1111001B",
you will have to cut them off (the A and B in the example sbove) before launching the program.

Add rather then the following instructions
DUP SIZE 1 - 2 SWAP SUB
at the very beginning of my program —>BIN4c
Find all posts by this user
Quote this message in a reply
04-24-2022, 11:59 AM
Post: #9
RE: HP 50g Binary Number Formatting
(04-24-2022 10:40 AM)3298 Wrote:  ...
The rest is just putting the string pieces together and converting the most significant digit group using one of the normal convert-to-string commands because that one is allowed to omit leading zeroes.
...

Wow, every time I get ready to post a response on this thread, someone posts something that makes it look as if I were plagiarizing.

I took a different view to this, mostly because I prefer to see full groups of 4 (ie. with leading zeros) instead of a shortened version for the initial digit group. In other words, I would prefer to convert #1Fh to "0001 1111" than "1 1111".

My standard UserRPL version of this would seem redundant given the previous posts. So instead I'll submit a version that uses some of the ListExt library commands to shorten the code:
Code:
\<<
   RCLF BIN                   @ save modes and set to binary
   SWAP \->STR                @ convert binary # to base-2 string
   SWAP STOF                  @ restore modes
   3.                         @ starting char to keep
   OVER SIZE 1. -             @ last char to keep
   SUB                        @ extract just the digits

   "000" SWAP +               @ left-pad with zeros
   S\->SL                     @ convert string to list of characters
   DUP SIZE 4. MOD LDROP      @ drop unwanted prefix characters
   4. LSDIV                   @ group all digit characters into quads
   " " LMAP                   @ place spaces after each group
   -1. LDROP                  @ drop the final space
   LXIL SL\->S                @ convert chars to final string
\>>

Size: 112.5 bytes
Checksum: # 1A0Bh

Descriptions of the ListExt commands used:
S→SL: Converts a string to a list of individual characters
LDROP: Drops the specified quantity of list elements from a given list (positive drops from the left, negative from the right)
LSDIV: Subdivides a given list into a list of sublists with the given size
LMAP: Executes the given object for each list element, and returns the results as a list
LXIL: (eXplode Inner Lists) replaces top-level sublists with the individual elements they contain
SL→S: builds a string from the given list of characters
Find all posts by this user
Quote this message in a reply
04-24-2022, 06:06 PM (This post was last modified: 04-24-2022 08:22 PM by dlidstrom.)
Post: #10
RE: HP 50g Binary Number Formatting
Here’s an implementation that accepts a real and converts it into a string.

→BIN4: r → s

Code:

« → d
  « { }
    DO d 16 MOD → r
      «
        CASE
        'r==0' THEN "0000" END
        'r==1' THEN "0001" END
        'r==2' THEN "0010" END
        'r==3' THEN "0011" END
        'r==4' THEN "0100" END
        'r==5' THEN "0101" END
        'r==6' THEN "0110" END
        'r==7' THEN "0111" END
        'r==8' THEN "1000" END
        'r==9' THEN "1001" END
        'r==10' THEN "1010" END
        'r==11' THEN "1011" END
        'r==12' THEN "1100" END
        'r==13' THEN "1101" END
        'r==14' THEN "1110" END
        'r==15' THEN "1111" END
        END
      »
      + d 16 / IP 'd' STO
    UNTIL
      'd==0'
    END
  »
  IF
    DUP SIZE 1 >
  THEN
    REVLIST
    « " " SWAP + + »
    STREAM
  ELSE
    EVAL
  END
»

This pattern matching approach trades some bytes for readability, which I tend to favour these days (when programming in other languages). I didn’t find a string join function that could avoid the last if statement. Unfortunately STREAM errors on a list with a single element.

2xHP48GX, HP 50g, two Retrotronik ram cards, DM42
/Daniel Lidström
Find all posts by this user
Quote this message in a reply
04-25-2022, 03:22 PM
Post: #11
RE: HP 50g Binary Number Formatting
(04-24-2022 10:40 AM)3298 Wrote:  As do the majority of good RPL programs, because in most cases variables are both bulkier and slower.

Such antiquated concept... newRPL variables are often faster than the stack.

Anyway, here's my take in newRPL dialect:

Code:

«
  → N 
  « 
    ""                          @@ START WITH AN EMPTY STRING
    DO
      #10000b N #Fh BAND +      @@ ISOLATE 4 BITS, TURN THE 5TH BIT ON TO GET ALL 4 DIGITS
      →STR 3 6 SUB              @@ CONVERT TO STRING "#1xxxxb" AND EXTRACT THE 4 DIGITS
      SWAP +                    @@ PREPEND TO THE ORIGINAL STRING
      N 4 BLSR 'N' STO          @@ ROTATE 4 BITS TO THE RIGHT TO GET THE NEXT DIGIT
      IF N THEN " " SWAP + END  @@ PREPEND A SPACE IF THERE ARE ANY MORE NONZERO DIGITS
    UNTIL  
        N NOT                   @@ END THE LOOP WHEN NO MORE NONZERO DIGITS
   END
  »
»
Find all posts by this user
Quote this message in a reply
04-25-2022, 04:04 PM
Post: #12
RE: HP 50g Binary Number Formatting
Sorry for my ignorance.

Where does the command BLSR in the last program, come from?
Should I load a special program to access it?

I use emu48 application on my phone exclusively.

Thanks for your answer.

Regards
Find all posts by this user
Quote this message in a reply
04-25-2022, 04:39 PM (This post was last modified: 04-25-2022 04:44 PM by Claudio L..)
Post: #13
RE: HP 50g Binary Number Formatting
(04-25-2022 04:04 PM)Gil Wrote:  Sorry for my ignorance.

Where does the command BLSR in the last program, come from?
Should I load a special program to access it?

I use emu48 application on my phone exclusively.

Thanks for your answer.

Regards

It's a newRPL only command, similar to the SR command on the 50g ROM except this one takes the number of bits you want to shift, rather than just shifting by one.

The code I provided was only meant to be used with newRPL, but you can replace 4 BLSR with SR SR SR SR (4 times 1-bit shifts) and it should work the same way on the stock ROM.

Or you can download newRPL Desktop and try it on your PC. You can simply copy the text from my post to your clipboard and select Stack -> "Paste to Level 1" to get the text on the simulator, then do STR→ to get the program compiled and ready to run.

**EDIT**: I just saw you use your phone exclusively. When you click the Download button it will download the PC version, but you can go instead to the Files tab, then you can go into the folder TARGET-ANDROID and download an .apk to install on your Android phone (assuming you use Android, if you have an iPhone you are out of luck...)
Find all posts by this user
Quote this message in a reply
04-25-2022, 06:34 PM
Post: #14
RE: HP 50g Binary Number Formatting
(04-24-2022 12:03 AM)Gil Wrote:  It seems that, with the program suggested by John Keith, the 4 digits-block starts from the left.
So that we get with his program:
1234 5678
1234 5678 9
1234 5678 91
1234 5678 912

But I understood that we should get:
123 4567 8912
12 3456 7891
1 2345 6789
1234 5678

Besides, John Keith's program seems to cut off the first and last digits.

Sorry about that, I posted on my way out and didn't check the program well enough.

As 3298 pointed out, when you enter a binary number using # or convert an integer to binary using B->R, the number format is # 1010b (or d, h or o depending on mode). The program removes the leading "# " and the trailing letter. If your binary numbers come from another source, that part of my program (and others) can be removed.
Find all posts by this user
Quote this message in a reply
04-25-2022, 10:34 PM
Post: #15
RE: HP 50g Binary Number Formatting
I understood afterwards, thinking at the very beginning that the input was composed of the only digits 1 and 0.

Thanks again.

Regards,
Gil
Find all posts by this user
Quote this message in a reply
04-27-2022, 08:46 PM
Post: #16
RE: HP 50g Binary Number Formatting
Thank you all for these solutions. I'm learning more about this great calculator.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)