Skip to content

Commit eb1a3c7

Browse files
committed
Revert "Add a workaround for slow BigDecimal#to_f when it has large N_significant_digits"
This reverts commit 8bb13f4.
1 parent 72937b7 commit eb1a3c7

File tree

2 files changed

+7
-16
lines changed

2 files changed

+7
-16
lines changed

lib/bigdecimal.rb

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,9 @@ def self.newton_loop(prec, initial_precision: BigDecimal.double_fig / 2, safe_ma
7676
end
7777
end
7878

79-
# Fast and rough conversion to float for mathematical calculations.
80-
# Bigdecimal#to_f is slow when n_significant_digits is large.
81-
# This is because to_f internally converts BigDecimal to String
82-
# to get the exact nearest float representation.
83-
# TODO: Remove this workaround when BigDecimal#to_f is optimized.
84-
def self.fast_to_f(x) # :nodoc:
85-
x.n_significant_digits < 40 ? x.to_f : x.mult(1, 20).to_f
86-
end
87-
8879
# Calculates Math.log(x.to_f) considering large or small exponent
8980
def self.float_log(x) # :nodoc:
90-
Math.log(fast_to_f(x._decimal_shift(-x.exponent))) + x.exponent * Math.log(10)
81+
Math.log(x._decimal_shift(-x.exponent).to_f) + x.exponent * Math.log(10)
9182
end
9283

9384
# Calculating Taylor series sum using binary splitting method
@@ -277,7 +268,7 @@ def sqrt(prec)
277268

278269
ex = exponent / 2
279270
x = _decimal_shift(-2 * ex)
280-
y = BigDecimal(Math.sqrt(BigDecimal::Internal.fast_to_f(x)), 0)
271+
y = BigDecimal(Math.sqrt(x.to_f), 0)
281272
Internal.newton_loop(prec + BigDecimal::Internal::EXTRA_PREC) do |p|
282273
y = y.add(x.div(y, p), p).div(2, p)
283274
end

lib/bigdecimal/math.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def cbrt(x, prec)
144144
x = -x if neg = x < 0
145145
ex = x.exponent / 3
146146
x = x._decimal_shift(-3 * ex)
147-
y = BigDecimal(Math.cbrt(BigDecimal::Internal.fast_to_f(x)), 0)
147+
y = BigDecimal(Math.cbrt(x.to_f), 0)
148148
BigDecimal::Internal.newton_loop(prec + BigDecimal::Internal::EXTRA_PREC) do |p|
149149
y = (2 * y + x.div(y, p).div(y, p)).div(3, p)
150150
end
@@ -304,7 +304,7 @@ def atan(x, prec)
304304

305305
# Solve tan(y) - x = 0 with Newton's method
306306
# Repeat: y -= (tan(y) - x) * cos(y)**2
307-
y = BigDecimal(Math.atan(BigDecimal::Internal.fast_to_f(x)), 0)
307+
y = BigDecimal(Math.atan(x.to_f), 0)
308308
BigDecimal::Internal.newton_loop(n) do |p|
309309
s = sin(y, p)
310310
c = (1 - s * s).sqrt(p)
@@ -605,7 +605,7 @@ def erf(x, prec)
605605
return BigDecimal(1) if x > 5000000000 # erf(5000000000) > 1 - 1e-10000000000000000000
606606

607607
if x > 8
608-
xf = BigDecimal::Internal.fast_to_f(x)
608+
xf = x.to_f
609609
log10_erfc = -xf ** 2 / Math.log(10) - Math.log10(xf * Math::PI ** 0.5)
610610
erfc_prec = [prec + log10_erfc.ceil, 1].max
611611
erfc = _erfc_asymptotic(x, erfc_prec)
@@ -647,7 +647,7 @@ def erfc(x, prec)
647647
# erfc(x) = 1 - erf(x) < exp(-x**2)/x/sqrt(pi)
648648
# Precision of erf(x) needs about log10(exp(-x**2)/x/sqrt(pi)) extra digits
649649
log10 = 2.302585092994046
650-
xf = BigDecimal::Internal.fast_to_f(x)
650+
xf = x.to_f
651651
high_prec = prec + BigDecimal::Internal::EXTRA_PREC + ((xf**2 + Math.log(xf) + Math.log(Math::PI)/2) / log10).ceil
652652
BigDecimal(1).sub(erf(x, high_prec), prec)
653653
end
@@ -698,7 +698,7 @@ def erfc(x, prec)
698698
# sqrt(2)/2 + k*log(k) - k - 2*k*log(x) < -prec*log(10)
699699
# and the left side is minimized when k = x**2.
700700
prec += BigDecimal::Internal::EXTRA_PREC
701-
xf = BigDecimal::Internal.fast_to_f(x)
701+
xf = x.to_f
702702
kmax = (1..(xf ** 2).floor).bsearch do |k|
703703
Math.log(2) / 2 + k * Math.log(k) - k - 2 * k * Math.log(xf) < -prec * Math.log(10)
704704
end

0 commit comments

Comments
 (0)