radix-firstbanco 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.index +59 -0
- data/.yardopts +8 -0
- data/HISTORY.md +95 -0
- data/LICENSE.txt +23 -0
- data/README.md +100 -0
- 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/demo/issues/004_zero_empty_string.md +18 -0
- data/lib/radix.rb +31 -0
- data/lib/radix.yml +59 -0
- data/lib/radix/base.rb +244 -0
- data/lib/radix/float.rb +456 -0
- data/lib/radix/integer.rb +466 -0
- data/lib/radix/numeric.rb +217 -0
- data/lib/radix/rational.rb +311 -0
- metadata +115 -0
data/demo/applique/ae.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'radix'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Zero becomes empty string (#4)
|
2
|
+
|
3
|
+
Example of the issue:
|
4
|
+
|
5
|
+
0.b(10).to_s #=> ""
|
6
|
+
|
7
|
+
I would expect "0" as a result.
|
8
|
+
|
9
|
+
0.b(10).to_s #=> "0"
|
10
|
+
|
11
|
+
Okay, lets make sure this works for Floats.
|
12
|
+
|
13
|
+
0.0.b(10).to_s #=> "0.0"
|
14
|
+
|
15
|
+
And Rationals too.
|
16
|
+
|
17
|
+
[0,1].br(10).to_s #=> "0/1"
|
18
|
+
|
data/lib/radix.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'radix/base'
|
2
|
+
require 'radix/integer'
|
3
|
+
require 'radix/float'
|
4
|
+
require 'radix/rational'
|
5
|
+
|
6
|
+
module Radix
|
7
|
+
|
8
|
+
##
|
9
|
+
# Returns the metadata contained in Radix.yml
|
10
|
+
#
|
11
|
+
# @return [Hash{String=>String}]
|
12
|
+
def self.metadata
|
13
|
+
@metadata ||= (
|
14
|
+
require 'yaml'
|
15
|
+
YAML.load(File.new(File.dirname(__FILE__) + '/radix.yml'))
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Gets value of name in metadata or goes up ancestry.
|
21
|
+
#
|
22
|
+
# @param [Symbol] name
|
23
|
+
#
|
24
|
+
# @return [String]
|
25
|
+
def self.const_missing(name)
|
26
|
+
key = name.to_s.downcase
|
27
|
+
metadata.key?(key) ? metadata[key] : super(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
data/lib/radix.yml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
revision: 2013
|
3
|
+
type: ruby
|
4
|
+
sources:
|
5
|
+
- var
|
6
|
+
authors:
|
7
|
+
- name: Thomas Sawyer
|
8
|
+
email: transfire@gmail.com
|
9
|
+
organizations: []
|
10
|
+
requirements:
|
11
|
+
- groups:
|
12
|
+
- build
|
13
|
+
development: true
|
14
|
+
name: ergo
|
15
|
+
- groups:
|
16
|
+
- test
|
17
|
+
development: true
|
18
|
+
name: qed
|
19
|
+
- groups:
|
20
|
+
- test
|
21
|
+
development: true
|
22
|
+
name: ae
|
23
|
+
conflicts: []
|
24
|
+
alternatives: []
|
25
|
+
resources:
|
26
|
+
- type: home
|
27
|
+
uri: http://rubyworks.github.com/radix
|
28
|
+
label: Homepage
|
29
|
+
- type: code
|
30
|
+
uri: http://github.com/rubyworks/radix
|
31
|
+
label: Source Code
|
32
|
+
- type: mail
|
33
|
+
uri: http://groups.google.com/groups/rubyworks-mailinglist
|
34
|
+
label: Mailing List
|
35
|
+
- type: bugs
|
36
|
+
uri: http://github.com/rubyworks/radix/issues
|
37
|
+
label: Issue Tracker
|
38
|
+
repositories:
|
39
|
+
- name: upstream
|
40
|
+
scm: git
|
41
|
+
uri: git://github.com/rubyworks/radix.git
|
42
|
+
categories: []
|
43
|
+
copyrights:
|
44
|
+
- holder: ''
|
45
|
+
year: '2009'
|
46
|
+
license: BSD-2-Clause
|
47
|
+
customs: []
|
48
|
+
paths:
|
49
|
+
lib:
|
50
|
+
- lib
|
51
|
+
created: '2009-07-01'
|
52
|
+
summary: Convert to and from any base.
|
53
|
+
title: Radix
|
54
|
+
version: 2.2.0
|
55
|
+
name: radix
|
56
|
+
description: ! "Radix is a very easy to use Ruby library for converting numbers to
|
57
|
+
and from\nany base. It supports both Integer, Float and Rational numbers, as well
|
58
|
+
as \nrepresentational string-notations that need not be in ASCII order."
|
59
|
+
date: '2013-03-20'
|
data/lib/radix/base.rb
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
module Radix
|
2
|
+
|
3
|
+
##
|
4
|
+
# Namespace for common bases defined as reusable constants.
|
5
|
+
#
|
6
|
+
module BASE
|
7
|
+
# Array of chars 0 - 9
|
8
|
+
B10 = ('0'..'9').to_a
|
9
|
+
# Array of chars 0 - 9 + X + E
|
10
|
+
B12 = B10 + ['X', 'E']
|
11
|
+
# Array of chars 0 - 9 + A - F
|
12
|
+
B16 = B10 + ('A'..'F').to_a
|
13
|
+
# Array of chars 0 - 9 + A - Z
|
14
|
+
B36 = B10 + ('A'..'Z').to_a
|
15
|
+
# Array of chars 0 - 9 + A - Z + a - x
|
16
|
+
B60 = B36 + ('a'..'x').to_a
|
17
|
+
# Array of chars 0 - 9 + A - Z + a - z
|
18
|
+
B62 = B36 + ('a'..'z').to_a
|
19
|
+
# Array of chars 0 - 9 + a - f
|
20
|
+
HEX = B10 + ('a'..'f').to_a
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Radix::Base is a functional model of a base system that can be used for
|
25
|
+
# number conversions.
|
26
|
+
#
|
27
|
+
# Radix::Base is the original Radix API. But with the advent of v2.0
|
28
|
+
# and the new Integer and Float classes, it is essentially deprecated.
|
29
|
+
#
|
30
|
+
# @example Convert any base
|
31
|
+
# b10 = Radix::Base.new(10)
|
32
|
+
# b10.convert_base([100, 10], 256)
|
33
|
+
# #=> [2,5,6,1,0]
|
34
|
+
#
|
35
|
+
# @example Convert to string notation upto base 62
|
36
|
+
# b10.convert("10", 62) #=> "62"
|
37
|
+
#
|
38
|
+
# @example Odd notations
|
39
|
+
# b10 = Radix::Base.new(%w{Q W E R T Y U I O U})
|
40
|
+
# b10.convert("FF", 16) #=> "EYY"
|
41
|
+
#
|
42
|
+
# @!attribute [r] chars
|
43
|
+
# @return [Array<String>] The ASCII character set in use.
|
44
|
+
# @!attribute [r] base
|
45
|
+
# @return [Fixnum] The base level in use.
|
46
|
+
# @!attribute [r] values
|
47
|
+
# @example Testing base hash default values.
|
48
|
+
# > test = Radix::Base.new(36)
|
49
|
+
# > test.values["F"]
|
50
|
+
# 15
|
51
|
+
# > test.values["5"]
|
52
|
+
# 5
|
53
|
+
# > test.values["Y"]
|
54
|
+
# 34
|
55
|
+
# > test.values["YY"]
|
56
|
+
# nil # Fails because "YY" is not a key in the +values+ hash.
|
57
|
+
# @return [Hash{String=>Fixnum}]
|
58
|
+
# A hash of characters and their respective value.
|
59
|
+
class Base
|
60
|
+
|
61
|
+
##
|
62
|
+
# The characters for this base level.
|
63
|
+
#
|
64
|
+
# @return [Array<String>] The ASCII character set in use.
|
65
|
+
attr :chars
|
66
|
+
|
67
|
+
##
|
68
|
+
# The base of this instance.
|
69
|
+
#
|
70
|
+
# @return [Fixnum] The base level in use.
|
71
|
+
attr :base
|
72
|
+
|
73
|
+
##
|
74
|
+
# Hash of characters and values.
|
75
|
+
#
|
76
|
+
# @return [Hash{String=>Fixnum}]
|
77
|
+
# A hash of characters and their respective value.
|
78
|
+
attr :values
|
79
|
+
|
80
|
+
##
|
81
|
+
# New Radix using +chars+ representation.
|
82
|
+
#
|
83
|
+
# @param [Array<String>, Numeric] chars
|
84
|
+
# Array of string representation of number values of the base
|
85
|
+
# or a Numeric of the Base level.
|
86
|
+
#
|
87
|
+
# @return [void]
|
88
|
+
def initialize(chars=BASE::B62)
|
89
|
+
if ::Numeric === chars
|
90
|
+
chars = BASE::B62[0...chars]
|
91
|
+
end
|
92
|
+
@chars = chars.map{ |c| c.to_s }
|
93
|
+
@base = @chars.size
|
94
|
+
@values = Hash[*(0...@base).map { |i| [ @chars[i], i ] }.flatten]
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Convert a value of given radix_base to that of the base instance.
|
99
|
+
#
|
100
|
+
# @param [String, Numeric, Array<String>] number
|
101
|
+
# The value in "radix_base" context.
|
102
|
+
#
|
103
|
+
# @param [Radix::Base, Numeric] radix_base
|
104
|
+
# Numeric for the radix or instance of Radix::Base.
|
105
|
+
#
|
106
|
+
# @example Convert Testing (Binary, Decimal, Hex)
|
107
|
+
# > b = Radix::Base.new(2)
|
108
|
+
# > d = Radix::Base.new(10)
|
109
|
+
# > h = Radix::Base.new(16)
|
110
|
+
# > d.convert("A", h)
|
111
|
+
# "10"
|
112
|
+
# > h.convert("A", d)
|
113
|
+
# TypeError
|
114
|
+
# > h.convert(10, d)
|
115
|
+
# "A"
|
116
|
+
# > h.convert(10, 10)
|
117
|
+
# "A"
|
118
|
+
# > b.convert(10, d)
|
119
|
+
# "1010"
|
120
|
+
# > b.convert(10, h)
|
121
|
+
# "10000"
|
122
|
+
#
|
123
|
+
# @return [String] representation of "number" in self.base level.
|
124
|
+
def convert(number, radix_base)
|
125
|
+
radix_base = Radix::Base.new(radix_base) unless Radix::Base === radix_base
|
126
|
+
case number
|
127
|
+
when ::String, ::Numeric
|
128
|
+
digits = number.to_s.split(//)
|
129
|
+
else
|
130
|
+
digits = number
|
131
|
+
end
|
132
|
+
|
133
|
+
# decode the digits
|
134
|
+
digits = digits.map{ |digit| radix_base.values[digit] }
|
135
|
+
|
136
|
+
# THINK: Is best way to check for base out of bounds?
|
137
|
+
raise TypeError if digits.any?{ |digit| digit.nil? }
|
138
|
+
|
139
|
+
digits = Radix.convert_base(digits, radix_base.base, base)
|
140
|
+
digits = digits.map{ |digit| chars[digit] }
|
141
|
+
digits.join
|
142
|
+
end
|
143
|
+
|
144
|
+
##
|
145
|
+
# Convert any base to any other base, using array of Fixnum's. Indexes of
|
146
|
+
# the array correspond to values for each column of the number in from_base
|
147
|
+
#
|
148
|
+
# @param [Array<Fixnum>] digits
|
149
|
+
# Array of values for each digit of source base.
|
150
|
+
#
|
151
|
+
# @param [Fixnum] from_base
|
152
|
+
# Source Base
|
153
|
+
#
|
154
|
+
# @param [Fixnum] to_base
|
155
|
+
# Destination Base
|
156
|
+
#
|
157
|
+
# @return [String] The value of digits in from_base converted as to_base.
|
158
|
+
def convert_base(digits, from_base, to_base)
|
159
|
+
bignum = 0
|
160
|
+
digits.each { |digit| bignum = bignum * from_base + digit }
|
161
|
+
converted = []
|
162
|
+
until bignum.zero?
|
163
|
+
bignum, digit = bignum.divmod(to_base)
|
164
|
+
converted.push(digit)
|
165
|
+
end
|
166
|
+
converted << 0 if converted.empty? # THINK: correct?
|
167
|
+
converted.reverse
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Encode a string in the radix.
|
172
|
+
#
|
173
|
+
# @param [String] byte_string
|
174
|
+
# String value in this base.
|
175
|
+
#
|
176
|
+
# @return [String] Encoded string from this Base.
|
177
|
+
def encode(byte_string)
|
178
|
+
digits = byte_string.unpack("C*")
|
179
|
+
digits = Radix.convert_base(digits, 256, base)
|
180
|
+
digits.map{ |d| @chars[d] }.join
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# Decode a string that was previously encoded in the radix.
|
185
|
+
#
|
186
|
+
# @param [String] encoded
|
187
|
+
# Encoded string from this Base.
|
188
|
+
#
|
189
|
+
# @return [String] Decoded string of value from this base.
|
190
|
+
def decode(encoded)
|
191
|
+
digits = encoded.split(//).map{ |c| @values[c] }
|
192
|
+
Radix.convert_base(digits, base, 256).pack("C*")
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
##
|
198
|
+
# Convert a number of from_base as to_base.
|
199
|
+
#
|
200
|
+
# @param [String, Numeric, Array<String>] number
|
201
|
+
# The value in context of "radix_base".
|
202
|
+
#
|
203
|
+
# @param [Fixnum, Radix::Base] from_base
|
204
|
+
# Source Base
|
205
|
+
#
|
206
|
+
# @param [Fixnum, Radix::Base] to_base
|
207
|
+
# Destination Base
|
208
|
+
#
|
209
|
+
# @return [String]
|
210
|
+
# The value of `digits` in `from_base` converted into `to_base`.
|
211
|
+
def self.convert(number, from_base, to_base)
|
212
|
+
from_base = Radix::Base.new(from_base) unless Radix::Base === from_base
|
213
|
+
to_base = Radix::Base.new(to_base) unless Radix::Base === to_base
|
214
|
+
to_base.convert(number, from_base)
|
215
|
+
end
|
216
|
+
|
217
|
+
##
|
218
|
+
# Convert any base to any other base, using array of Fixnum's. Indexes of
|
219
|
+
# the array correspond to values for each column of the number in from_base
|
220
|
+
#
|
221
|
+
# @param [Array<Fixnum>] digits
|
222
|
+
# Array of values for each digit of source base.
|
223
|
+
#
|
224
|
+
# @param [Fixnum] from_base
|
225
|
+
# Source Base
|
226
|
+
#
|
227
|
+
# @param [Fixnum] to_base
|
228
|
+
# Destination Base
|
229
|
+
#
|
230
|
+
# @return [String] The value of digits in from_base converted as to_base.
|
231
|
+
def self.convert_base(digits, from_base, to_base)
|
232
|
+
bignum = 0
|
233
|
+
digits.each { |digit| bignum = bignum * from_base + digit }
|
234
|
+
converted = []
|
235
|
+
until bignum.zero?
|
236
|
+
bignum, digit = bignum.divmod(to_base)
|
237
|
+
converted.push(digit)
|
238
|
+
end
|
239
|
+
converted << 0 if converted.empty? # THINK: correct?
|
240
|
+
converted.reverse
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
data/lib/radix/float.rb
ADDED
@@ -0,0 +1,456 @@
|
|
1
|
+
require 'radix/numeric'
|
2
|
+
|
3
|
+
module Radix
|
4
|
+
|
5
|
+
##
|
6
|
+
# Advanced float class for Radix conversions and mathematical operations
|
7
|
+
# with other bases.
|
8
|
+
#
|
9
|
+
# @todo Make fully immutable. After that we can catch @digits and
|
10
|
+
# the library should be a good bit faster.
|
11
|
+
#
|
12
|
+
# @!attribute [r] value
|
13
|
+
# @return [Float] Float's decimal value.
|
14
|
+
# @!attribute [r] base
|
15
|
+
# @return [Fixnum] The base level of Float instance.
|
16
|
+
# @!attribute [r] code
|
17
|
+
# @return [Array<String>, nil] Substitution chars or nil if default.
|
18
|
+
class Float < Numeric
|
19
|
+
|
20
|
+
##
|
21
|
+
# Internal floating point value.
|
22
|
+
#
|
23
|
+
# @return [Float] Float's decimal value.
|
24
|
+
attr :value
|
25
|
+
|
26
|
+
##
|
27
|
+
# Base of the number.
|
28
|
+
#
|
29
|
+
# @return [Fixnum] The base level of Float instance.
|
30
|
+
attr :base
|
31
|
+
|
32
|
+
##
|
33
|
+
# Base encoding table.
|
34
|
+
#
|
35
|
+
# @return [Array<String>, nil] Substitution chars or nil if default.
|
36
|
+
attr :code
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
##
|
41
|
+
# Starts a new instance of the Radix::Float class.
|
42
|
+
#
|
43
|
+
# @param [Radix::Numeric, Numeric, Array, String] value
|
44
|
+
# The value of the new integer in context of base.
|
45
|
+
#
|
46
|
+
# @param [Fixnum, Array<String>] base
|
47
|
+
# The base context in which value is determined. Can be an array
|
48
|
+
# of characters to use in place of default.
|
49
|
+
#
|
50
|
+
# @return [void]
|
51
|
+
def initialize(value, base=10)
|
52
|
+
@value = parse_value(value, base)
|
53
|
+
@base, @code = parse_base(base)
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Takes a Radix::Numeric, String or array and returns the decimal float
|
58
|
+
# value for storage in @value.
|
59
|
+
#
|
60
|
+
# @param [Radix::Numeric, Numeric, String, Array<Numeric, String>] value
|
61
|
+
# The value of the integer in base context.
|
62
|
+
#
|
63
|
+
# @param [Fixnum, Array<String>] base
|
64
|
+
# The context base of value.
|
65
|
+
#
|
66
|
+
# @return [Float] Float value of Integer.
|
67
|
+
def parse_value(value, base)
|
68
|
+
case value
|
69
|
+
when Float, Integer # Radix
|
70
|
+
parse_numeric(value.to_f, base)
|
71
|
+
when ::Array
|
72
|
+
parse_array(value, base)
|
73
|
+
when ::String
|
74
|
+
parse_string(value, base)
|
75
|
+
when ::Numeric
|
76
|
+
parse_numeric(value.to_f, base)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
public
|
81
|
+
|
82
|
+
##
|
83
|
+
# Makes this Radix::Float a ruby Integer.
|
84
|
+
#
|
85
|
+
# @return [Integer] Base(10) value as Integer.
|
86
|
+
def to_i
|
87
|
+
to_f.to_i
|
88
|
+
end
|
89
|
+
|
90
|
+
alias_method :to_int, :to_i
|
91
|
+
|
92
|
+
##
|
93
|
+
# Makes this Radix::Float a ruby float.
|
94
|
+
#
|
95
|
+
# @return [Float] Base(10) value as Float.
|
96
|
+
def to_f
|
97
|
+
value.to_f
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Makes this Radix::Float an array using code if defined. Returns an
|
102
|
+
# array using default chars otherwise.
|
103
|
+
#
|
104
|
+
# @param [Fixnum] base
|
105
|
+
# Desired base.
|
106
|
+
#
|
107
|
+
# @return [Array<Fixnum, String>] Current base encoded array.
|
108
|
+
def to_a(base=nil)
|
109
|
+
if base
|
110
|
+
convert(base).digits_encoded
|
111
|
+
else
|
112
|
+
digits_encoded
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Creates an encoded string in passed base, with passed digit divider.
|
118
|
+
#
|
119
|
+
# @note For base 10 or less does not use a divider unless specified.
|
120
|
+
#
|
121
|
+
# @param [Fixnum, Array<String>] base
|
122
|
+
# Desired base.
|
123
|
+
#
|
124
|
+
# @param [String] divider
|
125
|
+
# Desired divider character(s).
|
126
|
+
#
|
127
|
+
# @return [String] Encoded string with specified divider.
|
128
|
+
def to_s(base=nil, divider=nil)
|
129
|
+
divider = divider.to_s if divider
|
130
|
+
if base
|
131
|
+
convert(base).to_s(nil, divider)
|
132
|
+
else
|
133
|
+
if code
|
134
|
+
digits_encoded.join(divider)
|
135
|
+
else
|
136
|
+
if @base > 10
|
137
|
+
digits.join(divider || DIVIDER)
|
138
|
+
else
|
139
|
+
digits.join(divider)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# Creates a string representation of self.
|
147
|
+
#
|
148
|
+
# @return [String] String rep of self.digits and @base.
|
149
|
+
def inspect
|
150
|
+
"#{digits.join(' ')} (#{base})"
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Returns an array representation of each column's value in decimal chars.
|
155
|
+
#
|
156
|
+
# @return [Array<String, Fixnum>]
|
157
|
+
# Values per column of @base as array. Prepended with "-" if negative.
|
158
|
+
def digits
|
159
|
+
i, f = base_conversion(value, base)
|
160
|
+
if negative?
|
161
|
+
['-'] + i + [DOT] + f
|
162
|
+
else
|
163
|
+
i + [DOT] + f
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
##
|
168
|
+
# Returns digits, or coded version of digits if @code.
|
169
|
+
#
|
170
|
+
# @return [Array<String, Fixnum>]
|
171
|
+
# Values per column of @base as array. Prepended with "-" if negative.
|
172
|
+
# Or encoded version if @code is defined.
|
173
|
+
def digits_encoded
|
174
|
+
base_encode(digits)
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Returns true if the number is negative?
|
179
|
+
#
|
180
|
+
# @return [Boolean] True if float value is < 0.
|
181
|
+
def negative?
|
182
|
+
value < 0
|
183
|
+
end
|
184
|
+
|
185
|
+
##
|
186
|
+
# Creates a new Radix::Float of same value in different base.
|
187
|
+
#
|
188
|
+
# @return [Radix::Float] New float of same value in different base.
|
189
|
+
def convert(new_base)
|
190
|
+
self.class.new(value, new_base)
|
191
|
+
end
|
192
|
+
|
193
|
+
##
|
194
|
+
# Power exponentional operation.
|
195
|
+
#
|
196
|
+
# @param [#to_f] other
|
197
|
+
# The exponent by which to raise Float.
|
198
|
+
#
|
199
|
+
# @return [Radix::Float] Result of exponential operation.
|
200
|
+
def **(other)
|
201
|
+
operation(:**, other)
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Modulo binary operation.
|
206
|
+
#
|
207
|
+
# @param [#to_f] other
|
208
|
+
#
|
209
|
+
# @return [Radix::Float] Modulo result of division operation.
|
210
|
+
def %(other)
|
211
|
+
operation(:%, other)
|
212
|
+
end
|
213
|
+
|
214
|
+
alias_method :modulo, :%
|
215
|
+
|
216
|
+
##
|
217
|
+
# Returns the absolute value of self in @base.
|
218
|
+
#
|
219
|
+
# @return [Radix::Float] Absolute of @value.
|
220
|
+
def abs
|
221
|
+
self.class.new(value.abs, base)
|
222
|
+
end
|
223
|
+
|
224
|
+
##
|
225
|
+
# Returns the largest integer greater than or equal to self as a
|
226
|
+
# Radix::Float.
|
227
|
+
#
|
228
|
+
# @return [Radix::Float]
|
229
|
+
def ceil
|
230
|
+
self.class.new(value.ceil, base)
|
231
|
+
end
|
232
|
+
|
233
|
+
##
|
234
|
+
# Returns the smallest integer less than or equal to self as a
|
235
|
+
# Radix::Float.
|
236
|
+
#
|
237
|
+
# @return [Radix::Float]
|
238
|
+
def floor
|
239
|
+
self.class.new(value.floor, base)
|
240
|
+
end
|
241
|
+
|
242
|
+
##
|
243
|
+
# Returns a new Radix::Float instance of same base, rounded to the nearest
|
244
|
+
# whole integer.
|
245
|
+
#
|
246
|
+
# @example Rounding Radix Float
|
247
|
+
# > round_test = Radix::Float.new(123.03, 16)
|
248
|
+
# 7 11 . 0 7 10 14 1 4 7 10 14 1 (16)
|
249
|
+
# > round_test.value
|
250
|
+
# 123.03
|
251
|
+
# > round_test.round
|
252
|
+
# 7 11 . 0 (16)
|
253
|
+
# > round_test.round.value
|
254
|
+
# 123.0
|
255
|
+
# > round_test += 0.5
|
256
|
+
# 7 11 . 8 7 10 14 1 4 7 10 14 1 (16)
|
257
|
+
# > round_test.value
|
258
|
+
# 123.53
|
259
|
+
# > round_test.round
|
260
|
+
# 7 12 . 0 (16)
|
261
|
+
# > round_test.round.value
|
262
|
+
# 124.0
|
263
|
+
#
|
264
|
+
# @return [Radix::Float] New Instance
|
265
|
+
def round
|
266
|
+
return self.class.new((value + 0.5).floor, base) if self > 0.0
|
267
|
+
return self.class.new((value - 0.5).ceil, base) if self < 0.0
|
268
|
+
return self.class.new(0, base)
|
269
|
+
end
|
270
|
+
|
271
|
+
##
|
272
|
+
# Strict equality requires same class as well as value.
|
273
|
+
#
|
274
|
+
# @param [Object] num
|
275
|
+
# Object to compare.
|
276
|
+
#
|
277
|
+
# @return [Boolean] True if class and value are equal.
|
278
|
+
def eql?(num)
|
279
|
+
self.class.equal?(num.class) && self == num
|
280
|
+
end
|
281
|
+
|
282
|
+
##
|
283
|
+
# Simple equality requires equal values only.
|
284
|
+
#
|
285
|
+
# @param [Numeric] other
|
286
|
+
# Any Numeric instance.
|
287
|
+
#
|
288
|
+
# @return [Boolean] True if values are equal.
|
289
|
+
def ==(other)
|
290
|
+
case other
|
291
|
+
when Float, Integer # Radix
|
292
|
+
value == other.value
|
293
|
+
else
|
294
|
+
value == other
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
##
|
299
|
+
# Comparitive binary operation. Very useful for sorting methods.
|
300
|
+
#
|
301
|
+
# @param [#to_f] other
|
302
|
+
# The object to compare value against.
|
303
|
+
#
|
304
|
+
# @example Comparison testing
|
305
|
+
# > lower = Radix::Float.new(123.00,10)
|
306
|
+
# 1 2 3 . 0 (10)
|
307
|
+
# > higher = Radix::Float.new(456.00,16)
|
308
|
+
# 1 12 8 . 0 (16)
|
309
|
+
# > lower <=> higher
|
310
|
+
# -1
|
311
|
+
# > lower <=> 123
|
312
|
+
# 0
|
313
|
+
# > lower <=> "123"
|
314
|
+
# 0
|
315
|
+
# > higher <=> lower
|
316
|
+
# 1
|
317
|
+
#
|
318
|
+
# @return [Fixnum] Returns -1 for less than, 0 for equal or 1 for more than.
|
319
|
+
def <=>(other)
|
320
|
+
to_f <=> other.to_f
|
321
|
+
end
|
322
|
+
|
323
|
+
#
|
324
|
+
#def infinite?
|
325
|
+
# digits[0,2] == [0, DOT]
|
326
|
+
#end
|
327
|
+
|
328
|
+
#
|
329
|
+
#def finite?
|
330
|
+
# !infinite
|
331
|
+
#end
|
332
|
+
|
333
|
+
#
|
334
|
+
#def nan?
|
335
|
+
# digits[-2,2] == [DOT, 0]
|
336
|
+
#end
|
337
|
+
|
338
|
+
##
|
339
|
+
# Create a new Radix::Float from value in Base-10.
|
340
|
+
#
|
341
|
+
# @param [Numeric, Array, String] other
|
342
|
+
# The value of the new integer in base-10.
|
343
|
+
#
|
344
|
+
# @return [Array<Radix::Float>] An array of the new Float object and self.
|
345
|
+
def coerce(other)
|
346
|
+
[Radix::Float.new(other), self]
|
347
|
+
end
|
348
|
+
|
349
|
+
private
|
350
|
+
|
351
|
+
##
|
352
|
+
# Perform passed arithmetic operation.
|
353
|
+
#
|
354
|
+
# @param [#to_f] other
|
355
|
+
#
|
356
|
+
# @return [Radix::Float] Result of binary operation in @base.
|
357
|
+
def operation(op, other)
|
358
|
+
a = self.to_f
|
359
|
+
b = other.to_f
|
360
|
+
x = a.__send__(op, b)
|
361
|
+
Radix::Float.new(x, base)
|
362
|
+
|
363
|
+
end
|
364
|
+
|
365
|
+
##
|
366
|
+
# Returns two arrays. The integer part and the fractional part of the Float
|
367
|
+
# value in param base.
|
368
|
+
#
|
369
|
+
# @param [Float] value Float's decimal value.
|
370
|
+
# @param [Fixnum] base The base level of Float instance.
|
371
|
+
# @param [Fixnum] prec The # of places to extend F-part.
|
372
|
+
#
|
373
|
+
# @return [Array<(Array[Fixnum], Array[Fixnum])>]
|
374
|
+
def base_conversion(value, base, prec=10)
|
375
|
+
#if value < 0
|
376
|
+
# @negative, value = true, value.abs
|
377
|
+
#end
|
378
|
+
value = value.to_f.abs
|
379
|
+
|
380
|
+
i, f = split_float(value)
|
381
|
+
|
382
|
+
a = []
|
383
|
+
while i > 0
|
384
|
+
i, r = i.divmod(base)
|
385
|
+
a << r
|
386
|
+
end
|
387
|
+
|
388
|
+
#c = [] # f-cache
|
389
|
+
p = prec
|
390
|
+
b = []
|
391
|
+
while !f.zero?
|
392
|
+
k = (f * base)
|
393
|
+
r, f = split_float(k)
|
394
|
+
#c.include?(f) ? break : c << f
|
395
|
+
break if p == 0; p -= 1
|
396
|
+
b << r
|
397
|
+
end
|
398
|
+
|
399
|
+
a << 0 if a.empty?
|
400
|
+
b << 0 if b.empty?
|
401
|
+
|
402
|
+
[a.reverse, b]
|
403
|
+
end
|
404
|
+
|
405
|
+
##
|
406
|
+
# Convert array of values of a different base to decimal as called by
|
407
|
+
# parse_array.
|
408
|
+
#
|
409
|
+
# @param [Array<Numeric, String>] digits Representation of Base values.
|
410
|
+
# @param [Fixnum, Array<String>] base The base to convert from.
|
411
|
+
#
|
412
|
+
# @return [Float] The digits of base converted to decimal.
|
413
|
+
def decimal(digits, base)
|
414
|
+
i, f = split_digits(digits)
|
415
|
+
e = i.size - 1
|
416
|
+
v = 0
|
417
|
+
(i + f).each do |n|
|
418
|
+
v += n * base**e
|
419
|
+
e -= 1
|
420
|
+
end
|
421
|
+
v
|
422
|
+
end
|
423
|
+
|
424
|
+
##
|
425
|
+
# Returns the I-Part and F-Part of the passed value as arrays of fixnums.
|
426
|
+
#
|
427
|
+
# @param [Array<Numeric, String>] value
|
428
|
+
# The array of decimal values per column of @base.
|
429
|
+
#
|
430
|
+
# @return [Array<(Array<Fixnum>, Array<Fixnum>)>]
|
431
|
+
def split_digits(value)
|
432
|
+
if d = value.index(DOT) || value.index('.')
|
433
|
+
i, f = value[0...d], value[d+1..-1]
|
434
|
+
else
|
435
|
+
i, f = value, [0]
|
436
|
+
end
|
437
|
+
i.map!{ |x| x.to_i }
|
438
|
+
f.map!{ |x| x.to_i }
|
439
|
+
return i, f
|
440
|
+
end
|
441
|
+
|
442
|
+
##
|
443
|
+
# Returns an array of Integer and Float portions of the Radix::Float
|
444
|
+
#
|
445
|
+
# @param [Radix::Float] float Float value to split
|
446
|
+
#
|
447
|
+
# @return [Array<(Integer, Float)>]
|
448
|
+
def split_float(float)
|
449
|
+
i, f = float.to_s.split('.')
|
450
|
+
return i.to_i, ('0.'+f).to_f
|
451
|
+
end
|
452
|
+
|
453
|
+
end
|
454
|
+
|
455
|
+
end
|
456
|
+
|