Bug #10086 » Remove_Rational#power_from_mathn.patch
lib/mathn.rb | ||
---|---|---|
end
|
||
##
|
||
# When mathn is required Rational is changed to simplify the use of Rational
|
||
# operations.
|
||
#
|
||
# Normal behaviour:
|
||
#
|
||
# Rational.new!(1,3) ** 2 # => Rational(1, 9)
|
||
# (1 / 3) ** 2 # => 0
|
||
#
|
||
# require 'mathn' behaviour:
|
||
#
|
||
# (1 / 3) ** 2 # => 1/9
|
||
class Rational
|
||
remove_method :**
|
||
##
|
||
# Exponentiate by +other+
|
||
#
|
||
# (1/3) ** 2 # => 1/9
|
||
def ** (other)
|
||
if other.kind_of?(Rational)
|
||
other2 = other
|
||
if self < 0
|
||
return Complex(self, 0.0) ** other
|
||
elsif other == 0
|
||
return Rational(1,1)
|
||
elsif self == 0
|
||
return Rational(0,1)
|
||
elsif self == 1
|
||
return Rational(1,1)
|
||
end
|
||
npd = numerator.prime_division
|
||
dpd = denominator.prime_division
|
||
if other < 0
|
||
other = -other
|
||
npd, dpd = dpd, npd
|
||
end
|
||
for elm in npd
|
||
elm[1] = elm[1] * other
|
||
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
|
||
return Float(self) ** other2
|
||
end
|
||
elm[1] = elm[1].to_i
|
||
end
|
||
for elm in dpd
|
||
elm[1] = elm[1] * other
|
||
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
|
||
return Float(self) ** other2
|
||
end
|
||
elm[1] = elm[1].to_i
|
||
end
|
||
num = Integer.from_prime_division(npd)
|
||
den = Integer.from_prime_division(dpd)
|
||
Rational(num,den)
|
||
elsif other.kind_of?(Integer)
|
||
if other > 0
|
||
num = numerator ** other
|
||
den = denominator ** other
|
||
elsif other < 0
|
||
num = denominator ** -other
|
||
den = numerator ** -other
|
||
elsif other == 0
|
||
num = 1
|
||
den = 1
|
||
end
|
||
Rational(num, den)
|
||
elsif other.kind_of?(Float)
|
||
Float(self) ** other
|
||
else
|
||
x , y = other.coerce(self)
|
||
x ** y
|
||
end
|
||
end
|
||
end
|
||
##
|
||
# When mathn is required, the Math module changes as follows:
|
||
#
|
||
# Standard Math module behaviour:
|