radix-firstbanco 2.2.0
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 +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
|
+
|