# HP Forums

You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
To have handy like on other calculators the

a) conversion from a decimal result
to a (pi) fraction.

Example
7. ENTER
5 :
You get 1.4 in stack 1.

(You could enter also:
'7/5' ENTER —>NUM)

Press then the 3 keys:
LS (white key left to number 4)
Alpha-key (yellow key for USER functions)
: (division key, under TAN key).

You will get
1.4 (in stack level 3)
'7/5' (in stack level 2)
'1+2/5' (in stack level 1).

Code to be entered beforehand:
« —> x
« x TYPE 9 ≠
IF
THEN x DUP DUP
ABS 1 <
IF
THEN —>Q
ELSE —>Q DUP
PROPFRAC
END
ELSE x DUP
PROPFRAC DUP2 SAME
IF
THEN DROP
END
END
»
»

Then add just after the above program the following instructions:
65.1 ASN
(in other words, you asssign this program to key
65.1, i.e. the USER Key .

You can assign afterwards
—>Q¶ (symbol of pi) to 65.2

with the following code
« DUP —>Q¶ »
65.2 ASN

Example
2 ENTER 3 / pi * —>NUM

On stack 1 you should get
2.09439510239.

Now press the 4 keys:
LS (white key left to number 4)
Alpha-key (yellow key for USER functions)
LS (white key left to number 4)
: (division key, under TAN key)

And you get the fraction in function of pi :
'2/3*¶' (Stack 1)
2.09439510239 (decimal value in stack 2).

b) Useful also might be, given a division, to get a lot of decimals :

