@@ -19,18 +19,15 @@ class BigDecimal
1919 # Related: BigDecimal#power.
2020 #
2121 def **( y )
22- unless y . is_a? ( BigDecimal )
23- case y
24- when Integer , Float , Rational
25- y = BigDecimal ( y , 0 )
26- when nil
27- raise TypeError , 'wrong argument type NilClass'
28- else
29- x , y = y . coerce ( self )
30- return x **y
31- end
22+ case y
23+ when BigDecimal , Integer , Float , Rational
24+ power ( y )
25+ when nil
26+ raise TypeError , 'wrong argument type NilClass'
27+ else
28+ x , y = y . coerce ( self )
29+ x **y
3230 end
33- power ( y )
3431 end
3532
3633 # call-seq:
@@ -44,7 +41,7 @@ def **(y)
4441 def power ( y , prec = nil )
4542 BigMath . _validate_prec ( prec , :power ) if prec
4643 x = self
47- y = BigMath . _coerce_to_bigdecimal ( y , :power )
44+ y = BigMath . _coerce_to_bigdecimal ( y , prec || n_significant_digits , :power )
4845
4946 return BigMath . _nan_computation_result if x . nan? || y . nan?
5047 return BigDecimal ( 1 ) if y . zero?
@@ -145,12 +142,17 @@ def power(y, prec = nil)
145142# Core BigMath methods for BigDecimal (log, exp) are defined here.
146143# Other methods (sin, cos, atan) are defined in 'bigdecimal/math.rb'.
147144module BigMath
148- def self . _coerce_to_bigdecimal ( x , method_name , complex_domain_error = false ) # :nodoc:
145+
146+ # Coerce x to BigDecimal with the specified precision.
147+ # TODO: some methods (example: BigMath.exp) require more precision than specified to coerce.
148+ def self . _coerce_to_bigdecimal ( x , prec , method_name , complex_domain_error = false ) # :nodoc:
149149 case x
150150 when BigDecimal
151151 return x
152- when Integer , Float , Rational
153- return BigDecimal ( x , 0 )
152+ when Integer , Float
153+ return BigDecimal ( x )
154+ when Rational
155+ return BigDecimal ( x , [ prec , 2 * BigDecimal . double_fig ] . max )
154156 when Complex
155157 if complex_domain_error
156158 raise Math ::DomainError , "Complex argument for BigMath.#{ method_name } "
@@ -192,7 +194,7 @@ def self._nan_computation_result # :nodoc:
192194 #
193195 def self . log ( x , prec )
194196 _validate_prec ( prec , :log )
195- x = _coerce_to_bigdecimal ( x , :log , true )
197+ x = _coerce_to_bigdecimal ( x , prec , :log , true )
196198 return _nan_computation_result if x . nan?
197199 raise Math ::DomainError , 'Zero or negative argument for log' if x <= 0
198200 return _infinity_computation_result if x . infinite?
@@ -258,7 +260,7 @@ def self.log(x, prec)
258260 #
259261 def self . exp ( x , prec )
260262 _validate_prec ( prec , :exp )
261- x = _coerce_to_bigdecimal ( x , :exp )
263+ x = _coerce_to_bigdecimal ( x , prec , :exp )
262264 return _nan_computation_result if x . nan?
263265 return x . positive? ? _infinity_computation_result : BigDecimal ( 0 ) if x . infinite?
264266 return BigDecimal ( 1 ) if x . zero?
0 commit comments