Rewrite BigDecimal#sqrt in ruby with improved Newton's method#381
Rewrite BigDecimal#sqrt in ruby with improved Newton's method#381tompng merged 4 commits intoruby:masterfrom
Conversation
lib/bigdecimal.rb
Outdated
| if infinite? == 1 | ||
| exception_mode = BigDecimal.mode(BigDecimal::EXCEPTION_ALL) | ||
| raise FloatDomainError, "Computation results in 'Infinity'" if exception_mode.anybits?(BigDecimal::EXCEPTION_INFINITY) |
There was a problem hiding this comment.
@tompng, how do you think about extracting the infinity check and exception-raising part as a method?
There was a problem hiding this comment.
This is sqrt-specific condition. For example, Math.atan(infinity)=π/2, `"Computation results in 'Infinity'" is not a correct message.
We can re-consider adding a common infinity check method later, for unbounded monotonic increasing function and other types, but I think it's too early for now.
There was a problem hiding this comment.
Sorry I misread the comment. Changed to:
return BigMath._infinity_computation_result if infinite? == 1This method is added in #389 and used in BigDecimal#power, BigMath.exp and BigMath.log.
lib/bigdecimal.rb
Outdated
| prec = [prec, n_digits].max | ||
|
|
||
| ex = exponent / 2 | ||
| x = self * BigDecimal("1e#{-ex * 2}") |
There was a problem hiding this comment.
@tompng, I think this square root calculation can be faster if we use decimal shift operations here and on line 37, as we previously discussed. What about this?
There was a problem hiding this comment.
I think it's good to use decimal shift operator. I've updated #324 as ready for review.
f045650 to
db8554d
Compare
db8554d to
27d554a
Compare
a8976b6 to
337219a
Compare
337219a to
d6a3b69
Compare
d6a3b69 to
cd1a743
Compare
cd1a743 to
dae780d
Compare
Implement sqrt in ruby with faster Newton's method implementation.
Related to #323 (doing the same rewrite with Integer.sqrt)
Example calculating BigDecimal(2).sqrt in 116 precision
Minimum loop count, minimum precision in each step.
The original c implementation was slow for large precision because it was not doing this.
Small precision: gets slower
Large precision: faster