EXAMPLE
'7/51' ENTER.
It is mandatory to enter the
above expression with
integers only and with
' at the beginning of it
and finish that expression with '
(the relative key ' is the one above the SIN function key).

Press then the 4 keys:
LS (white key left to number 4)
Alpha-key (yellow key for USER functions)
RS (orange key left to number 1)
: (division key, under TAN key).

You should get :
'7/51' (in stack level 3)
.137254901961 (in stack level 2)
13725490196078431372549019607843137254901960784313725490196078431372549019607843​13725490196078431372 (in stack level 1)

To be able to enjoy the above described user 65.3 key,
enter the following code:

« DUPDUP —>NUM SWAP —>STR DUP SIZE RCLF —> x s f
« -105 CF 2 s 1 -
FOR i x "." POS DUP x 1 ROT 1 - SUB x ROT 1 + s SUB + 'x' STO
NEXT x OBJ—> 100 ALOG * PROPFRAC PROPFRAC -105 SF DUP TYPE 9 ==
IF
THEN OBJ—> 3 DROPN
END f STOF
»
»
Then, just after that program, write:
65.3 ASN.

Obervation 1:
You can work on non exact mode and enter for example
'7/5'.

Obervation 2:
As forms like
'7.23/59' are not allowed,
transform them previously into:
'723/59' or '723./59' or
'723/5900' or '723./5900'.

Regards,
Gil
Observation

More logical should be to
replace the two instructions 'FOR i'
by the instruction 'START',
as the index i is not used — and therefore unnecessary — in the 'assignment program'.

But of course it does not not change the result.
To get fractions from decimals

\<< RCLF \-> x f
\<< RAD x TYPE 9 \=/
IF
THEN x DUP DUP ABS 1 <
IF
THEN \->Q
ELSE \->Q DUP PROPFRAC
END
ELSE x DUP PROPFRAC DUP2 SAME
IF
THEN DROP
END
END f STOF
\>>
\>>
65.1 ASN

To get full decimals from 'integer fractions'

\<< DUPDUP \->NUM SWAP \->STR DUP SIZE RCLF \-> x s f
\<< RAD -105 CF 2 s 1 -
START x "." POS DUP x 1 ROT 1 - SUB x ROT 1 + s SUB + 'x' STO
NEXT x OBJ\-> 100 ALOG * PROPFRAC PROPFRAC -105 SF DUP TYPE 9 ==
IF
THEN OBJ\-> 3 DROPN
END f STOF
\>>
\>>
65.3 ASN

In that way, the key user assignment program should not ask anymore for RAD mode conversion, restoring however at the end the initial flags values.

Regards,
Gil
When, with HP50G or HP Prime,
you evaluate negative fractions < -1,
say -7/3, you get -2.333333333.
The reverse gives '-7/3' or '-7+-1/3'.

The latter, with the double signs '+-',
is not very nice looking and
could or should be replaced by '-7-1/3'.

That's what I changed in my assignment user key 65.1 below for the HP50G.

\<< RCLF \-> x f
\<< RAD x TYPE 9 \=/
IF
THEN x DUP DUP ABS 1 <
IF
THEN \->Q
ELSE \->Q DUP PROPFRAC
END
ELSE x DUP PROPFRAC DUP2 SAME
IF
THEN DROP
END
END \->STR DUP "+-" POS DUP 0 ==
IF
THEN DROP
ELSE " " REPL
END OBJ\->
f STOF
\>>
\>>

65.1 ASN

Regards,
Gil
Thanks to John Keith, I could simplify the
end of the conversion user assignment key 65.1
from decimal to fractions of integers.
Here below in bold :

\<< RCLF \-> x f
\<< RAD x TYPE 9 \=/
IF
THEN x DUP DUP ABS 1 <
IF
THEN \->Q
ELSE \->Q DUP PROPFRAC
END
ELSE x DUP PROPFRAC DUP2 SAME
IF
THEN DROP
END
END \->STR "+-" "-" SREPL DROP OBJ\-> f STOF
\>>
\>>

Regards,
Gil
Conversion of fractions into decimals (many digits)

I somewhat changed the beginning of the code, in order to the program accept expressions like
'57/3/19*727/31' or '59/3/19*727/31'
and simplify them before when possible.

'57/3/19*727/31'
+ programme returns 4 stacks levels:
'57/3/19*727/31' (original stack expression )
'729/31' (simplified expression)
23.45... (decimal value approximation)
2345... (many digits)

'59/3/19*727/31'
+ programme returns 4 stacks levels:
'59/3/19*727/31' (original stack expression )
'42893/1767' (simplified expression)
24. 274... (decimal value approximation)
242744765139... (many digits)

Meanwhile '727/31'
+ programme returns only 3 stacks levels:
'727/31' (original, already simplified stack expression )
23.45... (decimal value approximation)
2345... (many digits)

Here are the full codes (in bold, the changes).

\<< RCLF \-> f
\<< -105 CF DUPDUP EXPAND DUP ROT SAME
IF
THEN DROP
END
DUPDUP \->NUM SWAP \->STR DUP SIZE \-> x s //I suppressed here the flag Var f already introduced right at the beginning of the program
\<< RAD 2 s 1 -
START x "." POS DUP x 1 ROT 1 - SUB x ROT 1 + s SUB + 'x' STO
NEXT x OBJ\-> 100 ALOG * PROPFRAC PROPFRAC -105 SF DUP TYPE 9 ==
IF
THEN OBJ\-> 3 DROPN
END f STOF
\>>
\>>
\>>

Note
Important: the program to be able to work has to be written with integers (without dots),
like "-105 CF", "9 TYPE", "100 ALOG", asf
(and not with dots like "-105. CF", "9. TYPE", "100. ALOG", asf).

Regards,
Gil
In your new code the sequence
IF
THEN DROP
END
can be replaced by
{ DROP } IFT
Not a big deal but this method saves a few bytes in any program that uses a simple IF...THEN...END structure.
HP49-50G

New version to get the full digits when
you write '12/7' or other more complicate expressions.

Now, possible to use decimals when multiplying or dividing.

Example possible : '12.7*7.97'
LS-User
Division-Key

When dots, impossible expression :
'12.7*7.97+8'.
The result without the dots should be a multiple
equal exactly to 1, 10, 100,1000,10000, etc. (or the exact inverse of those values) of the original expression with the dots.

Possible solution, after manual transmission:
'127*797+8000'
LS-User
Division-Key

Recommended solution:
use always the division sign (/).
'127/10+797/100+8'
LS-User
Division-Key

Observation 1
Always write the sign ' at the beginning and at the end of the expression.

Observation 2
Any mode is allowed.
You can enter for example '5*3/7' or '5.*3/7'.

Observation 3
When copying the program, it is the only time when the exact mode should be on.
In other words, -105. CF (with a dot after 105) is not allowed inside the program when copying the program (only allowed integers without dots like here -105 CF).

Code
\<< DUP 0 0 0 RCLF \-> x1 x2 x21 num f
\<< RAD -105 CF x1 \->STR "." "" SREPL 0 ==
IF
THEN DROP
ELSE OBJ\-> 'x2' STO x2 x1 / \->NUM LOG DUP FP 0 \=/
IF
THEN DROP "Instead of decimals (ab.c),

Try fractions
('abc/10') !" DOERR
END \->STR "." "" SREPL DROP OBJ\-> ALOG 'x21' STO
IF x21 1 >
THEN x2 x21 /
ELSE
IF x21 1 <
THEN x2 x21 INV *
ELSE x2
END
END \->STR "." "" SREPL DROP OBJ\->
END DUP EXPAND DUP2 SAME
IF
THEN DROP
END DUP \->NUM DUP 'num' STO num ABS 100000000000 > num FP 0 \=/ OR
IF
THEN OVER 10 100 ^ * PROPFRAC PROPFRAC -105 SF DUP TYPE 9 ==
IF
THEN OBJ\-> 3 DROPN
END
ELSE DROP
END f STOF
\>>
\>>
65.3 ASN

Regards,
Gil
Gil, I think you should move the post you made in the Article forum. If you can't move it perhaps a moderator can? I don't know why you had problems posting here but nobody (other than a moderator) can reply to posts in the Articles forum.
As you all of you may have noticed, I am not so familiar with the forum arcanes.

Please a moderator feel free to move my thread where it should be more appropriate, as kindly suggest by Joe Keith.

In advance I thank you for your comprehension — and him (the future moderator) for his cooperation.

Regards,
Gil

<<6 5 >
DROP
IFT >>

is not possible with DROP, as DROP is not an object.

In that specific case, the right test-structure should be
<< 6 5 >
IF THEN
DROP
END >>.
(01-07-2021 08:01 PM)Gil Wrote: [ -> ]Please note that
<<6 5 >
DROP
IFT >>

is not possible with DROP, as DROP is not an object.
That's not even the actual problem, it's that DROP isn't self-pushing. You need DROP to be on the stack when IFT is about to be eval'ed, and simply writing a command (or object, for that matter) doesn't do the trick unless it's self-pushing.
For UserRPL commands that are self-pushing, I only know of NOVAL which is used as a placeholder in some user interfaces and not really useful otherwise. In SysRPL there are TRUE and FALSE as well, which are generally much more useful, but that's irrelevant here since they are SysRPL. Many object types are also self-pushing, like all kinds of numbers, strings, etc. Some aren't though (like programs, global and local vars), which is important because otherwise you couldn't ever run anything. The simplest UserRPL way I know of to get any command on the stack would be to embed it into a list (which is a type of self-pushing object), then explode the list right after that. (If there is a simpler way, anybody is welcome to correct me. I'm more of a SysRPL person.) In the case of IFT, it seems you can actually skip the exploding step since it's a command that will just evaluate the content of a list as if it was a program instead.

