diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mathn.rb | 97 |
1 files changed, 50 insertions, 47 deletions
diff --git a/lib/mathn.rb b/lib/mathn.rb index 618f82077b..61de1ff9ac 100644 --- a/lib/mathn.rb +++ b/lib/mathn.rb @@ -73,40 +73,43 @@ end class Rational remove_method :** + + ## + # exponentiate by +other+ def ** (other) if other.kind_of?(Rational) other2 = other if self < 0 - return Complex(self, 0.0) ** other + return Complex(self, 0.0) ** other elsif other == 0 - return Rational(1,1) + return Rational(1,1) elsif self == 0 - return Rational(0,1) + return Rational(0,1) elsif self == 1 - return Rational(1,1) + return Rational(1,1) end npd = numerator.prime_division dpd = denominator.prime_division if other < 0 - other = -other - npd, dpd = dpd, npd + 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 + 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 + 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) @@ -116,14 +119,14 @@ class Rational elsif other.kind_of?(Integer) if other > 0 - num = numerator ** other - den = denominator ** other + num = numerator ** other + den = denominator ** other elsif other < 0 - num = denominator ** -other - den = numerator ** -other + num = denominator ** -other + den = numerator ** -other elsif other == 0 - num = 1 - den = 1 + num = 1 + den = 1 end Rational(num, den) elsif other.kind_of?(Float) @@ -144,17 +147,17 @@ module Math if a.kind_of?(Complex) abs = sqrt(a.real*a.real + a.imag*a.imag) # if not abs.kind_of?(Rational) -# return a**Rational(1,2) +# return a**Rational(1,2) # end x = sqrt((a.real + abs)/Rational(2)) y = sqrt((-a.real + abs)/Rational(2)) # if !(x.kind_of?(Rational) and y.kind_of?(Rational)) -# return a**Rational(1,2) +# return a**Rational(1,2) # end if a.imag >= 0 - Complex(x, y) + Complex(x, y) else - Complex(x, -y) + Complex(x, -y) end elsif a.respond_to?(:nan?) and a.nan? a @@ -176,36 +179,36 @@ module Math byte_a = [src & 0xffffffff] # ruby's bug while (src >= max) and (src >>= 32) - byte_a.unshift src & 0xffffffff + byte_a.unshift src & 0xffffffff end answer = 0 main = 0 side = 0 for elm in byte_a - main = (main << 32) + elm - side <<= 16 - if answer != 0 - if main * 4 < side * side - applo = main.div(side) - else - applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1 - end - else - applo = sqrt!(main).to_i + 1 - end - - while (x = (side + applo) * applo) > main - applo -= 1 - end - main -= x - answer = (answer << 16) + applo - side += applo * 2 + main = (main << 32) + elm + side <<= 16 + if answer != 0 + if main * 4 < side * side + applo = main.div(side) + else + applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1 + end + else + applo = sqrt!(main).to_i + 1 + end + + while (x = (side + applo) * applo) > main + applo -= 1 + end + main -= x + answer = (answer << 16) + applo + side += applo * 2 end if main == 0 - answer + answer else - sqrt!(a) + sqrt!(a) end end end |