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
encoding table.
@return [Array<String>, nil] Substitution chars or nil if default.
Internal floating point value.
@return [Float] Float’s decimal value.
Public Class Methods
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) @base, @code = parse_base(base) @value = parse_value(value, @base) end
Public Instance Methods
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Returns a new Radix::Float
instance of same base, rounded to the nearest whole integer.
> 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
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
Convert Radix::Float
to a Ruby float.
@return [Float] Base(10) value as Float
.
# File lib/radix/float.rb, line 96 def to_f value.to_f end
Convert the 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
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
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
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
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
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
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