Class: Fixed

Inherits:
Numeric
  • Object
show all
Defined in:
lib/is/fixed.rb

Constant Summary collapse

VERSION =
'0.2.0'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(number = 0, shift = nil) ⇒ Fixed

Returns a new instance of Fixed.

Parameters:

  • number (Numeric) (defaults to: 0)
  • shift (Integer) (defaults to: nil)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/is/fixed.rb', line 65

def initialize number = 0, shift = nil
  if ! precision
    raise 'Undefined precision.'
  end
  case number
  when Fixed
    np = number.precision + (shift || 0)
    if np = precision
      @number = number.number
    elsif np < precision
      @number = number.number * 10 ** (precision - np)
    else
      nn = number.number.divmod(10 ** (np - precision))
      @number = nn[0] + (nn[1] < 5 && 0 || 1)
    end
  when Integer
    np = (shift || 0)
    if np == precision
      @number = number
    elsif np < precision
      @number = number * 10 ** (precision - np)
    else
      nn = number.divmod(10 ** (np - precision))
      @number = nn[0] + (nn[1] < 5 && 0 || 1)
    end
  else
    np = (shift || 0)
    @number = (Float(number) * Float(10) ** (precision - np)).round
  end
end

Class Attribute Details

.precisionInteger

Returns:

  • (Integer)


10
11
12
# File 'lib/is/fixed.rb', line 10

def precision
  @precision
end

Instance Attribute Details

#numberInteger (readonly, protected)

Returns:

  • (Integer)


57
58
59
# File 'lib/is/fixed.rb', line 57

def number
  @number
end

#precisionInteger (readonly, protected)

Returns:

  • (Integer)


54
55
56
# File 'lib/is/fixed.rb', line 54

def precision
  @precision
end

Class Method Details

.[](value) ⇒ Fixed

Parameters:

  • value (Numeric)

Returns:



42
43
44
# File 'lib/is/fixed.rb', line 42

def [] value
  self.new value
end

.number(value, precision) ⇒ Fixed

Parameters:

  • value (Numeric)
  • precision (Integer)

Returns:



36
37
38
# File 'lib/is/fixed.rb', line 36

def number value, precision
  subclass(precision).new(value)
end

.subclass(precision) ⇒ Class

Parameters:

  • precision (Integer)

Returns:

  • (Class)


24
25
26
27
28
29
30
31
# File 'lib/is/fixed.rb', line 24

def subclass precision
  @@classes ||= []
  if ! @@classes[precision]
    @@classes[precision] = Class.new(Fixed)
    @@classes[precision].precision = precision
  end
  @@classes[precision]
end

.to_sString

Returns:

  • (String)


47
48
49
# File 'lib/is/fixed.rb', line 47

def to_s
  name || "Fixed(#{@precision})"
end

Instance Method Details

#*(other) ⇒ Fixed

Parameters:

  • other (Numeric)

Returns:



121
122
123
124
125
126
127
128
129
130
# File 'lib/is/fixed.rb', line 121

def * other
  case other
  when Fixed
    self.class.new @number * other.number, precision + other.precision
  when Integer
    self.class.new @number * other, precision
  else
    self.class.new (Float(other) * @number).round, precision
  end
end

#**(other) ⇒ Fixed

Parameters:

  • other (Numeric)

Returns:



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/is/fixed.rb', line 151

def ** other
  case other
  when Integer
    n = self.class.new 1
    if other > 0
      other.times { n = n * self }
    elsif other < 0
      other.times { n = n / self }
    end
    n
  when Fixed
    if other.integer?
      self ** other.to_i
    else
      self ** other.to_f
    end
  else
    self.class.new self.to_f ** Float(other)
  end
end

#+(other) ⇒ Fixed

Parameters:

  • other (Numeric)

Returns:



108
109
110
111
# File 'lib/is/fixed.rb', line 108

def + other
  other = self.class.new other
  self.class.new @number + other.number, precision
end

#+@Fixed

Returns:



97
98
99
# File 'lib/is/fixed.rb', line 97

def +@
  self
end

#-(other) ⇒ Fixed

Parameters:

  • other (Numeric)

Returns:



115
116
117
# File 'lib/is/fixed.rb', line 115

def - other
  self + (-other)
end

#-@Fixed

Returns:



102
103
104
# File 'lib/is/fixed.rb', line 102

def -@
  self.class.new -@number, precision
end

#/(other) ⇒ Fixed

Parameters:

  • other (Numeric)

Returns:



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/is/fixed.rb', line 134

def / other
  # /
  case other
  when Fixed
    n = @number * 10 ** other.precision
    nn = n.divmod other.number
    self.class.new nn[0] + (nn[1] < 5 && 0 || 1), precision
  when Integer
    nn = @number.divmod other
    self.class.new nn[0] + (nn[1] < 5 && 0 || 1) / other.number, precision
  else
    self.class.new Float(@number) / Float(other), precision
  end
end

#<=>(other) ⇒ Object



196
197
198
199
200
201
202
# File 'lib/is/fixed.rb', line 196

def <=> other
  if precision >= other.precision
    @number <=> self.class.new(other).number
  else
    other.class.new(self).number <=> other.number
  end
end

#absObject



204
205
206
# File 'lib/is/fixed.rb', line 204

def abs
  self.class.new(@number.abs, precision)
end

#abs2Object



208
209
210
# File 'lib/is/fixed.rb', line 208

def abs2
  self * self
end

#coerce(other) ⇒ Object



212
213
214
215
216
217
218
# File 'lib/is/fixed.rb', line 212

def coerce other
  if Integer === other
    [self.class.new(other), self]
  else
    super other
  end
end

#integer?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/is/fixed.rb', line 172

def integer?
  @number.divmod(10 ** precision)[1] == 0
end

#to_fFloat

Returns:

  • (Float)


182
183
184
# File 'lib/is/fixed.rb', line 182

def to_f
  Float(@number) / Float(10 ** precision)
end

#to_iInteger

Returns:

  • (Integer)


177
178
179
# File 'lib/is/fixed.rb', line 177

def to_i
  @number.divmod(10 ** precision)[0]
end

#to_sString

Returns:

  • (String)


187
188
189
190
191
192
193
194
# File 'lib/is/fixed.rb', line 187

def to_s
  s = @number.to_s
  l = s.length
  if l <= precision
    s = '0' * (precision - l + 1) + s
  end
  "#{s[0...-precision]}.#{s[-precision..-1]}"
end