class Numerals::Format::ExpSetter

Adjust exponent to be used in a Numeral expression;
break up the numeral into integer, fractional and repeating parts.

  setter = ExpSetter[numeral]
  # To use 'fixed' format:
  setter.exponent = 0
  # To use scientific notation:
  setter.integer_part_size = 1
  # To adjust scientific notation to engineering mode:
  setter.integer_part_size += 1 (while setter.exponent % 3) != 0
  # To automatically choose between fixed/scientific format:
  setter.exponent = 0 # fixed
  if setter.leading_size > 6 || setter.trailing_size > 0
    setter.integer_part_size = 1 # scientific
  end

  # To access the numeric parts for formatting:

  setter.sign

setter.integer_part # digits before radix point
setter.fractional_part # digits after radix point, before repetition
setter.repeating_part  # repeated digits
setter.base            # base for exponent
setter.exponent        # exponent

Attributes

exponent[R]
fractional_insignificant_size[R]
integer_insignificant_size[R]
integer_part_size[R]
leading_size[R]
numeral[R]
trailing_size[R]

Public Class Methods

new(numeral, options={}) click to toggle source
# File lib/numerals/format/exp_setter.rb, line 29
def initialize(numeral, options={})
  @insignificant_digits = options[:insignificant_digits] || 0
  @numeral = numeral
  @integer_part_size = @numeral.point
  @digits = @numeral.digits
  @exponent = 0
  @repeat_size = @numeral.repeating? ? @digits.size - @numeral.repeat : 0
  adjust
end

Public Instance Methods

base() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 45
def base
  @numeral.base
end
exponent=(v) click to toggle source
# File lib/numerals/format/exp_setter.rb, line 69
def exponent=(v)
  if @exponent != v
    @integer_part_size -= (v - @exponent)
    @exponent = v
    adjust
  end
end
exponent_base() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 49
def exponent_base
  base
end
fractional_part() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 106
def fractional_part
  leading + @digits[@fractional_start...@fractional_end]
end
fractional_part_size() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 114
def fractional_part_size
  @fractional_end - @fractional_start + @leading_size
end
integer_part() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 110
def integer_part
  @digits[@integer_start...@integer_end] + trailing
end
integer_part_size=(v) click to toggle source
# File lib/numerals/format/exp_setter.rb, line 77
def integer_part_size=(v)
  if @integer_part_size != v
    @exponent -= (v - @integer_part_size)
    @integer_part_size = v
    adjust
  end
end
repeat_insignificant_size() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 120
def repeat_insignificant_size
  0
end
repeat_part() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 85
def repeat_part
  if @numeral.repeating?
    if @repeat_phase != 0 || @numeral.repeat < 0
      start = @numeral.repeat + @repeat_phase
      (start...start+repeat_part_size).map{|i| @numeral.digit_value_at(i)}
    else
      @digits[@numeral.repeat..-1]
    end
  else
    []
  end
end
repeat_part_size() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 98
def repeat_part_size
  if @numeral.repeating?
    @digits.size - @numeral.repeat
  else
    0
  end
end
repeating?() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 61
def repeating?
  @numeral.repeating?
end
sign() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 65
def sign
  @numeral.sign
end
special() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 57
def special
  @numeral.special
end
special?() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 53
def special?
  @numeral.special?
end

Private Instance Methods

adjust() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 146
def adjust
  raise "Inconsistet number of insignficant digits" if @numeral.repeating? && @insignificant_digits > 0
  if special?
    @leading_size = @trailing_size = 0
    @integer_start = @integer_end = 0
    @fractional_start = @fractional_end = 0
    @repeat_phase = 0
    @integer_insignificant_size = @fractional_insignificant_size = 0
  elsif @integer_part_size <= 0
    @trailing_size = 0
    # integer_part == []
    @integer_start = @integer_end = @digits.size
    @integer_insignificant_size = 0
    if !@numeral.repeating? || @numeral.repeat >= 0 || @integer_part_size >= @numeral.repeat
      @leading_size = -@integer_part_size
      @fractional_start = 0
      if @numeral.repeat
        if @numeral.repeat >= 0
          @fractional_end  = @numeral.repeat
        else
          @fractional_end = @digits.size
        end
        @fractional_insignificant_size = 0
      else
        @fractional_end = @digits.size
        @fractional_insignificant_size = [@insignificant_digits, @digits.size].min
      end
      @repeat_phase = 0
    else
      @leading_size = @numeral.repeat - @integer_part_size
      @trailing_size = 0
      @fractional_start = @fractional_end = @digits.size
      @fractional_insignificant_size = 0
      @repeat_phase = 0
    end
  elsif @integer_part_size >= @digits.size
    @trailing_size = @integer_part_size - @digits.size
    @leading_size = 0
    @integer_start = 0
    @integer_end = @digits.size
    @integer_insignificant_size = @insignificant_digits
    if @numeral.approximate?
      @integer_insignificant_size += @trailing_size
    end
    @fractional_insignificant_size = 0
    if @numeral.repeating?
      @repeat_phase = @trailing_size % repeat_part_size
      @fractional_start = @fractional_end = @digits.size
    else
      @repeat_phase = 0
      @fractional_start = @fractional_end = @digits.size
    end
  else
    @trailing_size = @leading_size = 0
    @integer_start = 0
    @integer_end   = @integer_part_size
    @integer_insignificant_size = [@insignificant_digits - (@digits.size - @integer_part_size), 0].max
    if @numeral.repeating? && @numeral.repeat < @integer_part_size
      @repeat_phase = (@integer_end - @numeral.repeat) % repeat_part_size
      @fractional_start = @fractional_end = @digits.size
      @fractional_insignificant_size = 0
    else
      @repeat_phase = 0
      @fractional_start = @integer_part_size
      @fractional_end   = @numeral.repeat || @digits.size
      @fractional_insignificant_size = [@insignificant_digits, @fractional_end - @fractional_start].min
    end
  end
end
leading() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 134
def leading
  n = @leading_size
  if @fractional_end < @fractional_start
    n += @fractional_end - @fractional_start
  end
  if n > 0
    [0]*n
  else
    []
  end
end
trailing() click to toggle source
# File lib/numerals/format/exp_setter.rb, line 126
def trailing
  if @trailing_size > 0
    (@digits.size...@digits.size+@trailing_size).map{|i| @numeral.digit_value_at(i)}
  else
    []
  end
end