All of those things considered, a working example for IFT with DROP would be:
Code:
```\<<   6. 5. >   { DROP }   IFT \>>```
Thanks for this corrective explanation.

I checked and it works fine with { }.

By the way, it's exactly what suggested Joe Keith.
My apologies by him for my having misread his thread mentioning the due { }.

Regards,
Gil
(01-07-2021 09:39 PM)3298 Wrote: [ -> ]
Code:
```\<<   6. 5. >   { DROP }   IFT \>>```

You could also tag the DROP with an empty tag ('::'), which will defer the execution but still execute in the context of IFT (or IFTE).

NDROP would be an even shorter solution here, as long as the boolean is always a 1 or 0 (no other numbers allowed ).
I did not quite understand the last "solution".

You mean
\<< 200 6 5 > {DROP} "" \->TAG IFT
\>>?

Why use tag, as it makes the code longer?

If it's different from the above, could you please write the full code solution relative to the "tag" and the 2nd solution?

Thanks,
Gil
David is talking about an unusual use of the :: (tag) called the "null tag". For example:

6 5 > :: DROP IFT

i.e. DROP goes after the tag, not inside it. To enter that on the HP 50, type [right-shift] . [right arrow] DROP.

Note that the "null tag" is not documented, it was discovered in the olden days by someone on comp.sys.hp48.
; is equivalent to DROP.

