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