class Radix::Float

Advanced float class for Radix conversions and mathematical operations with other bases.

@todo Make fully immutable. After that we can catch @digits and

the library should be a good bit faster.

@!attribute [r] value

@return [Float] Float's decimal value.

@!attribute [r] base

@return [Fixnum] The base level of Float instance.

@!attribute [r] code

@return [Array<String>, nil] Substitution chars or nil if default.

Attributes

base[R]

Base of the number.

@return [Fixnum] The base level of Float instance.

code[R]

Base encoding table.

@return [Array<String>, nil] Substitution chars or nil if default.

value[R]

Internal floating point value.

@return [Float] Float’s decimal value.

Public Class Methods

new(value, base=10) click to toggle source

Starts a new instance of the Radix::Float class.

@param [Radix::Numeric, Numeric, Array, String] value

The value of the new integer in context of base.

@param [Fixnum, Array<String>] base

The base context in which value is determined. Can be an array
of characters to use in place of default.

@return [void]

# File lib/radix/float.rb, line 51
def initialize(value, base=10)
  @value = parse_value(value, base)
  @base, @code = parse_base(base)
end

Public Instance Methods

%(other) click to toggle source

Modulo binary operation.

@param [#to_f] other

@return [Radix::Float] Modulo result of division operation.

# File lib/radix/float.rb, line 210
def %(other)
  operation(:%, other)
end
Also aliased as: modulo
**(other) click to toggle source

Power exponentional operation.

@param [#to_f] other

The exponent by which to raise Float.

@return [Radix::Float] Result of exponential operation.

# File lib/radix/float.rb, line 200
def **(other)
  operation(:**, other)
end
<=>(other) click to toggle source

Comparitive binary operation. Very useful for sorting methods.

@param [#to_f] other

The object to compare value against.

@example Comparison testing

> lower = Radix::Float.new(123.00,10)
1 2 3 . 0 (10)
> higher = Radix::Float.new(456.00,16)
1 12 8 . 0 (16)
> lower <=> higher
-1
> lower <=> 123
0
> lower <=> "123"
0
> higher <=> lower
1

@return [Fixnum] Returns -1 for less than, 0 for equal or 1 for more than.

# File lib/radix/float.rb, line 319
def <=>(other)
  to_f <=> other.to_f
end
==(other) click to toggle source

Simple equality requires equal values only.

@param [Numeric] other

Any Numeric instance.

@return [Boolean] True if values are equal.

# File lib/radix/float.rb, line 289
 def ==(other)
  case other
  when Float, Integer  # Radix
    value == other.value
  else
    value == other
  end
end
abs() click to toggle source

Returns the absolute value of self in @base.

@return [Radix::Float] Absolute of @value.

# File lib/radix/float.rb, line 220
def abs
  self.class.new(value.abs, base)
end
ceil() click to toggle source

Returns the largest integer greater than or equal to self as a Radix::Float.

@return [Radix::Float]

# File lib/radix/float.rb, line 229
def ceil
  self.class.new(value.ceil, base)
end
coerce(other) click to toggle source

Create a new Radix::Float from value in Base-10.

@param [Numeric, Array, String] other

The value of the new integer in base-10.

@return [Array<Radix::Float>] An array of the new Float object and self.

# File lib/radix/float.rb, line 345
def coerce(other)
  [Radix::Float.new(other), self]  
end
convert(new_base) click to toggle source

Creates a new Radix::Float of same value in different base.

@return [Radix::Float] New float of same value in different base.

# File lib/radix/float.rb, line 189
def convert(new_base)
  self.class.new(value, new_base)
end
digits() click to toggle source

Returns an array representation of each column’s value in decimal chars.

@return [Array<String, Fixnum>]

Values per column of @base as array. Prepended with "-" if negative.
# File lib/radix/float.rb, line 158
def digits
  i, f = base_conversion(value, base)
  if negative?
    ['-'] + i + [DOT] + f
  else
    i + [DOT] + f
  end
end
digits_encoded() click to toggle source

Returns digits, or coded version of digits if @code.

@return [Array<String, Fixnum>]

Values per column of @base as array. Prepended with "-" if negative.
Or encoded version if @code is defined.
# File lib/radix/float.rb, line 173
def digits_encoded
  base_encode(digits)
end
eql?(num) click to toggle source

Strict equality requires same class as well as value.

@param [Object] num

Object to compare.

@return [Boolean] True if class and value are equal.

# File lib/radix/float.rb, line 278
def eql?(num)
  self.class.equal?(num.class) && self == num
end
floor() click to toggle source

Returns the smallest integer less than or equal to self as a Radix::Float.

@return [Radix::Float]

# File lib/radix/float.rb, line 238
def floor
  self.class.new(value.floor, base)
end
inspect() click to toggle source

Creates a string representation of self.

@return [String] String rep of self.digits and @base.

# File lib/radix/float.rb, line 149
def inspect
  "#{digits.join(' ')} (#{base})"
end
modulo(other)
Alias for: %
negative?() click to toggle source

Returns true if the number is negative?

@return [Boolean] True if float value is < 0.

# File lib/radix/float.rb, line 181
def negative?
  value < 0
end
round() click to toggle source

Returns a new Radix::Float instance of same base, rounded to the nearest whole integer.

@example Rounding Radix Float

> round_test = Radix::Float.new(123.03, 16)
7 11 . 0 7 10 14 1 4 7 10 14 1 (16)
> round_test.value
123.03
> round_test.round
7 11 . 0 (16)
> round_test.round.value
123.0
> round_test += 0.5
7 11 . 8 7 10 14 1 4 7 10 14 1 (16)
> round_test.value
123.53
> round_test.round
7 12 . 0 (16)
> round_test.round.value
124.0

@return [Radix::Float] New Instance

# File lib/radix/float.rb, line 265
def round
  return self.class.new((value + 0.5).floor, base) if self > 0.0
  return self.class.new((value - 0.5).ceil,  base) if self < 0.0
  return self.class.new(0, base)
end
to_a(base=nil) click to toggle source

Makes this Radix::Float an array using code if defined. Returns an array using default chars otherwise.

@param [Fixnum] base

Desired base.

@return [Array<Fixnum, String>] Current base encoded array.

# File lib/radix/float.rb, line 108
def to_a(base=nil)
  if base
    convert(base).digits_encoded
  else
    digits_encoded
  end
end
to_f() click to toggle source

Makes this Radix::Float a ruby float.

@return [Float] Base(10) value as Float.

# File lib/radix/float.rb, line 96
def to_f
  value.to_f
end
to_i() click to toggle source

Makes this Radix::Float a ruby Integer.

@return [Integer] Base(10) value as Integer.

# File lib/radix/float.rb, line 86
def to_i
  to_f.to_i
end
Also aliased as: to_int
to_int()
Alias for: to_i
to_s(base=nil, divider=nil) click to toggle source

Creates an encoded string in passed base, with passed digit divider.

@note For base 10 or less does not use a divider unless specified.

@param [Fixnum, Array<String>] base

Desired base.

@param [String] divider

Desired divider character(s).

@return [String] Encoded string with specified divider.

# File lib/radix/float.rb, line 128
def to_s(base=nil, divider=nil)
  divider = divider.to_s if divider
  if base
    convert(base).to_s(nil, divider)
  else
    if code
      digits_encoded.join(divider)
    else
      if @base > 10
        digits.join(divider || DIVIDER)
      else
        digits.join(divider)
      end
    end
  end
end

Private Instance Methods

base_conversion(value, base, prec=10) click to toggle source

Returns two arrays. The integer part and the fractional part of the Float value in param base.

@param [Float] value Float’s decimal value. @param [Fixnum] base The base level of Float instance. @param [Fixnum] prec The # of places to extend F-part.

@return [Array<(Array, Array)>]

# File lib/radix/float.rb, line 374
def base_conversion(value, base, prec=10)
  #if value < 0
  #  @negative, value = true, value.abs
  #end
  value = value.to_f.abs

  i, f = split_float(value)

  a = []
  while i > 0
    i, r = i.divmod(base)
    a << r
  end

  #c = [] # f-cache
  p = prec
  b = []
  while !f.zero?
    k = (f * base)
    r, f = split_float(k)
    #c.include?(f) ? break : c << f
    break if p == 0; p -= 1
    b << r
  end

  a << 0 if a.empty?
  b << 0 if b.empty?

  [a.reverse, b]
end
decimal(digits, base) click to toggle source

Convert array of values of a different base to decimal as called by parse_array.

@param [Array<Numeric, String>] digits Representation of Base values. @param [Fixnum, Array<String>] base The base to convert from.

@return [Float] The digits of base converted to decimal.

# File lib/radix/float.rb, line 413
def decimal(digits, base)
  i, f = split_digits(digits)
  e = i.size - 1
  v = 0
  (i + f).each do |n|
    v += n * base**e
    e -= 1
  end
  v
end
operation(op, other) click to toggle source

Perform passed arithmetic operation.

@param [#to_f] other

@return [Radix::Float] Result of binary operation in @base.

# File lib/radix/float.rb, line 357
def operation(op, other)
  a = self.to_f
  b = other.to_f
  x = a.__send__(op, b)
  Radix::Float.new(x, base)

end
parse_value(value, base) click to toggle source

Takes a Radix::Numeric, String or array and returns the decimal float value for storage in @value.

@param [Radix::Numeric, Numeric, String, Array<Numeric, String>] value

The value of the integer in base context.

@param [Fixnum, Array<String>] base

The context base of value.

@return [Float] Float value of Integer.

# File lib/radix/float.rb, line 67
def parse_value(value, base)
  case value
  when Float, Integer # Radix
    parse_numeric(value.to_f, base)
  when ::Array
    parse_array(value, base)
  when ::String
    parse_string(value, base)
  when ::Numeric
    parse_numeric(value.to_f, base)
  end
end
split_digits(value) click to toggle source

Returns the I-Part and F-Part of the passed value as arrays of fixnums.

@param [Array<Numeric, String>] value

The array of decimal values per column of @base.

@return [Array<(Array<Fixnum>, Array<Fixnum>)>]

# File lib/radix/float.rb, line 431
def split_digits(value)
  if d = value.index(DOT) || value.index('.')
    i, f = value[0...d], value[d+1..-1]
  else
    i, f = value, [0]
  end
  i.map!{ |x| x.to_i }
  f.map!{ |x| x.to_i }
  return i, f
end
split_float(float) click to toggle source

Returns an array of Integer and Float portions of the Radix::Float

@param [Radix::Float] float Float value to split

@return [Array<(Integer, Float)>]

# File lib/radix/float.rb, line 448
def split_float(float)
  i, f = float.to_s.split('.')
  return i.to_i, ('0.'+f).to_f
end