So that
CLEAR << 100 200 ; >>
EVALUATE will return 100.

So that to spare place (3.5 bytes)

You could write
<< 100 5 6 >
{;} IFT >>

<< 100 5 6 >
{DROP} IFT >>.

And, to save still 1.5 byte supplementary, according to David&Joe's tip even better:
<< 100 5 6 >
:: ; IFT >> (; is equivalent to DROP).

Regards,
Gil
(01-07-2021 10:08 PM)Gil Wrote: [ -> ]I did not quite understand the last "solution".

You mean
\<< 200 6 5 > {DROP} "" \->TAG IFT
\>>?

Why use tag, as it makes the code longer?

If it's different from the above, could you please write the full code solution relative to the "tag" and the 2nd solution?

Thanks,
Gil

I apologize, that's what I get for posting while on break and not taking the time to proofread or elaborate.

The null tag in front of a command will keep the command from executing in the normal flow of a UserRPL program, thereby simply placing the tagged command on the stack. The nice thing about a tagged command is that it will still perform its function if it is subsequently EVALuated or executed (which happens with the IFT/IFTE construct). So:
Code:
```"A" "B" 1. ::DROP IFT```
...will result in "A" being left on the stack. A 0. before the ::DROP will leave "A" "B" on the stack.

::DROP is actually smaller than { DROP } by 1.5 bytes.

I was in a hurry, and made a reference to NDROP (which is actually a SysRPL command) when I should have stated DROPN (which is the UserRPL equivalent). In the specific case where the boolean will always be either 1 or 0 (which is frequently the case with booleans), DROPN can be used instead of the IFT or IF...THEN...END constructs under discussion. For example:
Code:
```"A" "B" 1 DROPN```
...results in "A" being left on the stack, and
Code:
```"A" "B" 0 DROPN```
...results in "A" "B" being left on the stack. This is a useful command to use when the "THEN" clause is simply a DROP command. It's also economical at 2.5 bytes.

The ; command ("Safe DROP") is designed for use in situations where the stack may actually be empty before it is called, as it won't generate an error if executed when the stack is empty. If the stack isn't empty, it is exactly the same as DROP. Just like DROP, it takes up 2.5 bytes in a program. If you know that the stack isn't empty, there's no benefit to using ";" over "DROP". If used in a loop that is executed many times, ";" is actually slower than DROP and should only be used if needed for its special treatment of an empty stack.
Thanks to John Keith and DavidM, here is a shorter version
of the assignment user key 65.1 and 65.3
(no more IF... THEN DROP END).

In bold the two changes in the two Assignment-Key-User Programs.

Decimal to fraction:
\<< RCLF \-> x f
\<< RAD x TYPE 9 \=/
IF
THEN x DUP DUP ABS 1 <
IF
THEN \->Q
ELSE \->Q DUP PROPFRAC
END
ELSE x DUP PROPFRAC DUP2 SAME DROPN
END
\->STR "+-" "-" SREPL DROP OBJ\-> f STOF
\>>
\>>
65.1 ASN

Fraction 'a/b+c/(d×e)' to decimal/reduced fraction/many digits:
\<< DUP 0 0 0 RCLF \-> x1 x2 x21 num f
\<< RAD -105 CF x1 \->STR "." "" SREPL 0 ==
IF
THEN DROP
ELSE OBJ\-> 'x2' STO x2 x1 / \->NUM LOG DUP FP 0 \=/
IF
THEN DROP "Instead of decimals (ab.c),

Try fractions
('abc/10') !" DOERR
END \->STR "." "" SREPL DROP OBJ\-> ALOG 'x21' STO
IF x21 1 >
THEN x2 x21 /
ELSE
IF x21 1 <
THEN x2 x21 INV *
ELSE x2
END
END \->STR "." "" SREPL DROP OBJ\->
END DUP EXPAND DUP2 SAME DROPN DUP \->NUM DUP 'num' STO num ABS 100000000000 > num FP 0 \=/ OR
IF
THEN OVER 10 100 ^ * PROPFRAC PROPFRAC -105 SF DUP TYPE 9 ==
IF
THEN OBJ\-> 3 DROPN
END
ELSE DROP
END f STOF
\>>
\>>
65.3 ASN

