radix 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{HISTORY → HISTORY.rdoc} +14 -0
- data/LICENSE +205 -789
- data/README.rdoc +29 -28
- data/doc/01_synopsis.rdoc +60 -0
- data/doc/02_integer.rdoc +48 -0
- data/doc/03_float.rdoc +36 -0
- data/doc/04_rational.rdoc +27 -0
- data/{qed/radix_base.rdoc → doc/05_base.rdoc} +35 -24
- data/{qed → doc}/applique/ae.rb +0 -0
- data/doc/applique/qed.rb +1 -0
- data/lib/radix.rb +42 -1
- data/lib/radix/base.rb +81 -85
- data/lib/radix/float.rb +263 -0
- data/lib/radix/integer.rb +263 -0
- data/lib/radix/meta/package +2 -2
- data/lib/radix/meta/profile +5 -5
- data/lib/radix/numeric.rb +144 -0
- data/lib/radix/operator.rb +0 -30
- data/lib/radix/rational.rb +203 -0
- data/meta/package +2 -2
- data/meta/profile +5 -5
- data/test/02_integer.rdoc +256 -0
- data/test/03_float.rdoc +294 -0
- data/test/04_rational.rdoc +84 -0
- data/test/05_base.rdoc +78 -0
- data/test/applique/ae.rb +1 -0
- data/test/applique/qed.rb +1 -0
- metadata +25 -12
- data/lib/radix/number.rb +0 -84
- data/qed/radix_operator.rdoc +0 -27
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= Radix
|
2
2
|
|
3
|
-
* http://rubyworks.github.com/radix
|
4
|
-
* http://github.com/rubyworks/radix
|
3
|
+
* home: http://rubyworks.github.com/radix
|
4
|
+
* code: http://github.com/rubyworks/radix
|
5
5
|
|
6
6
|
|
7
7
|
== DESCRIPTION
|
@@ -16,14 +16,14 @@ base 62.
|
|
16
16
|
== FEATURES/ISSUES
|
17
17
|
|
18
18
|
* Convert to and from any base.
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
19
|
+
* Define custom character sets.
|
20
|
+
* Can be used to encode/decode strings.
|
21
|
+
* Very intuitive API.
|
22
22
|
|
23
23
|
|
24
24
|
== RELEASE NOTES
|
25
25
|
|
26
|
-
Please see HISTORY file.
|
26
|
+
Please see the HISTORY.rdoc file.
|
27
27
|
|
28
28
|
|
29
29
|
== SYNOPSIS
|
@@ -37,44 +37,45 @@ But Ruby reaches it's limit at base 36.
|
|
37
37
|
|
38
38
|
255.to_s(37) #=> Error
|
39
39
|
|
40
|
-
Radix provides the means of converting to and from any base.
|
41
|
-
a number in base 256, represented by the array [100, 10] (ie. 100 * 256 + 10 * 1),
|
42
|
-
can be converted to base 10 as follows:
|
40
|
+
Radix provides the means of converting to and from any base.
|
43
41
|
|
44
|
-
|
45
|
-
|
42
|
+
For example, a number in base 256 can be represented by the array [100, 10]
|
43
|
+
(ie. 100**256 + 10**1) and can be convert to base 10.
|
46
44
|
|
47
|
-
|
45
|
+
[100,10].b(256).to_a(10) #=> [2,5,6,1,0]
|
48
46
|
|
49
|
-
|
47
|
+
Or, to get a string representation for any base upto 62.
|
50
48
|
|
51
|
-
|
52
|
-
can be used.
|
49
|
+
[100,10].b(256).to_s(10) #=> "25610"
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
A string representation of anumber can be converted too, again,
|
52
|
+
upto base 62.
|
56
53
|
|
54
|
+
"10".b(62).to_s(10) #=> "62"
|
57
55
|
|
58
|
-
|
56
|
+
To use a custom character set, use an array of characters as the base
|
57
|
+
rather than an integer. For example we can convert a base 10 number
|
58
|
+
to another base 10 number using a different encoding.
|
59
59
|
|
60
|
-
|
60
|
+
base = [:Q, :W, :E, :R, :T, :Y, :U, :I, :O, :U]
|
61
|
+
|
62
|
+
"10".b(10).to_a(base) #=> [:W, :Q]
|
61
63
|
|
62
|
-
|
64
|
+
To learn more have a look at the {QED}[http://rubyworks.github.com/radix/docs/qed].
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
+
== HOW TO INSTALL
|
67
|
+
|
68
|
+
To install with RubyGems simply open a console and type:
|
66
69
|
|
67
|
-
|
68
|
-
cd radix-1.0.0
|
69
|
-
sudo setup.rb all
|
70
|
+
$ gem install radix
|
70
71
|
|
71
|
-
|
72
|
+
Radix follows {Ruby Setup}[http://rubyworks.github.com/setup] package standard.
|
72
73
|
|
73
74
|
|
74
|
-
==
|
75
|
+
== LICENSE/COPYRIGHT
|
75
76
|
|
76
77
|
Copyright (c) 2009 Thomas Sawyer
|
77
78
|
|
78
|
-
This program is ditributed unser the terms of the
|
79
|
+
This program is ditributed unser the terms of the Apache 2.0 license.
|
79
80
|
|
80
81
|
See LICENSE file for details.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
= Synopsis
|
2
|
+
|
3
|
+
Base conversions with ASCII ordered notations are easy in Ruby.
|
4
|
+
|
5
|
+
255.to_s(16) #=> "ff"
|
6
|
+
"ff".to_i(16) #=> 255
|
7
|
+
|
8
|
+
But Ruby reaches it's limit at base 36.
|
9
|
+
|
10
|
+
expect ArgumentError do
|
11
|
+
255.to_s(37)
|
12
|
+
end
|
13
|
+
|
14
|
+
Radix provides the means of converting to and from any base.
|
15
|
+
|
16
|
+
require 'radix'
|
17
|
+
|
18
|
+
For example, a number in base 256 can be represented by the array [100, 10]
|
19
|
+
(ie. 100**256 + 10**1) and easily converted to base 10.
|
20
|
+
|
21
|
+
[100,10].b(256).to_i #=> 25610
|
22
|
+
|
23
|
+
We can get an Array representation as well.
|
24
|
+
|
25
|
+
[100,10].b(256).to_a(10) #=> [2,5,6,1,0]
|
26
|
+
[100,10].b(256).to_a(62) #=> [6,41,4]
|
27
|
+
[100,10].b(256).to_a(64) #=> [6,16,10]
|
28
|
+
|
29
|
+
To get a String representation for any base use #to_s.
|
30
|
+
|
31
|
+
[100,10].b(256).to_s(10) #=> "25610"
|
32
|
+
[100,10].b(256).to_s(62) #=> "6 41 4"
|
33
|
+
[100,10].b(256).to_s(64) #=> "6 16 10"
|
34
|
+
|
35
|
+
Notice that anything above base 10 is seperated by a space divider. The divider
|
36
|
+
can be changed by providing a second argument.
|
37
|
+
|
38
|
+
[100,10].b(256).to_s(64, ':') #=> "6:16:10"
|
39
|
+
|
40
|
+
A string representation of a number can be converted upto base 62 (B62).
|
41
|
+
|
42
|
+
"10".b(62).to_s(10) #=> "62"
|
43
|
+
"zz".b(62).to_s(10) #=> "3843"
|
44
|
+
|
45
|
+
To encode a number with a base greater than 10, use an Array base. Radix
|
46
|
+
provides a built-in set of these, such as `BASE::B62`.
|
47
|
+
|
48
|
+
[100,10].b(256).to_s(Radix::BASE::B62) #=> "6f4"
|
49
|
+
|
50
|
+
To use a custom character set, use an array of characters as the base
|
51
|
+
rather than an integer. For example we can convert a base 10 number
|
52
|
+
to another base 10 number but useing a different encoding.
|
53
|
+
|
54
|
+
base = %w[Q W E R T Y U I O U]
|
55
|
+
|
56
|
+
"10".b(10).to_a(base) #=> ["W", "Q"]
|
57
|
+
|
58
|
+
"10".b(10).to_s(base) #=> "WQ"
|
59
|
+
|
60
|
+
All of the above holds equally for floating point numbers.
|
data/doc/02_integer.rdoc
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
= Radix Integer
|
2
|
+
|
3
|
+
Radix provides an Integer class for working with integers in various bases.
|
4
|
+
|
5
|
+
require 'radix'
|
6
|
+
|
7
|
+
Radix extend the Integer, String and Array classes with the #b method
|
8
|
+
which simplifies the creation of Radix::Integer instances. The following
|
9
|
+
return the equivalent instance of Radix::Integer.
|
10
|
+
|
11
|
+
a = 8.b(2)
|
12
|
+
|
13
|
+
b = "1000".b(2)
|
14
|
+
|
15
|
+
c = [1, 0, 0, 0].b(2)
|
16
|
+
|
17
|
+
a.assert == b
|
18
|
+
b.assert == c
|
19
|
+
c.assert == a
|
20
|
+
|
21
|
+
a.assert == 8
|
22
|
+
b.assert == 8
|
23
|
+
c.assert == 8
|
24
|
+
|
25
|
+
Radix integers can ve converted to other bases with the #convert method.
|
26
|
+
|
27
|
+
b = "1000".b(2)
|
28
|
+
d = b.convert(10)
|
29
|
+
d.digits.assert == [8]
|
30
|
+
|
31
|
+
Radix::Integer supports all the usual mathematical operators.
|
32
|
+
|
33
|
+
r = "1000".b(2) + "2".b(8)
|
34
|
+
r.assert == "1010".b(2)
|
35
|
+
r.assert == "12".b(8)
|
36
|
+
r.assert == "10".b(10)
|
37
|
+
|
38
|
+
A more complex example with a much higher base.
|
39
|
+
|
40
|
+
r = "AZ42".b(62) + "54".b(10)
|
41
|
+
r.assert == "2518124".b(10)
|
42
|
+
r.assert == 2518124
|
43
|
+
|
44
|
+
Work with arrays for bases greater than 62.
|
45
|
+
|
46
|
+
r = [100,10].b(256) + "54".b(10)
|
47
|
+
r.assert == "25664".b(10)
|
48
|
+
|
data/doc/03_float.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
= Radix Float
|
2
|
+
|
3
|
+
Radix provides a Float class for working with floating point numbers in
|
4
|
+
any base.
|
5
|
+
|
6
|
+
require 'radix'
|
7
|
+
|
8
|
+
With it, the #b method extends String and Array classes to
|
9
|
+
simplify all mulit-base operations.
|
10
|
+
|
11
|
+
b = "100.01".b(2)
|
12
|
+
b.to_a.assert == [1,0,0,'.',0,1]
|
13
|
+
|
14
|
+
Convert to base 10.
|
15
|
+
|
16
|
+
t = b.convert(10)
|
17
|
+
t.to_a.assert == [4,'.',2,5]
|
18
|
+
|
19
|
+
Like a Numeric class, Radix::Float's can be added, subtracted, multipled, etc.
|
20
|
+
|
21
|
+
r = "1000.01".b(2) + "2".b(8)
|
22
|
+
r.assert == "1010.01".b(2)
|
23
|
+
r.assert == "12.2".b(8)
|
24
|
+
r.assert == "10.25".b(10)
|
25
|
+
|
26
|
+
Even complex conversions are supported.
|
27
|
+
|
28
|
+
r = "AZ42".b(62) + "54".b(10)
|
29
|
+
r.assert == "2518124".b(10)
|
30
|
+
|
31
|
+
To work with bases greater than 62, use arrays. A '.' entry in the array
|
32
|
+
can be used to separate the whole from the fractional part of the number.
|
33
|
+
|
34
|
+
r = [100,10,'.',64].b(256) + "54".b(10)
|
35
|
+
r.assert == "25664.25".b(10)
|
36
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
= Radix Rational
|
2
|
+
|
3
|
+
Radix also provides a Rational class. Like the Integer and Float classes
|
4
|
+
Radix::Rational delegates to an underlying instance of Ruby standard
|
5
|
+
Rational class.
|
6
|
+
|
7
|
+
require 'radix'
|
8
|
+
|
9
|
+
b = ["100","10"].br(2)
|
10
|
+
b.assert = [2,1].br(10)
|
11
|
+
|
12
|
+
When convert to Array or String Radix::Rational uses `/` to separate
|
13
|
+
the numerator from the denominator.
|
14
|
+
|
15
|
+
b.to_a #=> [1,0,0,'/',1,0]
|
16
|
+
b.to_s #=> "100/10"
|
17
|
+
|
18
|
+
To use a custom character set, use an array of characters as the base
|
19
|
+
rather than an integer. For example we can convert a base 10 number
|
20
|
+
to another base 10 number but useing a different encoding.
|
21
|
+
|
22
|
+
base = %w[Q W E R T Y U I O U]
|
23
|
+
|
24
|
+
["10","1"].br(10).to_a(base) #=> ["W", "Q", '/', 'W']
|
25
|
+
|
26
|
+
["10","1"].br(10).to_s(base) #=> "WQ/W"
|
27
|
+
|
@@ -1,14 +1,20 @@
|
|
1
|
-
=
|
1
|
+
= Radix Base
|
2
2
|
|
3
|
-
|
3
|
+
Radix::Base encapsulates a base which can then be used to perform conversions
|
4
|
+
to and form that base.
|
5
|
+
|
6
|
+
NOTE: Radix::Base is the original Radix API. But with the advent of v2.0
|
7
|
+
and the new Integer and Float classes, it is outmoded. For now it is here
|
8
|
+
for backward compatibility. In a future version it may be deprecated, or
|
9
|
+
reworked to serve as the backbone of the other classes.
|
4
10
|
|
5
11
|
require 'radix/base'
|
6
12
|
|
7
13
|
First let's try something we all know, hexideciaml.
|
8
14
|
First we setup the radix for each.
|
9
15
|
|
10
|
-
b10 = Radix::Base.new(Radix::
|
11
|
-
b16 = Radix::Base.new(Radix::
|
16
|
+
b10 = Radix::Base.new(Radix::BASE::B10)
|
17
|
+
b16 = Radix::Base.new(Radix::BASE::B16)
|
12
18
|
|
13
19
|
Now we can covert from one base to the other.
|
14
20
|
|
@@ -30,42 +36,47 @@ a Radix object.
|
|
30
36
|
b10.convert("A0", 16).should == "160"
|
31
37
|
b10.convert("FF", 16).should == "255"
|
32
38
|
|
33
|
-
|
34
|
-
|
39
|
+
Now let's try a more down to earth base, my favorite,
|
40
|
+
senary, or base six.
|
35
41
|
|
36
|
-
Radix::Base.
|
37
|
-
|
38
|
-
Radix::Base.convert("FF", 16, 10).should == "255"
|
42
|
+
b6 = Radix::Base.new(0..5)
|
43
|
+
b6.convert("39", 10).should == "103"
|
39
44
|
|
40
|
-
|
45
|
+
And the notations need not be in ASCII order. Odd alternate notations
|
46
|
+
can be used as well.
|
41
47
|
|
42
|
-
Radix::Base.
|
43
|
-
|
48
|
+
b10 = Radix::Base.new([:Q, :W, :E, :R, :T, :Y, :U, :I, :O, :U])
|
49
|
+
b10.convert("FF", 16) #=> "EYY"
|
44
50
|
|
45
|
-
|
46
|
-
Radix::Base.convert( "AZ42", 62, 10).should == "8814542"
|
51
|
+
== Encoding and Decoding
|
47
52
|
|
48
53
|
Radix can also be used to encode and decode strings.
|
49
54
|
|
50
55
|
b16.encode("CHARLIE").should == "434841524C4945"
|
51
56
|
b16.decode("434841524C4945").should == "CHARLIE"
|
52
57
|
|
53
|
-
|
54
|
-
senary, or base six.
|
58
|
+
== Module Methods
|
55
59
|
|
56
|
-
|
57
|
-
|
60
|
+
We can also use the module function to convert to and from standard
|
61
|
+
notations upto 62 without creating an instance of Radix::Base.
|
58
62
|
|
59
|
-
|
60
|
-
|
63
|
+
Radix.convert("10", 16, 10).should == "16"
|
64
|
+
Radix.convert("A0", 16, 10).should == "160"
|
65
|
+
Radix.convert("FF", 16, 10).should == "255"
|
61
66
|
|
62
|
-
|
63
|
-
|
67
|
+
Let's try that again with the maximum base supported.
|
68
|
+
|
69
|
+
Radix.convert( "62", 10, 62).should == "10"
|
70
|
+
Radix.convert("8814542", 10, 62).should == "az42"
|
71
|
+
|
72
|
+
Radix.convert( "10", 62, 10).should == "62"
|
73
|
+
Radix.convert( "az42", 62, 10).should == "8814542"
|
64
74
|
|
65
75
|
Finally, we will demonstrate how to convert bases larger than 62.
|
66
76
|
These can only be represented as arrays since there are not enough
|
67
77
|
latin characters to represent them.
|
68
78
|
|
69
|
-
Radix
|
70
|
-
Radix
|
79
|
+
Radix.convert_base([100, 10], 256, 10).should == [2, 5, 6, 1, 0]
|
80
|
+
Radix.convert_base([2, 5, 6, 1, 0], 10, 256).should == [100, 10]
|
81
|
+
Radix.convert_base([1, 0, 1, 0, 1], 2, 10).should == [2, 1]
|
71
82
|
|
data/{qed → doc}/applique/ae.rb
RENAMED
File without changes
|
data/doc/applique/qed.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'qed/extensions/check'
|
data/lib/radix.rb
CHANGED
@@ -1 +1,42 @@
|
|
1
|
-
require 'radix/
|
1
|
+
require 'radix/meta/data'
|
2
|
+
require 'radix/base'
|
3
|
+
require 'radix/integer'
|
4
|
+
require 'radix/float'
|
5
|
+
require 'radix/rational' # load ?
|
6
|
+
|
7
|
+
class ::Float
|
8
|
+
#
|
9
|
+
def b(base)
|
10
|
+
Radix::Float.new(self, base)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ::Integer
|
15
|
+
#
|
16
|
+
def b(base)
|
17
|
+
Radix::Integer.new(self, base)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class ::String
|
22
|
+
#
|
23
|
+
def b(base)
|
24
|
+
if index('.')
|
25
|
+
Radix::Float.new(self, base)
|
26
|
+
else
|
27
|
+
Radix::Integer.new(self, base)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ::Array
|
33
|
+
#
|
34
|
+
def b(base)
|
35
|
+
if index('.')
|
36
|
+
Radix::Float.new(self, base)
|
37
|
+
else
|
38
|
+
Radix::Integer.new(self, base)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/lib/radix/base.rb
CHANGED
@@ -1,96 +1,81 @@
|
|
1
|
-
# Radix coverts to and from any base.
|
2
|
-
#
|
3
|
-
# Base conversions with ASCII ordered notations are easy in Ruby.
|
4
|
-
#
|
5
|
-
# 255.to_s(16) #=> "FF"
|
6
|
-
# "FF".to_i(16) #=> 255
|
7
|
-
#
|
8
|
-
# But Ruby reaches it's limit at base 36.
|
9
|
-
#
|
10
|
-
# 255.to_s(37) #=> Error
|
11
|
-
#
|
12
|
-
# Radix provides the means of converting to and from any base.
|
13
|
-
#
|
14
|
-
# Radix::Base.convert_base([100, 10], 256, 10)
|
15
|
-
# #=> [2,5,6,1,0]
|
16
|
-
#
|
17
|
-
# And it can handle any notation upto base 62.
|
18
|
-
#
|
19
|
-
# Radix::Base.convert("10", 62, 10) #=> "62"
|
20
|
-
#
|
21
|
-
# And the notations need not be in ASCII order --odd notations
|
22
|
-
# can be used.
|
23
|
-
#
|
24
|
-
# b10 = Radix::Base.new([:Q, :W, :E, :R, :T, :Y, :U, :I, :O, :U])
|
25
|
-
# b10.convert("FF", 16) #=> "EYY"
|
26
|
-
#
|
27
1
|
module Radix
|
28
2
|
|
29
|
-
|
3
|
+
# Collection of base encodings.
|
4
|
+
module BASE
|
5
|
+
B10 = ('0'..'9').to_a
|
6
|
+
B12 = B10 + ['X', 'E']
|
7
|
+
B16 = B10 + ('A'..'F').to_a
|
8
|
+
B36 = B10 + ('A'..'Z').to_a
|
9
|
+
B60 = B36 + ('a'..'x').to_a
|
10
|
+
B62 = B36 + ('a'..'z').to_a
|
11
|
+
|
12
|
+
# Like BASE16 but encodes with lowercase letters.
|
13
|
+
HEX = B10 + ('a'..'f').to_a
|
14
|
+
end
|
30
15
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
16
|
+
# Radix::Base provides the means of converting to and from any base.
|
17
|
+
#
|
18
|
+
# b10 = Radix::Base.new(10)
|
19
|
+
# b10.convert_base([100, 10], 256)
|
20
|
+
# #=> [2,5,6,1,0]
|
21
|
+
#
|
22
|
+
# And it can handle any notation upto base 62.
|
23
|
+
#
|
24
|
+
# b10.convert("10", 62) #=> "62"
|
25
|
+
#
|
26
|
+
# And the notations need not be in ASCII order --odd notations
|
27
|
+
# can be used.
|
28
|
+
#
|
29
|
+
# b10 = Radix::Base.new(%w{Q W E R T Y U I O U})
|
30
|
+
# b10.convert("FF", 16) #=> "EYY"
|
31
|
+
#
|
32
|
+
# NOTE: Radix::Base is the original Radix API. But with the advent of v2.0
|
33
|
+
# and the new Integer and Float classes, it is outmoded. For now it is here
|
34
|
+
# for backward compatibility. In a future version it may be deprecated, or
|
35
|
+
# reworked to serve as the backbone of the other classes.
|
36
|
+
#
|
37
|
+
class Base
|
37
38
|
|
38
39
|
attr :chars
|
40
|
+
|
39
41
|
attr :base
|
42
|
+
|
40
43
|
attr :values
|
41
44
|
|
42
45
|
# New Radix using +chars+ representation.
|
43
|
-
def initialize(chars=
|
46
|
+
def initialize(chars=BASE::B62)
|
47
|
+
if ::Numeric === chars
|
48
|
+
chars = BASE::B62[0...chars]
|
49
|
+
end
|
44
50
|
@chars = chars.map{ |c| c.to_s }
|
45
51
|
@base = @chars.size
|
46
52
|
@values = Hash[*(0...@base).map { |i| [ @chars[i], i ] }.flatten]
|
47
53
|
end
|
48
54
|
|
49
|
-
#
|
50
|
-
def
|
51
|
-
|
52
|
-
digits = convert_base(digits, 256, base)
|
53
|
-
digits.map{ |d| @chars[d] }.join
|
54
|
-
end
|
55
|
+
# Convert an *encoded* +number+ of given +base+ to the Base's radix.
|
56
|
+
def convert(number, radix_base)
|
57
|
+
radix_base = Radix::Base.new(radix_base) unless Radix::Base === radix_base
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
case number
|
60
|
+
when ::String, ::Numeric
|
61
|
+
digits = number.to_s.split(//)
|
62
|
+
else
|
63
|
+
digits = number
|
64
|
+
end
|
65
|
+
|
66
|
+
# decode the digits
|
67
|
+
digits = digits.map{ |digit| radix_base.values[digit] }
|
68
|
+
|
69
|
+
# THINK: Is best way to check for base out of bounds?
|
70
|
+
raise TypeError if digits.any?{ |digit| digit.nil? }
|
61
71
|
|
62
|
-
|
63
|
-
def convert(number, from_radix)
|
64
|
-
from_radix = standard_radix(from_radix) if Integer === from_radix
|
65
|
-
digits = number.to_s.split(//)
|
66
|
-
digits = digits.map{ |digit| from_radix.values[digit] }
|
67
|
-
digits = convert_base(digits, from_radix.base, base)
|
72
|
+
digits = Radix.convert_base(digits, radix_base.base, base)
|
68
73
|
digits = digits.map{ |digit| chars[digit] }
|
69
74
|
digits.join
|
70
75
|
end
|
71
76
|
|
72
77
|
# Convert any base to any other base, using array of +digits+.
|
73
78
|
def convert_base(digits, from_base, to_base)
|
74
|
-
self.class.convert_base(digits, from_base, to_base)
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def standard_radix(integer_base)
|
80
|
-
self.class.standard_radix(integer_base)
|
81
|
-
end
|
82
|
-
|
83
|
-
public
|
84
|
-
|
85
|
-
# Do a standard conversion upto base 62.
|
86
|
-
def self.convert(number, from_base, to_base)
|
87
|
-
r1 = standard_radix(from_base)
|
88
|
-
r2 = standard_radix(to_base)
|
89
|
-
r2.convert(number, r1)
|
90
|
-
end
|
91
|
-
|
92
|
-
# Convert any base to any other base, using array of +digits+.
|
93
|
-
def self.convert_base(digits, from_base, to_base)
|
94
79
|
bignum = 0
|
95
80
|
digits.each { |digit| bignum = bignum * from_base + digit }
|
96
81
|
converted = []
|
@@ -98,33 +83,44 @@ module Radix
|
|
98
83
|
bignum, digit = bignum.divmod(to_base)
|
99
84
|
converted.push(digit)
|
100
85
|
end
|
86
|
+
converted << 0 if converted.empty? # THINK: correct?
|
101
87
|
converted.reverse
|
102
88
|
end
|
103
89
|
|
104
|
-
#
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
90
|
+
# Encode a string in the radix.
|
91
|
+
def encode(byte_string)
|
92
|
+
digits = byte_string.unpack("C*")
|
93
|
+
digits = Radix.convert_base(digits, 256, base)
|
94
|
+
digits.map{ |d| @chars[d] }.join
|
95
|
+
end
|
96
|
+
|
97
|
+
# Decode a string that was previously encoded in the radix.
|
98
|
+
def decode(encoded)
|
99
|
+
digits = encoded.split(//).map{ |c| @values[c] }
|
100
|
+
Radix.convert_base(digits, base, 256).pack("C*")
|
111
101
|
end
|
112
102
|
|
113
103
|
end
|
114
104
|
|
105
|
+
# Convert number from it's given base to antoher base.
|
115
106
|
# Do a standard conversion upto base 62.
|
116
107
|
def self.convert(number, from_base, to_base)
|
117
|
-
Radix::Base.
|
108
|
+
from_base = Radix::Base.new(from_base) unless Radix::Base === from_base
|
109
|
+
to_base = Radix::Base.new(to_base) unless Radix::Base === to_base
|
110
|
+
to_base.convert(number, from_base)
|
118
111
|
end
|
119
112
|
|
120
113
|
# Convert any base to any other base, using array of +digits+.
|
121
114
|
def self.convert_base(digits, from_base, to_base)
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
115
|
+
bignum = 0
|
116
|
+
digits.each { |digit| bignum = bignum * from_base + digit }
|
117
|
+
converted = []
|
118
|
+
until bignum.zero?
|
119
|
+
bignum, digit = bignum.divmod(to_base)
|
120
|
+
converted.push(digit)
|
121
|
+
end
|
122
|
+
converted << 0 if converted.empty? # THINK: correct?
|
123
|
+
converted.reverse
|
128
124
|
end
|
129
125
|
|
130
126
|
end
|