Class: Radix::Numeric

Inherits:
Numeric
  • Object
show all
Defined in:
lib/radix/numeric.rb

Overview

TODO:

Make immutable, but best way to do it?

Radix::Numeric class inherits from Ruby's Numeric class. It is then subclassed by Radix::Integer and Radix::Float.

Examples:

First suggestion

class << self
  alias_method :_new, :new
  private :_new
end

Second suggestion

def self.new(value, base=10)
  @cache ||= {}
  @cache[[value, base]] ||= _new(value, base)
end

Direct Known Subclasses

Float, Integer, Rational

Instance Method Summary collapse

Instance Method Details

#*(other) ⇒ Radix::Numeric

Multiplication, binary operation.

Parameters:

Returns:


57
58
59
# File 'lib/radix/numeric.rb', line 57

def *(other)
  operation(:*, other)
end

#+(other) ⇒ Radix::Numeric

Addition, binary operation.

Parameters:

Returns:


37
38
39
# File 'lib/radix/numeric.rb', line 37

def +(other)
  operation(:+, other)
end

#-(other) ⇒ Radix::Numeric

Subtraction, binary operation.

Parameters:

Returns:


47
48
49
# File 'lib/radix/numeric.rb', line 47

def -(other)
  operation(:-, other)
end

#/(other) ⇒ Radix::Numeric

Division, binary operation.

Parameters:

Returns:


67
68
69
# File 'lib/radix/numeric.rb', line 67

def /(other)
  operation(:/, other)
end

#base_decode(digits) ⇒ Array<String, Numeric> (private)

Decode an encoded array. Defaults to BASE::B62 if @code is not set.

Parameters:

Returns:


200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/radix/numeric.rb', line 200

def base_decode(digits)
  #return digits unless code
  code = self.code || BASE::B62
  digits.map do |c|
    case c
    when '-', DOT, DIV
      c
    when ::Numeric
      c
    else
      code.index(c)  # TODO: Could speed up with an reverse index.
    end
  end
end

#base_encode(digits) ⇒ Array<String, Fixnum> (private)

Map array of values to base encoding. If no encoding is defined this simply returns the digits unchanged.

Parameters:

Returns:

  • (Array<String, Fixnum>)

    Encoded digits, or digits if @code is nil


182
183
184
185
186
187
188
189
190
191
192
# File 'lib/radix/numeric.rb', line 182

def base_encode(digits)
  return digits unless @code
  digits.map do |i|
    case i
    when '-', DOT, DIV
      i
    else
      code[i]
    end
  end
end

#decimal(digits, base) ⇒ Integer (private)

Convert array of values of a different base to decimal. This handles integer values. The method for Radix::Float is slighly different.

Parameters:

Returns:

  • (Integer)

    The digits of base converted to decimal.


165
166
167
168
169
170
171
172
173
# File 'lib/radix/numeric.rb', line 165

def decimal(digits, base)
  e = digits.size - 1
  v = 0
  digits.each do |n|
    v += n.to_i * base**e
    e -= 1
  end
  v
end

#parse_array(value, base) ⇒ Fixnum (private)

Take an Array in the form of [d1, d2, …, DOT, d-1, d-2, …] and convert it to base ten, and store in @value.

Parameters:

Returns:

  • (Fixnum)

    Decimal version of passed array in base context.

Raises:

  • (ArgumentError)

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/radix/numeric.rb', line 134

def parse_array(value, base)
  value = value.dup

  if value.first == '-'
    neg = true
    value.shift
  else
    neg = false
  end

  value = base_decode(value)

  ## raise an error if any digit is not less than base
  raise ArgumentError if value.any?{ |e| ::Numeric === e && base < e }

  v = decimal(value, base)

  neg ? -v : v # Returns negated v if value array.first == "-"
end

#parse_base(base) ⇒ Array<(Fixnum, [Array<String>, nil])> (private)

Note:

If an array of String characters is passed, its length is the value of the base level.

Parses the value of the base and character set to use.

Parameters:

  • base (Fixnum, Array<String>)

    The value of the base, or a set of characters to use as representation of the base.

Returns:

  • (Array<(Fixnum, [Array<String>, nil])>)

    Two part array: 0 - Fixnum value of the base. 1 - Nil, or Array of characters representing the base values.


86
87
88
89
90
91
92
93
94
95
96
# File 'lib/radix/numeric.rb', line 86

def parse_base(base)
  case base
  when Array
    code = base
    base = base.size
  else
    code = nil
    base = base
  end
  return base, code
end

#parse_numeric(value, base) ⇒ Radix::Float, Radix::Integer (private)

Simply returns the passed value. Used for simplifying creation of Radix::Numeric instances.

Parameters:

Returns:


106
107
108
# File 'lib/radix/numeric.rb', line 106

def parse_numeric(value, base)
  value
end

#parse_string(value, base) ⇒ Radix::Float, Radix::Integer (private)

If a float style string is passed in for value, e.g. “9.5”, the decimal will simply be truncated. So “9.x” would become “9”.

Parameters:

Returns:


121
122
123
124
# File 'lib/radix/numeric.rb', line 121

def parse_string(value, base)
  digits = value.split(//)
  parse_array(digits, base)
end