Regards,
Gil
HP49-50G
Two assignment user keys
New slight change in both of them.
In bold below, right at the beginning.

1st assignment key 65.1
Decimals to fraction:
\<< RCLF \-> x f
\<< -3 CF RAD x TYPE 9 \=/
IF
THEN x DUP DUP ABS 1 <
IF
THEN \->Q
ELSE \->Q DUP PROPFRAC
END
ELSE x DUP PROPFRAC DUP2 SAME DROPN
END \->STR "+-" "-" SREPL DROP OBJ\-> f STOF
\>>
\>>
65.1 ASN
Example .8 returns '4/5'

1st assignment key 65.3
Fraction to fractions & decimals
\<< DUP 0 0 0 RCLF \-> x1 x2 x21 num f
\<< RAD -3 CF -105 CF x1 \->STR "." "" SREPL 0 ==

IF
THEN DROP
ELSE OBJ\-> 'x2' STO x2 x1 / \->NUM LOG DUP FP 0 \=/
IF
THEN DROP "Instead of decimals (ab.c),

Try fractions
('abc/10') !" DOERR
END \->STR "." "" SREPL DROP OBJ\-> ALOG 'x21' STO
IF x21 1 >
THEN x2 x21 /
ELSE
IF x21 1 <
THEN x2 x21 INV *
ELSE x2
END
END \->STR "." "" SREPL DROP OBJ\->
END DUP EXPAND DUP2 SAME DROPN DUP \->NUM DUP 'num' STO num ABS 100000000000 > num FP 0 \=/ OR
IF
THEN OVER 10 100 ^ * PROPFRAC PROPFRAC -105 SF DUP TYPE 9 ==
IF
THEN OBJ\-> 3 DROPN
END
ELSE DROP
END f STOF
\>>
\>>
65.3 ASN
Example
'77/13+99/31' will return the 4 lines/stacks:
'77/13+99/31' (stack level 4)
'3674/403' (stack level 3)
9.11663 (stack level 2)
91166253101736972704714640198511166253101736972704714640198511166253101736972704​714640198511166253101 (stack level 1).

Regards,
Gil
One more improvement in assignment user key 65.3

i.e. the addition of the single STD instruction right at the beginning

for 'fractions' => irreductible fraction & many decimals.

Before that, if you wrote
4 FIX
.218
'7/9'
*
you would get '0.2180*(7/9)'.
And executing just after that
LEFT-SHIFT USER
RIGHT-SHIFT DIVISION-KEY
would give an error.

Thanks to the STD instruction, right at the beginning, the problem is easily solved.

Here the new, full code, in bold the change :

\<< DUP 0 0 0 RCLF \-> x1 x2 x21 num f

\<< RAD STD -3 CF -105 CF x1 \->STR "." "" SREPL 0 ==
IF
THEN DROP
ELSE OBJ\-> 'x2' STO x2 x1 / \->NUM LOG DUP FP 0 \=/
IF
THEN DROP "Instead of decimals (ab.c),

Try fractions
('abc/10') !" DOERR
END \->STR "." "" SREPL DROP OBJ\-> ALOG 'x21' STO
IF x21 1 >
THEN x2 x21 /
ELSE
IF x21 1 <
THEN x2 x21 INV *
ELSE x2
END
END \->STR "." "" SREPL DROP OBJ\->
END DUP EXPAND DUP2 SAME DROPN DUP \->NUM DUP 'num' STO num ABS 100000000000 > num FP 0 \=/ OR
IF
THEN OVER 10 100 ^ * PROPFRAC PROPFRAC -105 SF DUP TYPE 9 ==
IF
THEN OBJ\-> 3 DROPN
END
ELSE DROP
END f STOF
\>>
\>>
65.3 ASN

Regards,
Gil
Pages: 1 2
Reference URL's
• HP Forums: https://www.hpmuseum.org/forum/index.php
• :