Case Study CS00012: Number representations in different bases
The problem: Sometimes in troubleshooting output it
helps to see data in various encodings (i.e. hex, octal, binary, etc.).
The solution: This case study illustrates how
Glee's base and representation serve this need
almost directly.
- Capture a string of text to be displayed in various forms
- Convert to hex and capture in h
- Convert to octal and capture in o
- Convert to binary and capture in b
- Columnize the various results int a table
- Display the table.
Note: You can cut and paste these code fragments into the code pane of
the Glee interpreter and experiment as you go along to see the actual
operations live.
The Glee code:
'Now is the time'=>t;
'0'..'9','A'..'F'[t #asc %<16 #ea'+1>']=>h; $$ Hex
t#asc %<8 #ea'->3 %*
~'=>o;
$$ Octal
t#asc %<2 #ea'->8 %* ~'=>b;
$$ Binary
t ,| h ,| o ,| b =>
output;
$$ Build Output table
output ,,(' : '(32 58 13 10 #asc))%* ,' :' $; $$ Display
The Output:
N : 4E : 116 : 01001110 :
o : 6F : 157 : 01101111 :
w : 77 : 167 : 01110111 :
: 20 : 040 : 00100000 :
i : 69 : 151 : 01101001 :
s : 73 : 163 : 01110011 :
: 20 : 040 : 00100000 :
t : 74 : 164 : 01110100 :
h : 68 : 150 : 01101000 :
e : 65 : 145 : 01100101 :
: 20 : 040 : 00100000 :
t : 74 : 164 : 01110100 :
i : 69 : 151 : 01101001 :
m : 6D : 155 : 01101101 :
e : 65 : 145 : 01100101 :
The play-by-play:
- 'Now is the time'=>t; Collect the
text under study in t.
- '0'..'9','A'..'F'[t #asc %<16
#ea'+1>']=>h; $$ Hex. Convert to hex by creating an index and
indexing from the hex characters. '0'..'9','A'..'F' creates the string of the 16
valid hex characters in the proper order...'F'[t #asc
%<16 #ea'+1>'] indexes the characters out of the string.
t #asc converts characters to their
numeric ASCII index. %<16
represents the index in base 16. #ea'+1>' takes the elements of rep which are
in origin 0 and adds 1 to make them origin 1 which Glee
uses for indexing. This two digit result is enclosed to be used as a
single unit. The resulting sequence of two number sequences is used to directly
index out the hex representation.
- t#asc %< 8 #ea'->3%* ~'=>o; $$
Octal. The octal conversion works the same as the hex
conversion except no translation is needed for the output characters. The
result is already in the valid set of digits 0 thru 7. However, depending on
the size of the number in, we get from 1 to 3 digits out. We want to pad with
leading 0's. #ea'->3%* ~' for each
sequence element, pulls on leading 0's; converts to a string; and removes
blanks. At each of these we convert to character form.
- t #asc %<2 #ea' ->8%* ~'=>b; $$
Binary. For binary, we operate in the same fashion as with
octal. However, we expect 8 binary digits per character where we only expected
3 for octal so we do an 8-right-take instead of a 3-right take.
- t ,| h ,| o ,| b => output; $$ Build
Output table . We build the output table by successively
column catenating t ,| h ... the
individual results. This really just creates sequences within sequences.
- output ,,(' : '(32 58 13 10 #asc))%* ,' :'
$; $$ Display. Here we use the dyadic sequence separation
operator ,, using a two element right
argument (' : '(32 58 13 10 #asc)). The
first element goes between elements of the inner-most sequence. In this case it
is just the colon character. On the outer sequence we want a space, a colon,
and a line feed. This is most easily formed by taking the numeric ASCII
codes (32, 58, and 10) and converting them to their character form. This three
element string is inserted between the elements of the outer sequence and
causes each character and its conversions to be displayed on a separate
line.%* ,' :' $; $$ Display At this
point we still have a sequence of sequences so we convert it to a simple
character string %* and catenate on the
final colon and display,' :' $;
This completes the example. To better understand these operators and other
things you can do with them, consult the operator pages according to the type of
data you see being operated on.