EBBases Script
Webb - all rights reserved - ©2004
spacer
Author - Eric Backus
Email: eric_backus@agilent.com
Webpage:

Summary: Base conversions, supporting arbitrary word lengths,
signed and unsigned base 10, and integer overflow and underflow.

Instructions:
EB Bases RPN script

This is an implementation of a
"computer science" calculator.  It
supports switching between bases,
setting word length, and provides
basic bit-wise operations.

Why another "Bases" script?

The scripts I've seen support only
unsigned 32-bit values.  This
script allows setting arbitrary
word lengths (up to 32 bits), and
distinguishes between unsigned
base 10 and signed base 10.  This
script also deals properly with
integer overflow and underflow.
For example, -1 becomes 2^32-1,
while 2^32+1 becomes 1, assuming
the current word size is unsigned
32 bits.

This script also provides both
arithmetic and logical shift-right
operators.

This script re-maps some of the
"hard" keys (the /, *, -, +, x^-1,
y^x, sqrt(x), and x^2 keys), so
that those keys round their inputs
to the nearest integer, and they
fix their output to obey the
current word length and sign flag.

The Enter key is also re-mapped to
convert anything entered to obey
the current word length and sign
flag.

Because x^-1 is not useful for
integer math, this key is
re-mapped to do bit complement.

Finally, if the the sign flag is
not set, the +/- key is re-mapped
to negate the top of stack (RPN
otherwise makes +/- do nothing in
this case).

If you don't like the re-mapping
of the keys, comment out the
second line of the script.


Code:

I put my comments before the start
of the RPN script, so that I can
keep the RPN stuff less than 1000
bytes, so that the palm clipboard
can deal with it.

Internal variables:
a: word size
b: 2^a
c: sign flag

Internal functions:
{b} Re-maps some of the "hard"
keys.
{c} Switches back to base 10 when
leaving EB Bases.
[r] Takes the whole part of a
number, with margin to allow for
rounding errors.
[w] Makes sure the word size is
valid, and puts 2^a in b.
[u] Makes the TOS fit the word
size and makes it unsigned.
[s] Makes the TOS fit the word
size and makes it signed.
[f] Applies either [u] or [s]
depending on the sign flag.
[W] Sets the word size, and
applies it to TOS if present.
[U] Sets the base, and sets the
sign flag to unsigned, and applies
this to TOS if present.
[S] Sets the base, and sets the
sign flag to signed, and applies
this to TOS if present.
[t] Converts the top two stack
locations to unsigned and correct
word length.  The order is left
swapped, with the presumption that
some bit operation will be done
that doesn't care about order.
[T] Sets the handled flag, enters
the user inout line, and converts
the top two stack locations based
on the sign flag and the word
length.
[O] Sets the handled flag, enters
the user inout line, and converts
the TOS based on the sign flag and
the word length.
[D] Convert the TOS based on sign
flag and word length, then
displays it.

RPN.2.c \EB Bases
{b}c(::::CT/CrCD:UhUe?1Cuxb1-^CD:::::CT*CD:CTPCrCD:UhhVUeh(Cfhv>(:g1))Ud::::CT-CD:COsCD::::xc(:COnCD):CT+CD:CO2PCD:);
{c}Ue#'10'UbUd;
[r]#'1e-13'1+*w;
[w]#'32'Vxav>(vXa)xa1<(vXa)xa#'0.5'+wXa2xaPXb;
[u]Cwxb%g10<(#'0.5'-:#'0.5'+)wg10<(xb+);
[s]Cug1xbH1->(xb-);
[f]xc(Cs:Cu);
[W]Xah(Cf);
[U]Ub0Xch(Cu);
[S]Ub1Xch(Cs);
[t]?2Cuk2Cu;
[T]UhUe?2Cfk2Cfk2;
[O]UhUe?1Cf;
[D]CfUd;
"EB Bases"
"_sd: Signed base 10" #'10'CS;
"_ud: Unsigned base 10" #'10'CU;
"_hx: Base 16" #'16'CU;
"_oc: Base 8" 8CU;
"_bn: Base 2" 2CU;
~
"_32: 32-bit words" #'32'CW;
"_16: 16-bit words" #'16'CW;
"_8b: 8-bit words" 8CW;
"_Xb: X-bit words" ?1CW;
"_BX: Base X" ?1CU;
~
"&: Bit and" Ct&Cf;
"|: Bit or|" Ct|Cf;
"^: Bit xor" Ct^Cf;
"_<: Shift left" ?1Cf2*Cf;
"_>: Logical shift right" ?1Cu2/CrCf;
"_->: Arithmetic shift right" ?1Cu1|1-Cs2/CrCf;
~
"A: 10 hex" KA;
"B: 11 hex" KB;
"C: 12 hex" KC;
"D: 13 hex" KD;
"E: 14 hex" KE;
"F: 15 hex" KF;