@@ -144,10 +144,10 @@ def power(y, prec = 0)
144144 return BigDecimal ( 1 )
145145 end
146146
147- prec = BigDecimal . limit if prec . zero?
147+ limit = BigDecimal . limit
148148 frac_part = y . frac
149149
150- if frac_part . zero? && prec . zero?
150+ if frac_part . zero? && prec . zero? && limit . zero?
151151 # Infinite precision calculation for `x ** int` and `x.power(int)`
152152 int_part = y . fix . to_i
153153 int_part = -int_part if ( neg = int_part < 0 )
@@ -167,18 +167,19 @@ def power(y, prec = 0)
167167 return neg ? BigDecimal ( 1 ) / ans : ans
168168 end
169169
170- prec = [ x . n_significant_digits , y . n_significant_digits , BigDecimal . double_fig ] . max + BigDecimal . double_fig if prec . zero?
170+ result_prec = prec . nonzero? || [ x . n_significant_digits , y . n_significant_digits , BigDecimal . double_fig ] . max + BigDecimal . double_fig
171+ result_prec = [ result_prec , limit ] . min if prec . zero? && limit . nonzero?
172+
173+ prec2 = result_prec + BigDecimal . double_fig
171174
172175 if y < 0
173- inv = x . power ( -y , prec )
176+ inv = x . power ( -y , prec2 )
174177 return BigDecimal ( 0 ) if inv . infinite?
175178 return BigDecimal ::Internal . infinity_computation_result if inv . zero?
176- return BigDecimal ( 1 ) . div ( inv , prec )
179+ return BigDecimal ( 1 ) . div ( inv , result_prec )
177180 end
178181
179- prec2 = prec + BigDecimal . double_fig
180-
181- if frac_part . zero? && y . exponent < Math . log ( prec ) * 5 + 20
182+ if frac_part . zero? && y . exponent < Math . log ( result_prec ) * 5 + 20
182183 # Use exponentiation by squaring if y is an integer and not too large
183184 pow_prec = prec2 + y . exponent
184185 n = 1
@@ -191,7 +192,7 @@ def power(y, prec = 0)
191192 break if n > int_part
192193 xn = xn . mult ( xn , pow_prec )
193194 end
194- ans . mult ( 1 , prec )
195+ ans . mult ( 1 , result_prec )
195196 else
196197 if x > 1
197198 # To calculate exp(z, prec), z needs prec+max(z.exponent, 0) precision if z > 0.
@@ -200,7 +201,7 @@ def power(y, prec = 0)
200201 ylogx_exponent = y . exponent + logx_exponent
201202 prec2 += [ ylogx_exponent , 0 ] . max
202203 end
203- BigMath . exp ( BigMath . log ( x , prec2 ) . mult ( y , prec2 ) , prec )
204+ BigMath . exp ( BigMath . log ( x , prec2 ) . mult ( y , prec2 ) , result_prec )
204205 end
205206 end
206207
@@ -217,7 +218,9 @@ def sqrt(prec)
217218 return self if zero?
218219
219220 if prec == 0
220- prec = BigDecimal . limit . nonzero? || n_significant_digits + BigDecimal . double_fig
221+ limit = BigDecimal . limit
222+ prec = n_significant_digits + BigDecimal . double_fig
223+ prec = [ limit , prec ] . min if limit . nonzero?
221224 end
222225
223226 ex = exponent / 2
0 commit comments