Webb - all rights reserved - ©2004

modified by Russ Webb on 2004-04-22 21:00:38 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; |