mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/cmath.rb: make same exception for Math. fix [Bug #3137].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32297 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
549d4feecd
commit
09dee51be3
2 changed files with 180 additions and 96 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Thu Jun 30 00:30:15 2011 Keiju Ishitsuka <keiju@ishitsuka.com>
|
||||||
|
|
||||||
|
* lib/cmath.rb: make same exception for Math. fix [Bug #3137].
|
||||||
|
|
||||||
Thu Jun 30 00:03:20 2011 Keiju Ishitsuka <keiju@ishitsuka.com>
|
Thu Jun 30 00:03:20 2011 Keiju Ishitsuka <keiju@ishitsuka.com>
|
||||||
|
|
||||||
* lib/irb/completion.rb: complate correctry string literal. fix
|
* lib/irb/completion.rb: complate correctry string literal. fix
|
||||||
|
|
90
lib/cmath.rb
90
lib/cmath.rb
|
@ -50,6 +50,7 @@ module CMath
|
||||||
# exp(Complex(0,PI)) #=> -1.0+1.2246467991473532e-16i
|
# exp(Complex(0,PI)) #=> -1.0+1.2246467991473532e-16i
|
||||||
# exp(Complex(0,PI/2.0)) #=> 6.123233995736766e-17+1.0i
|
# exp(Complex(0,PI/2.0)) #=> 6.123233995736766e-17+1.0i
|
||||||
def exp(z)
|
def exp(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
exp!(z)
|
exp!(z)
|
||||||
else
|
else
|
||||||
|
@ -57,6 +58,9 @@ module CMath
|
||||||
Complex(ere * cos!(z.imag),
|
Complex(ere * cos!(z.imag),
|
||||||
ere * sin!(z.imag))
|
ere * sin!(z.imag))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -65,7 +69,11 @@ module CMath
|
||||||
#
|
#
|
||||||
# log(Complex(0,0)) #=> -Infinity+0.0i
|
# log(Complex(0,0)) #=> -Infinity+0.0i
|
||||||
def log(*args)
|
def log(*args)
|
||||||
|
begin
|
||||||
z, b = args
|
z, b = args
|
||||||
|
unless b.kind_of?(Numeric)
|
||||||
|
raise TypeError, "Numeric Number required"
|
||||||
|
end
|
||||||
if z.real? and z >= 0 and (b.nil? or b >= 0)
|
if z.real? and z >= 0 and (b.nil? or b >= 0)
|
||||||
log!(*args)
|
log!(*args)
|
||||||
else
|
else
|
||||||
|
@ -75,26 +83,37 @@ module CMath
|
||||||
end
|
end
|
||||||
a
|
a
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the base 2 logarithm of +z+
|
# returns the base 2 logarithm of +z+
|
||||||
def log2(z)
|
def log2(z)
|
||||||
|
begin
|
||||||
if z.real? and z >= 0
|
if z.real? and z >= 0
|
||||||
log2!(z)
|
log2!(z)
|
||||||
else
|
else
|
||||||
log(z) / log!(2)
|
log(z) / log!(2)
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the base 10 logarithm of +z+
|
# returns the base 10 logarithm of +z+
|
||||||
def log10(z)
|
def log10(z)
|
||||||
|
begin
|
||||||
if z.real? and z >= 0
|
if z.real? and z >= 0
|
||||||
log10!(z)
|
log10!(z)
|
||||||
else
|
else
|
||||||
log(z) / log!(10)
|
log(z) / log!(10)
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -103,6 +122,7 @@ module CMath
|
||||||
# sqrt(Complex(-1,0)) #=> 0.0+1.0i
|
# sqrt(Complex(-1,0)) #=> 0.0+1.0i
|
||||||
# sqrt(Complex(0,8)) #=> 2.0+2.0i
|
# sqrt(Complex(0,8)) #=> 2.0+2.0i
|
||||||
def sqrt(z)
|
def sqrt(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
if z < 0
|
if z < 0
|
||||||
Complex(0, sqrt!(-z))
|
Complex(0, sqrt!(-z))
|
||||||
|
@ -119,6 +139,9 @@ module CMath
|
||||||
Complex(sqrt!((r + x) / 2.0), sqrt!((r - x) / 2.0))
|
Complex(sqrt!((r + x) / 2.0), sqrt!((r - x) / 2.0))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -130,136 +153,188 @@ module CMath
|
||||||
##
|
##
|
||||||
# returns the sine of +z+, where +z+ is given in radians
|
# returns the sine of +z+, where +z+ is given in radians
|
||||||
def sin(z)
|
def sin(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
sin!(z)
|
sin!(z)
|
||||||
else
|
else
|
||||||
Complex(sin!(z.real) * cosh!(z.imag),
|
Complex(sin!(z.real) * cosh!(z.imag),
|
||||||
cos!(z.real) * sinh!(z.imag))
|
cos!(z.real) * sinh!(z.imag))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the cosine of +z+, where +z+ is given in radians
|
# returns the cosine of +z+, where +z+ is given in radians
|
||||||
def cos(z)
|
def cos(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
cos!(z)
|
cos!(z)
|
||||||
else
|
else
|
||||||
Complex(cos!(z.real) * cosh!(z.imag),
|
Complex(cos!(z.real) * cosh!(z.imag),
|
||||||
-sin!(z.real) * sinh!(z.imag))
|
-sin!(z.real) * sinh!(z.imag))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the tangent of +z+, where +z+ is given in radians
|
# returns the tangent of +z+, where +z+ is given in radians
|
||||||
def tan(z)
|
def tan(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
tan!(z)
|
tan!(z)
|
||||||
else
|
else
|
||||||
sin(z) / cos(z)
|
sin(z) / cos(z)
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the hyperbolic sine of +z+, where +z+ is given in radians
|
# returns the hyperbolic sine of +z+, where +z+ is given in radians
|
||||||
def sinh(z)
|
def sinh(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
sinh!(z)
|
sinh!(z)
|
||||||
else
|
else
|
||||||
Complex(sinh!(z.real) * cos!(z.imag),
|
Complex(sinh!(z.real) * cos!(z.imag),
|
||||||
cosh!(z.real) * sin!(z.imag))
|
cosh!(z.real) * sin!(z.imag))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the hyperbolic cosine of +z+, where +z+ is given in radians
|
# returns the hyperbolic cosine of +z+, where +z+ is given in radians
|
||||||
def cosh(z)
|
def cosh(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
cosh!(z)
|
cosh!(z)
|
||||||
else
|
else
|
||||||
Complex(cosh!(z.real) * cos!(z.imag),
|
Complex(cosh!(z.real) * cos!(z.imag),
|
||||||
sinh!(z.real) * sin!(z.imag))
|
sinh!(z.real) * sin!(z.imag))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the hyperbolic tangent of +z+, where +z+ is given in radians
|
# returns the hyperbolic tangent of +z+, where +z+ is given in radians
|
||||||
def tanh(z)
|
def tanh(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
tanh!(z)
|
tanh!(z)
|
||||||
else
|
else
|
||||||
sinh(z) / cosh(z)
|
sinh(z) / cosh(z)
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the arc sine of +z+
|
# returns the arc sine of +z+
|
||||||
def asin(z)
|
def asin(z)
|
||||||
|
begin
|
||||||
if z.real? and z >= -1 and z <= 1
|
if z.real? and z >= -1 and z <= 1
|
||||||
asin!(z)
|
asin!(z)
|
||||||
else
|
else
|
||||||
(-1.0).i * log(1.0.i * z + sqrt(1.0 - z * z))
|
(-1.0).i * log(1.0.i * z + sqrt(1.0 - z * z))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the arc cosine of +z+
|
# returns the arc cosine of +z+
|
||||||
def acos(z)
|
def acos(z)
|
||||||
|
begin
|
||||||
if z.real? and z >= -1 and z <= 1
|
if z.real? and z >= -1 and z <= 1
|
||||||
acos!(z)
|
acos!(z)
|
||||||
else
|
else
|
||||||
(-1.0).i * log(z + 1.0.i * sqrt(1.0 - z * z))
|
(-1.0).i * log(z + 1.0.i * sqrt(1.0 - z * z))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the arc tangent of +z+
|
# returns the arc tangent of +z+
|
||||||
def atan(z)
|
def atan(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
atan!(z)
|
atan!(z)
|
||||||
else
|
else
|
||||||
1.0.i * log((1.0.i + z) / (1.0.i - z)) / 2.0
|
1.0.i * log((1.0.i + z) / (1.0.i - z)) / 2.0
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the arc tangent of +y+ divided by +x+ using the signs of +y+ and
|
# returns the arc tangent of +y+ divided by +x+ using the signs of +y+ and
|
||||||
# +x+ to determine the quadrant
|
# +x+ to determine the quadrant
|
||||||
def atan2(y,x)
|
def atan2(y,x)
|
||||||
|
begin
|
||||||
if y.real? and x.real?
|
if y.real? and x.real?
|
||||||
atan2!(y,x)
|
atan2!(y,x)
|
||||||
else
|
else
|
||||||
(-1.0).i * log((x + 1.0.i * y) / sqrt(x * x + y * y))
|
(-1.0).i * log((x + 1.0.i * y) / sqrt(x * x + y * y))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the inverse hyperbolic sine of +z+
|
# returns the inverse hyperbolic sine of +z+
|
||||||
def asinh(z)
|
def asinh(z)
|
||||||
|
begin
|
||||||
if z.real?
|
if z.real?
|
||||||
asinh!(z)
|
asinh!(z)
|
||||||
else
|
else
|
||||||
log(z + sqrt(1.0 + z * z))
|
log(z + sqrt(1.0 + z * z))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the inverse hyperbolic cosine of +z+
|
# returns the inverse hyperbolic cosine of +z+
|
||||||
def acosh(z)
|
def acosh(z)
|
||||||
|
begin
|
||||||
if z.real? and z >= 1
|
if z.real? and z >= 1
|
||||||
acosh!(z)
|
acosh!(z)
|
||||||
else
|
else
|
||||||
log(z + sqrt(z * z - 1.0))
|
log(z + sqrt(z * z - 1.0))
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# returns the inverse hyperbolic tangent of +z+
|
# returns the inverse hyperbolic tangent of +z+
|
||||||
def atanh(z)
|
def atanh(z)
|
||||||
|
begin
|
||||||
if z.real? and z >= -1 and z <= 1
|
if z.real? and z >= -1 and z <= 1
|
||||||
atanh!(z)
|
atanh!(z)
|
||||||
else
|
else
|
||||||
log((1.0 + z) / (1.0 - z)) / 2.0
|
log((1.0 + z) / (1.0 - z)) / 2.0
|
||||||
end
|
end
|
||||||
|
rescue NoMethodError
|
||||||
|
handle_no_method_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module_function :exp!
|
module_function :exp!
|
||||||
|
@ -313,10 +388,15 @@ module CMath
|
||||||
module_function :gamma
|
module_function :gamma
|
||||||
module_function :lgamma
|
module_function :lgamma
|
||||||
|
|
||||||
|
private
|
||||||
|
def handle_no_method_error
|
||||||
|
if $!.name == :real?
|
||||||
|
raise TypeError, "Numeric Number required"
|
||||||
|
else
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
end
|
||||||
|
module_function :handle_no_method_error
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Object
|
|
||||||
def real?
|
|
||||||
raise TypeError, "Numeric Number required"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue