-
Notifications
You must be signed in to change notification settings - Fork 0
/
Simple_Numbers.spin
179 lines (112 loc) · 5.69 KB
/
Simple_Numbers.spin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
'' *****************************
'' * Simple_Numbers *
'' * (c) 2006 Parallax, Inc. *
'' *****************************
''
'' Provides simple numeric conversion methods; all methods return a pointer to
'' a string.
''
'' Authors... Chip Gracey, Jon Williams
'' Updated... 29 APR 2006
CON
MAX_LEN = 64 ' 63 chars + zero terminator
VAR
long idx ' pointer into string
byte nstr[MAX_LEN] ' string for numeric data
PUB dec(value)
'' Returns pointer to signed-decimal string
clrstr(@nstr, MAX_LEN) ' clear output string
return decstr(value) ' return pointer to numeric string
PUB decf(value, width) | t_val, field
'' Returns pointer to signed-decimal, fixed-width (space padded) string
clrstr(@nstr, MAX_LEN)
width := 1 #> width <# constant(MAX_LEN - 1) ' qualify field width
t_val := ||value ' work with absolute
field~ ' clear field
repeat while t_val > 0 ' count number of digits
field++
t_val /= 10
field #>= 1 ' min field width is 1
if value < 0 ' if value is negative
field++ ' bump field for neg sign indicator
if field < width ' need padding?
repeat (width - field) ' yes
nstr[idx++] := " " ' pad with space(s)
return decstr(value)
PUB decx(value, digits) | div
'' Returns pointer to zero-padded, signed-decimal string
'' -- if value is negative, field width is digits+1
clrstr(@nstr, MAX_LEN)
digits := 1 #> digits <# 10
if (value < 0) ' negative value?
-value ' yes, make positive
nstr[idx++] := "-" ' and print sign indicator
div := 1_000_000_000 ' initialize divisor
if digits < 10 ' less than 10 digits?
repeat (10 - digits) ' yes, adjust divisor
div /= 10
value //= (div * 10) ' truncate unused digits
repeat digits
nstr[idx++] := (value / div + "0") ' convert digit to ASCII
value //= div ' update value
div /= 10 ' update divisor
return @nstr
PUB hex(value, digits)
'' Returns pointer to a digits-wide hexadecimal string
clrstr(@nstr, MAX_LEN)
return hexstr(value, digits)
PUB ihex(value, digits)
'' Returns pointer to a digits-wide, indicated (with $) hexadecimal string
clrstr(@nstr, MAX_LEN)
nstr[idx++] := "$"
return hexstr(value, digits)
PUB bin(value, digits)
'' Returns pointer to a digits-wide binary string
clrstr(@nstr, MAX_LEN)
return binstr(value, digits)
PUB ibin(value, digits)
'' Returns pointer to a digits-wide, indicated (with %) binary string
clrstr(@nstr, MAX_LEN)
nstr[idx++] := "%" ' preface with binary indicator
return binstr(value, digits)
PRI clrstr(strAddr, size)
' Clears string at strAddr
' -- also resets global character pointer (idx)
bytefill(strAddr, 0, size) ' clear string to zeros
idx~ ' reset index
PRI decstr(value) | div, z_pad
' Converts value to signed-decimal string equivalent
' -- characters written to current position of idx
' -- returns pointer to nstr
if (value < 0) ' negative value?
-value ' yes, make positive
nstr[idx++] := "-" ' and print sign indicator
div := 1_000_000_000 ' initialize divisor
z_pad~ ' clear zero-pad flag
repeat 10
if (value => div) ' printable character?
nstr[idx++] := (value / div + "0") ' yes, print ASCII digit
value //= div ' update value
z_pad~~ ' set zflag
elseif z_pad or (div == 1) ' printing or last column?
nstr[idx++] := "0"
div /= 10
return @nstr
PRI hexstr(value, digits)
' Converts value to digits-wide hexadecimal string equivalent
' -- characters written to current position of idx
' -- returns pointer to nstr
digits := 1 #> digits <# 8 ' qualify digits
value <<= (8 - digits) << 2 ' prep most significant digit
repeat digits
nstr[idx++] := lookupz((value <-= 4) & $F : "0".."9", "A".."F")
return @nstr
PRI binstr(value, digits)
' Converts value to digits-wide binary string equivalent
' -- characters written to current position of idx
' -- returns pointer to nstr
digits := 1 #> digits <# 32 ' qualify digits
value <<= 32 - digits ' prep MSB
repeat digits
nstr[idx++] := (value <-= 1) & 1 + "0" ' move digits (ASCII) to string
return @nstr