radix 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/{.ruby → .index} +36 -27
- data/DEMO.md +763 -0
- data/{HISTORY.rdoc → HISTORY.md} +31 -5
- data/LICENSE.txt +23 -0
- data/{README.rdoc → README.md} +27 -34
- data/demo/01_synopsis.md +46 -0
- data/demo/02_integer.md +256 -0
- data/demo/03_float.md +294 -0
- data/demo/04_rational.md +84 -0
- data/demo/05_base.md +78 -0
- data/demo/applique/ae.rb +3 -0
- data/demo/applique/check.rb +7 -0
- data/demo/applique/radix.rb +1 -0
- data/lib/radix.yml +36 -27
- data/lib/radix/float.rb +1 -0
- data/lib/radix/integer.rb +3 -0
- data/lib/radix/rational.rb +43 -8
- metadata +37 -15
- data/NOTICE.rdoc +0 -31
data/{.ruby → .index}
RENAMED
@@ -1,46 +1,55 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
|
2
|
+
revision: 2013
|
3
|
+
type: ruby
|
4
|
+
sources:
|
5
|
+
- var
|
4
6
|
authors:
|
5
7
|
- name: Thomas Sawyer
|
6
8
|
email: transfire@gmail.com
|
7
|
-
|
8
|
-
- holder: ''
|
9
|
-
year: '2009'
|
10
|
-
license: BSD-2-Clause
|
11
|
-
replacements: []
|
12
|
-
alternatives: []
|
9
|
+
organizations: []
|
13
10
|
requirements:
|
14
|
-
-
|
15
|
-
groups:
|
11
|
+
- groups:
|
16
12
|
- build
|
17
13
|
development: true
|
18
|
-
|
19
|
-
|
14
|
+
name: detroit
|
15
|
+
- groups:
|
20
16
|
- test
|
21
17
|
development: true
|
22
|
-
|
18
|
+
name: qed
|
23
19
|
conflicts: []
|
20
|
+
alternatives: []
|
21
|
+
resources:
|
22
|
+
- type: home
|
23
|
+
uri: http://rubyworks.github.com/radix
|
24
|
+
label: Homepage
|
25
|
+
- type: code
|
26
|
+
uri: http://github.com/rubyworks/radix
|
27
|
+
label: Source Code
|
28
|
+
- type: mail
|
29
|
+
uri: http://groups.google.com/groups/rubyworks-mailinglist
|
30
|
+
label: Mailing List
|
31
|
+
- type: bugs
|
32
|
+
uri: http://github.com/rubyworks/radix/issues
|
33
|
+
label: Issue Tracker
|
24
34
|
repositories:
|
25
|
-
-
|
35
|
+
- name: upstream
|
26
36
|
scm: git
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
uri: git://github.com/rubyworks/radix.git
|
38
|
+
categories: []
|
39
|
+
copyrights:
|
40
|
+
- holder: ''
|
41
|
+
year: '2009'
|
42
|
+
license: BSD-2-Clause
|
43
|
+
customs: []
|
44
|
+
paths:
|
45
|
+
lib:
|
46
|
+
- lib
|
37
47
|
created: '2009-07-01'
|
38
48
|
summary: Convert to and from any base.
|
39
49
|
title: Radix
|
40
|
-
version: 2.
|
50
|
+
version: 2.1.1
|
41
51
|
name: radix
|
42
52
|
description: ! "Radix is a very easy to use Ruby library for converting numbers to
|
43
53
|
and from\nany base. It supports both Integer, Float and Rational numbers, as well
|
44
54
|
as \nrepresentational string-notations that need not be in ASCII order."
|
45
|
-
|
46
|
-
date: '2011-10-23'
|
55
|
+
date: '2013-02-06'
|
data/DEMO.md
ADDED
@@ -0,0 +1,763 @@
|
|
1
|
+
= Synopsis
|
2
|
+
|
3
|
+
Radix provides the means of converting to and from any base.
|
4
|
+
For example, a number in base 256 can be represented by the array [100, 10]
|
5
|
+
(ie. 100**256 + 10**1) and easily converted to base 10.
|
6
|
+
|
7
|
+
[100,10].b(256).to_i #=> 25610
|
8
|
+
|
9
|
+
We can get an Array representation as well.
|
10
|
+
|
11
|
+
[100,10].b(256).to_a(10) #=> [2,5,6,1,0]
|
12
|
+
[100,10].b(256).to_a(62) #=> [6,41,4]
|
13
|
+
[100,10].b(256).to_a(64) #=> [6,16,10]
|
14
|
+
|
15
|
+
To get a String representation for any base use #to_s.
|
16
|
+
|
17
|
+
[100,10].b(256).to_s(10) #=> "25610"
|
18
|
+
[100,10].b(256).to_s(62) #=> "6 41 4"
|
19
|
+
[100,10].b(256).to_s(64) #=> "6 16 10"
|
20
|
+
|
21
|
+
Notice that anything above base 10 is seperated by a space divider. The divider
|
22
|
+
can be changed by providing a second argument.
|
23
|
+
|
24
|
+
[100,10].b(256).to_s(64, ':') #=> "6:16:10"
|
25
|
+
|
26
|
+
A string representation of a number can be converted upto base 62 (B62).
|
27
|
+
|
28
|
+
"10".b(62).to_s(10) #=> "62"
|
29
|
+
"zz".b(62).to_s(10) #=> "3843"
|
30
|
+
|
31
|
+
To encode a number with a base greater than 10, use an Array base. Radix
|
32
|
+
provides a built-in set of these, such as `BASE::B62`.
|
33
|
+
|
34
|
+
[100,10].b(256).to_s(Radix::BASE::B62) #=> "6f4"
|
35
|
+
|
36
|
+
To use a custom character set, use an array of characters as the base
|
37
|
+
rather than an integer. For example we can convert a base 10 number
|
38
|
+
to another base 10 number but useing a different encoding.
|
39
|
+
|
40
|
+
base = %w[Q W E R T Y U I O U]
|
41
|
+
|
42
|
+
"10".b(10).to_a(base) #=> ["W", "Q"]
|
43
|
+
|
44
|
+
"10".b(10).to_s(base) #=> "WQ"
|
45
|
+
|
46
|
+
All of the above holds equally for floating point numbers.
|
47
|
+
|
48
|
+
= Radix Integer
|
49
|
+
|
50
|
+
Radix provides an Integer class for working with integers in various bases.
|
51
|
+
|
52
|
+
require 'radix'
|
53
|
+
|
54
|
+
== Initialization
|
55
|
+
|
56
|
+
Radix::Integer's initializer can accept either an Integer, String or
|
57
|
+
Array as a value and an integer base.
|
58
|
+
|
59
|
+
Give an integer value, it will automatically be converted to the base
|
60
|
+
specified.
|
61
|
+
|
62
|
+
check do |integer, base, digits|
|
63
|
+
r = Radix::Integer.new(integer, base)
|
64
|
+
r.digits.assert == digits
|
65
|
+
end
|
66
|
+
|
67
|
+
ok 8, 2, [1,0,0,0]
|
68
|
+
ok 4, 2, [1,0,0]
|
69
|
+
ok 8, 10, [8]
|
70
|
+
ok 10, 10, [1, 0]
|
71
|
+
ok 8, 16, [8]
|
72
|
+
ok 16, 16, [1, 0]
|
73
|
+
|
74
|
+
Where as a String value is taken to already be in the base given.
|
75
|
+
|
76
|
+
ok "1000", 2, [1,0,0,0]
|
77
|
+
ok "100", 2, [1,0,0]
|
78
|
+
|
79
|
+
ok "8", 10, [8]
|
80
|
+
ok "10", 10, [1, 0]
|
81
|
+
ok "8", 16, [8]
|
82
|
+
ok "10", 16, [1, 0]
|
83
|
+
|
84
|
+
And an Array is also taken to be in the base given.
|
85
|
+
|
86
|
+
ok %w[1 0 0 0], 2, [1,0,0,0]
|
87
|
+
ok %w[ 1 0 0], 2, [1,0,0]
|
88
|
+
|
89
|
+
ok %w[ 8], 10, [8]
|
90
|
+
ok %w[1 0], 10, [1, 0]
|
91
|
+
ok %w[ 8], 16, [8]
|
92
|
+
ok %w[1 0], 16, [1, 0]
|
93
|
+
|
94
|
+
Integers can also be negative, rather than positive. In each case
|
95
|
+
just prepend the value with a minus sign.
|
96
|
+
|
97
|
+
check do |integer, base, digits|
|
98
|
+
r = Radix::Integer.new(integer, base)
|
99
|
+
r.digits.assert == digits
|
100
|
+
r.assert.negative?
|
101
|
+
end
|
102
|
+
|
103
|
+
ok -8, 2, ['-',1,0,0,0]
|
104
|
+
ok "-1000", 2, ['-',1,0,0,0]
|
105
|
+
ok %w[- 1 0 0 0], 2, ['-',1,0,0,0]
|
106
|
+
|
107
|
+
If a value has a digit outside of the range of the base an ArgumentError
|
108
|
+
will be raised.
|
109
|
+
|
110
|
+
expect ArgumentError do
|
111
|
+
Radix::Integer.new('9', 2)
|
112
|
+
end
|
113
|
+
|
114
|
+
Radix provides a convenience extension method to Integer, String and Array
|
115
|
+
called #b, to more easily initialize a Radix numeric object. The method simply
|
116
|
+
passes the receiver on to `Radix::Integer#new`.
|
117
|
+
|
118
|
+
check do |integer, base, digits|
|
119
|
+
r = integer.b(base)
|
120
|
+
r.assert.is_a?(Radix::Integer)
|
121
|
+
r.digits.assert == digits
|
122
|
+
end
|
123
|
+
|
124
|
+
ok 8, 2, [1,0,0,0]
|
125
|
+
ok 4, 2, [1,0,0]
|
126
|
+
|
127
|
+
ok "1000", 2, [1,0,0,0]
|
128
|
+
ok "100", 2, [1,0,0]
|
129
|
+
|
130
|
+
ok %w"1 0 0 0", 2, [1,0,0,0]
|
131
|
+
ok %w"1 0 0", 2, [1,0,0]
|
132
|
+
|
133
|
+
== Conversion
|
134
|
+
|
135
|
+
Radix integers can ve converted to other bases with the #convert method.
|
136
|
+
|
137
|
+
b = "1000".b(2)
|
138
|
+
d = b.convert(10)
|
139
|
+
d.digits.assert == [8]
|
140
|
+
|
141
|
+
We can convert a Radix::Integer to a regular base-10 Integer with the #to_i
|
142
|
+
method.
|
143
|
+
|
144
|
+
b = "1000".b(2)
|
145
|
+
d = b.to_i
|
146
|
+
d.assert == 8
|
147
|
+
|
148
|
+
== Equality
|
149
|
+
|
150
|
+
Radix extend the Integer, String and Array classes with the #b method
|
151
|
+
which simplifies the creation of Radix::Integer instances. The following
|
152
|
+
return the equivalent instance of Radix::Integer.
|
153
|
+
|
154
|
+
a = 8.b(2)
|
155
|
+
b = "1000".b(2)
|
156
|
+
c = [1, 0, 0, 0].b(2)
|
157
|
+
|
158
|
+
a.assert == b
|
159
|
+
b.assert == c
|
160
|
+
c.assert == a
|
161
|
+
|
162
|
+
a.assert == 8
|
163
|
+
b.assert == 8
|
164
|
+
c.assert == 8
|
165
|
+
|
166
|
+
More stringent equality can be had from #eql?, in which the other integer
|
167
|
+
must be a Radix::Integer too.
|
168
|
+
|
169
|
+
a.assert.eql?(b)
|
170
|
+
a.refute.eql?(8)
|
171
|
+
|
172
|
+
== Operations
|
173
|
+
|
174
|
+
Radix::Integer supports all the usual mathematical operators.
|
175
|
+
|
176
|
+
=== Addition
|
177
|
+
|
178
|
+
check do |a, b, x|
|
179
|
+
(a + b).assert == x
|
180
|
+
end
|
181
|
+
|
182
|
+
ok "1000".b(2), "0010".b(2), "1010".b(2)
|
183
|
+
ok "1000".b(2), "2".b(8), "1010".b(2)
|
184
|
+
ok "1000".b(2), "2".b(8), "10".b(10)
|
185
|
+
|
186
|
+
A more complex example.
|
187
|
+
|
188
|
+
x = "AZ42".b(62) + "54".b(10)
|
189
|
+
x.assert == "2518124".b(10)
|
190
|
+
x.assert == 2518124
|
191
|
+
|
192
|
+
Adding negative integers will, of course, be akin to subtraction.
|
193
|
+
|
194
|
+
ok "1000".b(2), "-0010".b(2), "110".b(2)
|
195
|
+
ok "1000".b(2), "-2".b(8), "110".b(2)
|
196
|
+
ok "1000".b(2), "-2".b(8), "6".b(10)
|
197
|
+
|
198
|
+
ok "-1000".b(2), "0010".b(2), "-110".b(2)
|
199
|
+
ok "-1000".b(2), "2".b(8), "-110".b(2)
|
200
|
+
ok "-1000".b(2), "2".b(8), "-6".b(10)
|
201
|
+
|
202
|
+
ok "-1000".b(2), "-0010".b(2), "-1010".b(2)
|
203
|
+
ok "-1000".b(2), "-2".b(8), "-1010".b(2)
|
204
|
+
ok "-1000".b(2), "-2".b(8), "-10".b(10)
|
205
|
+
|
206
|
+
=== Subtraction
|
207
|
+
|
208
|
+
check do |a, b, x|
|
209
|
+
(a - b).assert == x
|
210
|
+
end
|
211
|
+
|
212
|
+
ok "1000".b(2), "10".b(2), "0110".b(2)
|
213
|
+
ok "1000".b(2), "2".b(8), "0110".b(2)
|
214
|
+
ok "1000".b(2), "2".b(8), "6".b(8)
|
215
|
+
ok "1000".b(2), "2".b(8), "6".b(10)
|
216
|
+
|
217
|
+
A more complex example.
|
218
|
+
|
219
|
+
x = "AZ42".b(62) - "54".b(10)
|
220
|
+
x.assert == "2518016".b(10)
|
221
|
+
x.assert == 2518016
|
222
|
+
|
223
|
+
=== Multiplication
|
224
|
+
|
225
|
+
check do |a, b, x|
|
226
|
+
(a * b).assert == x
|
227
|
+
end
|
228
|
+
|
229
|
+
ok "1000".b(2), "10".b(2), "10000".b(2)
|
230
|
+
ok "1000".b(2), "2".b(8), "10000".b(2)
|
231
|
+
ok "1000".b(2), "2".b(8), "20".b(8)
|
232
|
+
ok "1000".b(2), "2".b(8), "16".b(10)
|
233
|
+
|
234
|
+
A more complex example.
|
235
|
+
|
236
|
+
x = "Z42".b(62) * "4".b(10)
|
237
|
+
x.assert == "539160".b(10)
|
238
|
+
x.assert == 539160
|
239
|
+
|
240
|
+
=== Division
|
241
|
+
|
242
|
+
check do |a, b, x|
|
243
|
+
(a / b).assert == x
|
244
|
+
end
|
245
|
+
|
246
|
+
ok "1000".b(2), "10".b(2), "100".b(2)
|
247
|
+
ok "1000".b(2), "2".b(8), "100".b(2)
|
248
|
+
ok "1000".b(2), "2".b(8), "4".b(8)
|
249
|
+
ok "1000".b(2), "2".b(8), "4".b(10)
|
250
|
+
|
251
|
+
A more complex example.
|
252
|
+
|
253
|
+
x = "AZ42".b(62) / "54".b(10)
|
254
|
+
x.assert == "46630".b(10)
|
255
|
+
x.assert == 46630
|
256
|
+
|
257
|
+
=== Power
|
258
|
+
|
259
|
+
check do |a, b, x|
|
260
|
+
(a ** b).assert == x
|
261
|
+
end
|
262
|
+
|
263
|
+
ok "1000".b(2), "10".b(2), 64
|
264
|
+
|
265
|
+
=== Modulo
|
266
|
+
|
267
|
+
check do |a, b, x|
|
268
|
+
(a % b).assert == x
|
269
|
+
end
|
270
|
+
|
271
|
+
ok "1000".b(2), "10".b(2), 0
|
272
|
+
ok "1000".b(2), "11".b(2), 2
|
273
|
+
|
274
|
+
=== Bitwise Shift
|
275
|
+
|
276
|
+
check do |a, b, x|
|
277
|
+
(a << b).assert == x
|
278
|
+
end
|
279
|
+
|
280
|
+
ok "10".b(2), "10".b(2), "1000".b(2)
|
281
|
+
ok "10".b(2), 2, "1000".b(2)
|
282
|
+
ok "10".b(2), 2, 8
|
283
|
+
|
284
|
+
=== Bitwise AND
|
285
|
+
|
286
|
+
check do |a, b, x|
|
287
|
+
(a & b).assert == x
|
288
|
+
end
|
289
|
+
|
290
|
+
ok "1010".b(2), "10".b(2), "10".b(2)
|
291
|
+
ok "1010".b(2), "2".b(8), "10".b(2)
|
292
|
+
|
293
|
+
== Coerce
|
294
|
+
|
295
|
+
When a Radix::Integer is the operand in an operation against a regular
|
296
|
+
Ruby Integer, the calculation should still work via #coerce.
|
297
|
+
|
298
|
+
check do |a, b, x|
|
299
|
+
(a + b).assert == x
|
300
|
+
end
|
301
|
+
|
302
|
+
ok 10, "10".b(2), "12".b(10)
|
303
|
+
|
304
|
+
|
305
|
+
= Radix Float
|
306
|
+
|
307
|
+
Radix provides a Float class for working with rational numbers in various bases.
|
308
|
+
Actually Radix's implementation of Float is a <i>fixed point</i>, not a
|
309
|
+
<i>floating point</i>.
|
310
|
+
|
311
|
+
require 'radix'
|
312
|
+
|
313
|
+
D = Radix::DOT
|
314
|
+
|
315
|
+
== Initialization
|
316
|
+
|
317
|
+
Radix::Float's initializer can accept either an Integer, Float, String or
|
318
|
+
Array as a value and an integer base.
|
319
|
+
|
320
|
+
Give a float value, it will automatically be converted to the base
|
321
|
+
specified.
|
322
|
+
|
323
|
+
check do |float, base, digits|
|
324
|
+
r = Radix::Float.new(float, base)
|
325
|
+
r.digits.assert == digits
|
326
|
+
end
|
327
|
+
|
328
|
+
ok 8.5, 2, [1,0,0,0,D,1]
|
329
|
+
ok 4.5, 2, [ 1,0,0,D,1]
|
330
|
+
|
331
|
+
ok 8.1, 10, [ 8,D,1]
|
332
|
+
ok 10.2, 10, [1,0,D,2]
|
333
|
+
#ok 8.1, 16, [ 8,D,1]
|
334
|
+
#ok 16.1, 16, [1,0,D,1]
|
335
|
+
|
336
|
+
Give an integer value, it will automatically be converted to the base
|
337
|
+
specified and given a fraction part set to zero.
|
338
|
+
|
339
|
+
check do |float, base, digits|
|
340
|
+
r = Radix::Float.new(float, base)
|
341
|
+
r.digits.assert == digits
|
342
|
+
end
|
343
|
+
|
344
|
+
ok 8, 2, [1,0,0,0,D,0]
|
345
|
+
ok 4, 2, [ 1,0,0,D,0]
|
346
|
+
|
347
|
+
ok 8, 10, [ 8,D,0]
|
348
|
+
ok 10, 10, [1,0,D,0]
|
349
|
+
ok 8, 16, [ 8,D,0]
|
350
|
+
ok 16, 16, [1,0,D,0]
|
351
|
+
|
352
|
+
Given a float, the same will occur.
|
353
|
+
|
354
|
+
ok 8.0, 2, [1,0,0,0,D,0]
|
355
|
+
ok 4.0, 2, [ 1,0,0,D,0]
|
356
|
+
|
357
|
+
ok 8.0, 10, [ 8,D,0]
|
358
|
+
ok 10.0, 10, [1,0,D,0]
|
359
|
+
ok 8.0, 16, [ 8,D,0]
|
360
|
+
ok 16.0, 16, [1,0,D,0]
|
361
|
+
|
362
|
+
Where as a String value is taken to already be in the base given.
|
363
|
+
|
364
|
+
ok "1000", 2, [1,0,0,0,D,0]
|
365
|
+
ok "100", 2, [ 1,0,0,D,0]
|
366
|
+
|
367
|
+
ok "8", 10, [ 8,D,0]
|
368
|
+
ok "10", 10, [1,0,D,0]
|
369
|
+
ok "8", 16, [ 8,D,0]
|
370
|
+
ok "10", 16, [1,0,D,0]
|
371
|
+
|
372
|
+
ok "1000.0", 2, [1,0,0,0,D,0]
|
373
|
+
ok "100.0", 2, [ 1,0,0,D,0]
|
374
|
+
|
375
|
+
ok "8.0", 10, [ 8,D,0]
|
376
|
+
ok "10.0", 10, [1,0,D,0]
|
377
|
+
ok "8.0", 16, [ 8,D,0]
|
378
|
+
ok "10.0", 16, [1,0,D,0]
|
379
|
+
|
380
|
+
And an Array is also taken to be in the base given.
|
381
|
+
|
382
|
+
ok %w[1 0 0 0], 2, [1,0,0,0,D,0]
|
383
|
+
ok %w[ 1 0 0], 2, [ 1,0,0,D,0]
|
384
|
+
|
385
|
+
ok %w[ 8], 10, [ 8,D,0]
|
386
|
+
ok %w[1 0], 10, [1,0,D,0]
|
387
|
+
ok %w[ 8], 16, [ 8,D,0]
|
388
|
+
ok %w[1 0], 16, [1,0,D,0]
|
389
|
+
|
390
|
+
Passing in an Array with a fraction part, either the DOT constant can be used,
|
391
|
+
which is simply the symbol :'.', or the string '.' can be used.
|
392
|
+
|
393
|
+
ok %w[1 0 0 0 . 0], 2, [1,0,0,0,D,0]
|
394
|
+
ok %w[ 1 0 0 . 0], 2, [ 1,0,0,D,0]
|
395
|
+
|
396
|
+
ok %w[ 8 . 0], 10, [ 8,D,0]
|
397
|
+
ok %w[1 0 . 0], 10, [1,0,D,0]
|
398
|
+
ok %w[ 8 . 0], 16, [ 8,D,0]
|
399
|
+
ok %w[1 0 . 0], 16, [1,0,D,0]
|
400
|
+
|
401
|
+
Integers can also be negative, rather than positive. In each case
|
402
|
+
just prepend the value with a minus sign.
|
403
|
+
|
404
|
+
check do |float, base, digits|
|
405
|
+
r = Radix::Float.new(float, base)
|
406
|
+
r.digits.assert = digits
|
407
|
+
r.assert.negative?
|
408
|
+
end
|
409
|
+
|
410
|
+
ok( -8, 2, ['-',1,0,0,0,D,0])
|
411
|
+
ok( "-1000", 2, ['-',1,0,0,0,D,0])
|
412
|
+
ok( %w[- 1 0 0 0], 2, ['-',1,0,0,0,D,0])
|
413
|
+
|
414
|
+
If a value has a digit outside of the range of the base an ArgumentError
|
415
|
+
will be raised.
|
416
|
+
|
417
|
+
expect ArgumentError do
|
418
|
+
Radix::Float.new('9', 2)
|
419
|
+
end
|
420
|
+
|
421
|
+
Radix provides a convenience extension method to Integer, String and Array
|
422
|
+
called #b, to more easily initialize a Radix numeric object. The method simply
|
423
|
+
passes the receiver on to `Radix::Integer#new`.
|
424
|
+
|
425
|
+
check do |float, base, digits|
|
426
|
+
r = float.b(base)
|
427
|
+
r.assert.is_a?(Radix::Float)
|
428
|
+
r.digits.assert = digits
|
429
|
+
end
|
430
|
+
|
431
|
+
ok 8.0, 2, [1,0,0,0,D,0]
|
432
|
+
ok 4.0, 2, [ 1,0,0,D,0]
|
433
|
+
|
434
|
+
ok "1000.0", 2, [1,0,0,0,D,0]
|
435
|
+
ok "100.0", 2, [ 1,0,0,D,0]
|
436
|
+
|
437
|
+
ok %w"1 0 0 0 . 0", 2, [1,0,0,0,D,0]
|
438
|
+
ok %w"1 0 0 . 0", 2, [ 1,0,0,D,0]
|
439
|
+
|
440
|
+
== Conversion
|
441
|
+
|
442
|
+
Radix integers can ve converted to other bases with the #convert method.
|
443
|
+
|
444
|
+
b = "1000.0".b(2)
|
445
|
+
d = b.convert(10)
|
446
|
+
d.digits.assert == [8,D,0]
|
447
|
+
|
448
|
+
We can convert a Radix::Float to a regular base-10 Float with the #to_f
|
449
|
+
method.
|
450
|
+
|
451
|
+
b = "1000.0".b(2)
|
452
|
+
d = b.to_f
|
453
|
+
d.assert == 8.0
|
454
|
+
|
455
|
+
We can convert a Radix::Float to a regular base-10 Integer with the #to_i
|
456
|
+
method.
|
457
|
+
|
458
|
+
b = "1000.0".b(2)
|
459
|
+
d = b.to_i
|
460
|
+
d.assert == 8
|
461
|
+
|
462
|
+
=== Equality
|
463
|
+
|
464
|
+
Radix extend the Integer, String and Array classes with the #b method
|
465
|
+
which simplifies the creation of Radix::Float instances. The following
|
466
|
+
return the equivalent instance of Radix::Float.
|
467
|
+
|
468
|
+
a = 8.0.b(2)
|
469
|
+
b = "1000.0".b(2)
|
470
|
+
c = [1,0,0,0,'.',0].b(2)
|
471
|
+
|
472
|
+
a.assert = b
|
473
|
+
b.assert = c
|
474
|
+
c.assert = a
|
475
|
+
|
476
|
+
a.assert = 8.0
|
477
|
+
b.assert = 8.0
|
478
|
+
c.assert = 8.0
|
479
|
+
|
480
|
+
More stringent equality can be had from #eql?, in which the other integer
|
481
|
+
must be a Radix::Integer too.
|
482
|
+
|
483
|
+
a.assert.eql?(b)
|
484
|
+
a.refute.eql?(8.0)
|
485
|
+
|
486
|
+
== Operations
|
487
|
+
|
488
|
+
Radix::Float supports all the usual mathematical operators.
|
489
|
+
|
490
|
+
=== Addition
|
491
|
+
|
492
|
+
check do |a, b, x|
|
493
|
+
(a + b).assert = x
|
494
|
+
end
|
495
|
+
|
496
|
+
ok "1000.0".b(2), "0010.0".b(2), "1010.0".b(2)
|
497
|
+
ok "1000.0".b(2), "2.0".b(8), "1010.0".b(2)
|
498
|
+
ok "1000.0".b(2), "2.0".b(8), "10.0".b(10)
|
499
|
+
|
500
|
+
A more complex example.
|
501
|
+
|
502
|
+
x = "AZ42.0".b(62) + "54.0".b(10)
|
503
|
+
x.assert == "2518124.0".b(10)
|
504
|
+
x.assert == 2518124.0
|
505
|
+
|
506
|
+
Adding negative integers will, of course, be akin to subtraction.
|
507
|
+
|
508
|
+
ok "1000.0".b(2), "-0010".b(2), "110.0".b(2)
|
509
|
+
ok "1000.0".b(2), "-2".b(8), "110.0".b(2)
|
510
|
+
ok "1000.0".b(2), "-2".b(8), "6.0".b(10)
|
511
|
+
|
512
|
+
ok "-1000.0".b(2), "0010".b(2), "-110.0".b(2)
|
513
|
+
ok "-1000.0".b(2), "2".b(8), "-110.0".b(2)
|
514
|
+
ok "-1000.0".b(2), "2".b(8), "-6.0".b(10)
|
515
|
+
|
516
|
+
ok "-1000.0".b(2), "-0010".b(2), "-1010.0".b(2)
|
517
|
+
ok "-1000.0".b(2), "-2".b(8), "-1010.0".b(2)
|
518
|
+
ok "-1000.0".b(2), "-2".b(8), "-10.0".b(10)
|
519
|
+
|
520
|
+
=== Subtraction
|
521
|
+
|
522
|
+
check do |a, b, x|
|
523
|
+
(a - b).assert == x
|
524
|
+
end
|
525
|
+
|
526
|
+
ok "1000.0".b(2), "10".b(2), "110.0".b(2)
|
527
|
+
ok "1000.0".b(2), "2".b(8), "110.0".b(2)
|
528
|
+
ok "1000.0".b(2), "2".b(8), "6.0".b(8)
|
529
|
+
ok "1000.0".b(2), "2".b(8), "6.0".b(10)
|
530
|
+
|
531
|
+
A more complex example.
|
532
|
+
|
533
|
+
x = "AZ42.0".b(62) - "54".b(10)
|
534
|
+
x.assert == "2518016.0".b(10)
|
535
|
+
x.assert == 2518016.0
|
536
|
+
|
537
|
+
=== Multiplication
|
538
|
+
|
539
|
+
check do |a, b, x|
|
540
|
+
(a * b).assert = x
|
541
|
+
end
|
542
|
+
|
543
|
+
ok "1000.0".b(2), "10".b(2), "10000.0".b(2)
|
544
|
+
ok "1000.0".b(2), "2".b(8), "10000.0".b(2)
|
545
|
+
ok "1000.0".b(2), "2".b(8), "20.0".b(8)
|
546
|
+
ok "1000.0".b(2), "2".b(8), "16.0".b(10)
|
547
|
+
|
548
|
+
A more complex example.
|
549
|
+
|
550
|
+
x = "Z42.0".b(62) * "4.0".b(10)
|
551
|
+
x.assert == "539160.0".b(10)
|
552
|
+
x.assert == 539160.0
|
553
|
+
|
554
|
+
=== Division
|
555
|
+
|
556
|
+
check do |a, b, x|
|
557
|
+
(a / b).assert = x
|
558
|
+
end
|
559
|
+
|
560
|
+
ok "1000.0".b(2), "10".b(2), "100.0".b(2)
|
561
|
+
ok "1000.0".b(2), "2".b(8), "100.0".b(2)
|
562
|
+
ok "1000.0".b(2), "2".b(8), "4.0".b(8)
|
563
|
+
ok "1000.0".b(2), "2".b(8), "4.0".b(10)
|
564
|
+
|
565
|
+
A more complex example.
|
566
|
+
|
567
|
+
x = "AZ40.0".b(62) / "62.0".b(10)
|
568
|
+
x.assert == "40614.0".b(10)
|
569
|
+
x.assert == 40614.0
|
570
|
+
|
571
|
+
=== Power
|
572
|
+
|
573
|
+
check do |a, b, x|
|
574
|
+
(a ** b).assert == x
|
575
|
+
end
|
576
|
+
|
577
|
+
ok "1000.0".b(2), "10.0".b(2), 64.0
|
578
|
+
|
579
|
+
=== Modulo
|
580
|
+
|
581
|
+
check do |a, b, x|
|
582
|
+
(a % b).assert == x
|
583
|
+
end
|
584
|
+
|
585
|
+
ok "1000.0".b(2), "10".b(2), 0
|
586
|
+
ok "1000.0".b(2), "11".b(2), 2
|
587
|
+
|
588
|
+
== Coerce
|
589
|
+
|
590
|
+
When a Radix::Integer is the operand in an operation against a regular
|
591
|
+
Ruby Integer, the calculation should still work via #coerce.
|
592
|
+
|
593
|
+
check do |a, b, x|
|
594
|
+
(a + b).assert == x
|
595
|
+
end
|
596
|
+
|
597
|
+
ok 10.0, "10".b(2), "12".b(10)
|
598
|
+
|
599
|
+
|
600
|
+
= Radix Rational
|
601
|
+
|
602
|
+
require 'radix'
|
603
|
+
|
604
|
+
== Initialization
|
605
|
+
|
606
|
+
Radix::Rational's initializer takes a numerator and a denominator,
|
607
|
+
either of which can be an Integer, Float, String or Array along witha
|
608
|
+
an integer base.
|
609
|
+
|
610
|
+
Give a integer value, it will automatically be converted to the base
|
611
|
+
specified.
|
612
|
+
|
613
|
+
check do |num, dem, base, eqf|
|
614
|
+
r = Radix::Rational.new(num, dem, base)
|
615
|
+
r.assert == eqf
|
616
|
+
end
|
617
|
+
|
618
|
+
ok 1, 2, 2, 0.5
|
619
|
+
ok 1, 1, 2, 1.0
|
620
|
+
|
621
|
+
ok 8, 1, 10, 8.0
|
622
|
+
ok 8, 5, 10, 1.6
|
623
|
+
ok 8, 8, 10, 1.0
|
624
|
+
|
625
|
+
ok 10, 1, 10, 10.0
|
626
|
+
ok 10, 2, 10, 5.0
|
627
|
+
ok 10, 5, 10, 2.0
|
628
|
+
|
629
|
+
ok 8, 1, 16, 8.0
|
630
|
+
ok 16, 1, 16, 16.0
|
631
|
+
|
632
|
+
== Reduction
|
633
|
+
|
634
|
+
check do |a, x|
|
635
|
+
r = a.reduce
|
636
|
+
r.assert == x
|
637
|
+
end
|
638
|
+
|
639
|
+
ok [10,5].br(10), [2,1].br(10)
|
640
|
+
ok [30,3].br(10), [10,1].br(10)
|
641
|
+
|
642
|
+
== Operations
|
643
|
+
|
644
|
+
=== Addition
|
645
|
+
|
646
|
+
check do |a, b, x|
|
647
|
+
r = a + b
|
648
|
+
r.assert == x
|
649
|
+
end
|
650
|
+
|
651
|
+
ok [8,5].br(10), [1,2].br(10), [21,10].br(10)
|
652
|
+
|
653
|
+
ok [8,5].br(10), 1, [13,5].br(10)
|
654
|
+
|
655
|
+
ok [8,5].br(10), 0.5, [21,10].br(10)
|
656
|
+
|
657
|
+
=== Subtraction
|
658
|
+
|
659
|
+
check do |a, b, x|
|
660
|
+
r = a - b
|
661
|
+
r.assert == x
|
662
|
+
end
|
663
|
+
|
664
|
+
ok [8,5].br(10), [1,2].br(10), [11,10].br(10)
|
665
|
+
|
666
|
+
=== Multiplication
|
667
|
+
|
668
|
+
check do |a, b, x|
|
669
|
+
r = a * b
|
670
|
+
r.assert == x
|
671
|
+
end
|
672
|
+
|
673
|
+
ok [8,5].br(10), [1,2].br(10), [8,10].br(10)
|
674
|
+
|
675
|
+
=== Division
|
676
|
+
|
677
|
+
check do |a, b, x|
|
678
|
+
r = a / b
|
679
|
+
r.assert == x
|
680
|
+
end
|
681
|
+
|
682
|
+
ok [8,5].br(10), [1,2].br(10), [16,5].br(10)
|
683
|
+
|
684
|
+
|
685
|
+
= Radix::Base
|
686
|
+
|
687
|
+
The Radix::Base class is an encapsulatin of a numeric base. By creating
|
688
|
+
an instance of Base one can convert numbers to and from other bases.
|
689
|
+
|
690
|
+
require 'radix/base'
|
691
|
+
|
692
|
+
== Base Instance
|
693
|
+
|
694
|
+
First let's try something we all know, converting decimal to hexideciaml.
|
695
|
+
To do this we setup the radix base objects for each base.
|
696
|
+
|
697
|
+
b10 = Radix::Base.new(Radix::BASE::B10)
|
698
|
+
b16 = Radix::Base.new(Radix::BASE::B16)
|
699
|
+
|
700
|
+
Now we can covert from one base to the other.
|
701
|
+
|
702
|
+
b16.convert("16" , b10).should == "10"
|
703
|
+
b16.convert("160", b10).should == "A0"
|
704
|
+
b16.convert("255", b10).should == "FF"
|
705
|
+
|
706
|
+
To confirm, lets convert from hexidecimal back to decimal.
|
707
|
+
|
708
|
+
b10.convert("10", b16).should == "16"
|
709
|
+
b10.convert("A0", b16).should == "160"
|
710
|
+
b10.convert("FF", b16).should == "255"
|
711
|
+
|
712
|
+
If we are happy with standard encodings then we can simply provide an
|
713
|
+
integer base, rather than a Radix::Base object.
|
714
|
+
|
715
|
+
b10.convert("10", 16).should == "16"
|
716
|
+
b10.convert("A0", 16).should == "160"
|
717
|
+
b10.convert("FF", 16).should == "255"
|
718
|
+
|
719
|
+
Now let's try a more down to earth base, my favorite,
|
720
|
+
senary, or base six.
|
721
|
+
|
722
|
+
b6 = Radix::Base.new(0..5)
|
723
|
+
b6.convert("39", 10).should == "103"
|
724
|
+
|
725
|
+
And the notations need not be in ASCII order. Odd alternate notations
|
726
|
+
can be used as well.
|
727
|
+
|
728
|
+
b10 = Radix::Base.new([:Q, :W, :E, :R, :T, :Y, :U, :I, :O, :U])
|
729
|
+
b10.convert("FF", 16) #=> "EYY"
|
730
|
+
|
731
|
+
== Encoding and Decoding
|
732
|
+
|
733
|
+
Radix::Base instances can also be used to encode and decode strings.
|
734
|
+
|
735
|
+
b16.encode("CHARLIE").should == "434841524C4945"
|
736
|
+
b16.decode("434841524C4945").should == "CHARLIE"
|
737
|
+
|
738
|
+
== Module Methods
|
739
|
+
|
740
|
+
For further convenience, Radix::base provides functions to convert to and from
|
741
|
+
standard notations upto 62 without creating an instance of Radix::Base.
|
742
|
+
|
743
|
+
Radix.convert("10", 16, 10).should == "16"
|
744
|
+
Radix.convert("A0", 16, 10).should == "160"
|
745
|
+
Radix.convert("FF", 16, 10).should == "255"
|
746
|
+
|
747
|
+
Let's try that again with the maximum base supported.
|
748
|
+
|
749
|
+
Radix.convert( "62", 10, 62).should == "10"
|
750
|
+
Radix.convert("8814542", 10, 62).should == "az42"
|
751
|
+
|
752
|
+
Radix.convert( "10", 62, 10).should == "62"
|
753
|
+
Radix.convert( "az42", 62, 10).should == "8814542"
|
754
|
+
|
755
|
+
Finally, we will demonstrate how to convert bases larger than 62.
|
756
|
+
These can only be represented as arrays since there are not enough
|
757
|
+
latin characters to represent them.
|
758
|
+
|
759
|
+
Radix.convert_base([100, 10], 256, 10).should == [2, 5, 6, 1, 0]
|
760
|
+
Radix.convert_base([2, 5, 6, 1, 0], 10, 256).should == [100, 10]
|
761
|
+
Radix.convert_base([1, 0, 1, 0, 1], 2, 10).should == [2, 1]
|
762
|
+
|
763
|
+
|