Class: BaseConvert::Number

Inherits:
Object
  • Object
show all
Includes:
BaseConvert, Configuration
Defined in:
lib/base_convert/number.rb

Constant Summary

Constants included from BaseConvert

VERSION

Constants included from Configuration

Configuration::AMBIGUOUS, Configuration::BASE, Configuration::BASE64, Configuration::DIGITS, Configuration::GRAPH, Configuration::INDEXa, Configuration::QGRAPH, Configuration::UNAMBIGUOUS, Configuration::WORD, Configuration::WORD_

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from BaseConvert

#tob, #toi

Constructor Details

#initialize(counter, base: nil, digits: nil, validate: true) ⇒ Number

Returns a new instance of Number.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/base_convert/number.rb', line 114

def initialize(counter, base: nil, digits: nil, validate: true)
  @base, @digits, @validate = base, digits, validate
  @string, @integer = nil, nil
  case counter
  when String
    @string = counter
    _integer!
  when Integer
    @integer = counter
    _string!
  else
    raise "Need counter String|Integer."
  end
end

Instance Attribute Details

#baseObject (readonly)

Returns the value of attribute base.



113
114
115
# File 'lib/base_convert/number.rb', line 113

def base
  @base
end

#digitsObject (readonly)

Returns the value of attribute digits.



113
114
115
# File 'lib/base_convert/number.rb', line 113

def digits
  @digits
end

Instance Method Details

#_base!Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/base_convert/number.rb', line 68

def _base!
  if @base.nil?
    _digits!
    if @integer.nil?
      @base = _infer_base_from_string
    else
      @base = @digits.length
    end
  else
    if @base.is_a? Symbol
      base = BASE[@base]
      raise "Unrecognized base #{@base}." if base.nil?
      @base = base
    else
      raise "base must be an Integer greater than 1." unless @base.is_a?(Integer) and @base > 1
    end
    _digits!
  end
end

#_digits!Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/base_convert/number.rb', line 43

def _digits!
  if @digits.nil?
    @digits = @integer.nil? ? _infer_digits_from_string : WORD
    if @base and @base > @digits.length
      if @base == 64
        @digits = BASE64
      elsif @base <= QGRAPH.length
        @digits = QGRAPH
      elsif @base <= GRAPH.length
        @digits = GRAPH
      else
        raise "Need digits that can cover base #{@base}."
      end
    end
  else
    if @digits.is_a? Symbol
      digits = DIGITS[@digits]
      raise "Unrecognized digits #{@digits}." if digits.nil?
      @digits = digits
    else
      raise "digits must be a String of at least length 2." unless @digits.is_a?(String) and @digits.length > 2
    end
  end
end

#_infer_base_from_stringObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/base_convert/number.rb', line 16

def _infer_base_from_string
  min = 1 + @digits.index(@string.chars.max)
  max = @digits.length
  return max if max==min
  case @digits
  when WORD, WORD_
    if min <= 32
      raise "Need base for WORD or WORD_." if @string.length < 8
      return  8 if min <= 8
      return 16 if min <= 16
      return 32
    end
  when UNAMBIGUOUS
    if min <= 22
      raise "Need base for UNAMBIGUOUS." if @string.length < 8
      return 22
    end
  when QGRAPH, GRAPH
    n = @digits.index 'a'
    if min <= n
      raise "Need base for QGRAPH or GRAPH." if @string.length < 8
      return n
    end
  end
  return max
end

#_infer_digits_from_stringObject



6
7
8
9
10
11
12
13
14
# File 'lib/base_convert/number.rb', line 6

def _infer_digits_from_string
  if @string.chars.all?{|_|WORD_.include?_}
    @string.include?('_')? WORD_ : WORD
  elsif @string.chars.all?{|_|GRAPH.include?_}
    @string.match?(/['"`]/)? GRAPH : QGRAPH
  else
    raise "Need digits."
  end
end

#_integer!Object



100
101
102
103
104
105
# File 'lib/base_convert/number.rb', line 100

def _integer!
  _base!
  @string.upcase! if @base <= INDEXa and @digits == WORD
  _validate if @validate
  @integer = toi
end

#_string!Object



107
108
109
110
111
# File 'lib/base_convert/number.rb', line 107

def _string!
  _base!
  _validate if @validate
  @string = tob
end

#_validateObject



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/base_convert/number.rb', line 88

def _validate
  raise "digits must cover base." if @base > @digits.length
  raise "digits must not have duplicates." if @digits.length > @digits.chars.uniq.length
  unless @string.nil?
    raise "digits must cover string." unless @string.chars.all?{|_|@digits.include?_}
    raise "digits in string must be under base." unless @base > @digits.index(@string.chars.max)
  end
  unless @integer.nil?
    raise "integer can't be negative." if @integer < 0
  end
end

#to_base(base, digits = @digits, validate = @validate) ⇒ Object



137
138
139
# File 'lib/base_convert/number.rb', line 137

def to_base(base, digits=@digits, validate=@validate)
  Number.new @integer, base: base, digits: digits, validate: validate
end

#to_digits(digits, base = @base, validate = @validate) ⇒ Object



141
142
143
# File 'lib/base_convert/number.rb', line 141

def to_digits(digits, base=@base, validate=@validate)
  Number.new @integer, base: base, digits: digits, validate: validate
end

#to_iObject



133
134
135
# File 'lib/base_convert/number.rb', line 133

def to_i
  @integer
end

#to_sObject



129
130
131
# File 'lib/base_convert/number.rb', line 129

def to_s
  @string
end