1 # depends on: class.rb comparable.rb
6 # Numeric and sub-classes do not have ivars
7 def __ivars__ ; nil ; end
18 b, a = math_coerce other
23 b, a = math_coerce other
28 b, a = math_coerce other
33 b, a = math_coerce other
34 raise ZeroDivisionError, "divided by 0" unless b.__kind_of__(Float) or b != 0
39 # see README-DEVELOPERS regarding safe math compiler plugin
43 b, a = math_coerce other
44 raise ZeroDivisionError, "divided by 0" unless b.__kind_of__(Float) or b != 0
47 alias_method :/, :divide
50 b, a = math_coerce other
55 b, a = math_coerce other
58 raise FloatDomainError, "NaN" if other.__kind_of__ Float
59 raise ZeroDivisionError, "divided by 0"
66 raise FloatDomainError, "NaN" if self == 0 && other.__kind_of__(Float) && other == 0
67 b, a = math_coerce other
72 if other.__kind_of__ Integer
75 b, a = math_coerce other
81 b, a = math_coerce other, :compare_error
86 b, a = math_coerce other, :compare_error
91 b, a = math_coerce other, :compare_error
96 b, a = math_coerce other, :compare_error
101 return true if other.equal?(self)
107 b, a = math_coerce other, :compare_error
118 # Delegate #to_int to #to_i in subclasses
123 # Delegate #modulp to #% in subclasses
145 self < 0 ? -self : self
150 if self == int or self > 0
159 if self == int or self < 0
167 b, a = math_coerce other
170 if mod != 0 && (a < 0 && b > 0 || a > 0 && b < 0)
178 # We deviate from MRI behavior here because we ensure that Fixnum op Bignum
179 # => Bignum (possibly normalized to Fixnum)
181 # Note these differences on MRI, where a is a Fixnum, b is a Bignum
183 # a.coerce b => [Float, Float]
184 # b.coerce a => [Bignum, Bignum]
188 Ruby.primitive :numeric_coerce
189 [Float(other), Float(self)]
193 # This method mimics the semantics of MRI's do_coerce function
194 # in numeric.c. Note these differences between it and #coerce:
196 # 1.2.coerce("2") => [2.0, 1.2]
197 # 1.2 + "2" => TypeError: String can't be coerced into Float
199 # See also Integer#coerce
201 def math_coerce(other, error=:coerce_error)
203 values = other.coerce(self)
208 unless values.__kind_of__(Array) && values.length == 2
209 raise TypeError, "coerce must return [x, y]"
212 return values[1], values[0]
216 def coerce_error(other)
217 raise TypeError, "#{other.class} can't be coerced into #{self.class}"
219 private :coerce_error
221 def compare_error(other)
222 raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
224 private :compare_error
226 def step(limit, step=1, &block)
227 raise ArgumentError, "step cannot be 0" if step == 0
228 limit,step = step.coerce(limit)
229 # FIXME: why is this not covered by the block parameter above?
230 raise LocalJumpError, "no block given" unless block_given?
231 idx,step = step.coerce(self)
232 cmp = step > 0 ? :<= : :>=
233 while (idx.send(cmp,limit))
238 rescue TypeError => e
239 raise ArgumentError, e.message