class BigDecimal
def **(y)
Related: BigDecimal#power.
b ** Rational(2, 1) # => 0.98596e1
b ** 2.0 # => 0.98596e1
b ** 2 # => 0.98596e1
b = BigDecimal('3.14')
Returns the \BigDecimal value of +self+ raised to power +other+:
self ** other -> bigdecimal
call-seq:
def **(y) case y when BigDecimal, Integer, Float, Rational power(y) when nil raise TypeError, 'wrong argument type NilClass' else x, y = y.coerce(self) x**y end end
def _decimal_shift(i) # :nodoc:
def _decimal_shift(i) # :nodoc: to_java.move_point_right(i).to_d end
def power(y, prec = 0)
Also available as the operator **.
Returns the value raised to the power of n.
power(n, prec)
power(n)
call-seq:
def power(y, prec = 0) prec = Internal.coerce_validate_prec(prec, :power, accept_zero: true) x = self y = Internal.coerce_to_bigdecimal(y, prec.nonzero? || n_significant_digits, :power) return Internal.nan_computation_result if x.nan? || y.nan? return BigDecimal(1) if y.zero? if y.infinite? if x < 0 return BigDecimal(0) if x < -1 && y.negative? return BigDecimal(0) if x > -1 && y.positive? raise Math::DomainError, 'Result undefined for negative base raised to infinite power' elsif x < 1 return y.positive? ? BigDecimal(0) : BigDecimal::Internal.infinity_computation_result elsif x == 1 return BigDecimal(1) else return y.positive? ? BigDecimal::Internal.infinity_computation_result : BigDecimal(0) end end if x.infinite? && y < 0 # Computation result will be +0 or -0. Avoid overflow. neg = x < 0 && y.frac.zero? && y % 2 == 1 return neg ? -BigDecimal(0) : BigDecimal(0) end if x.zero? return BigDecimal(1) if y.zero? return BigDecimal(0) if y > 0 if y.frac.zero? && y % 2 == 1 && x.sign == -1 return -BigDecimal::Internal.infinity_computation_result else return BigDecimal::Internal.infinity_computation_result end elsif x < 0 if y.frac.zero? if y % 2 == 0 return (-x).power(y, prec) else return -(-x).power(y, prec) end else raise Math::DomainError, 'Computation results in complex number' end elsif x == 1 return BigDecimal(1) end limit = BigDecimal.limit frac_part = y.frac if frac_part.zero? && prec.zero? && limit.zero? # Infinite precision calculation for `x ** int` and `x.power(int)` int_part = y.fix.to_i int_part = -int_part if (neg = int_part < 0) ans = BigDecimal(1) n = 1 xn = x while true ans *= xn if int_part.allbits?(n) n <<= 1 break if n > int_part xn *= xn # Detect overflow/underflow before consuming infinite memory if (xn.exponent.abs - 1) * int_part / n >= 0x7FFFFFFFFFFFFFFF return ((xn.exponent > 0) ^ neg ? BigDecimal::Internal.infinity_computation_result : BigDecimal(0)) * (int_part.even? || x > 0 ? 1 : -1) end end return neg ? BigDecimal(1) / ans : ans end result_prec = prec.nonzero? || [x.n_significant_digits, y.n_significant_digits, BigDecimal.double_fig].max + BigDecimal.double_fig result_prec = [result_prec, limit].min if prec.zero? && limit.nonzero? prec2 = result_prec + BigDecimal::Internal::EXTRA_PREC if y < 0 inv = x.power(-y, prec2) return BigDecimal(0) if inv.infinite? return BigDecimal::Internal.infinity_computation_result if inv.zero? return BigDecimal(1).div(inv, result_prec) end if frac_part.zero? && y.exponent < Math.log(result_prec) * 5 + 20 # Use exponentiation by squaring if y is an integer and not too large pow_prec = prec2 + y.exponent n = 1 xn = x ans = BigDecimal(1) int_part = y.fix.to_i while true ans = ans.mult(xn, pow_prec) if int_part.allbits?(n) n <<= 1 break if n > int_part xn = xn.mult(xn, pow_prec) end ans.mult(1, result_prec) else if x > 1 && x.finite? # To calculate exp(z, prec), z needs prec+max(z.exponent, 0) precision if z > 0. # Estimate (y*log(x)).exponent logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).round ylogx_exponent = y.exponent + logx_exponent prec2 += [ylogx_exponent, 0].max end BigMath.exp(BigMath.log(x, prec2).mult(y, prec2), result_prec) end end
def sqrt(prec)
Result has at least prec significant digits.
Returns the square root of the value.
def sqrt(prec) prec = Internal.coerce_validate_prec(prec, :sqrt, accept_zero: true) return Internal.infinity_computation_result if infinite? == 1 raise FloatDomainError, 'sqrt of negative value' if self < 0 raise FloatDomainError, "sqrt of 'NaN'(Not a Number)" if nan? return self if zero? if prec == 0 limit = BigDecimal.limit prec = n_significant_digits + BigDecimal.double_fig prec = [limit, prec].min if limit.nonzero? end ex = exponent / 2 x = _decimal_shift(-2 * ex) y = BigDecimal(Math.sqrt(BigDecimal::Internal.fast_to_f(x)), 0) Internal.newton_loop(prec + BigDecimal::Internal::EXTRA_PREC) do |p| y = y.add(x.div(y, p), p).div(2, p) end y._decimal_shift(ex).mult(1, prec) end
def to_d
d.to_d # => 0.314e1
d = BigDecimal("3.14")
require 'bigdecimal/util'
Returns self.
a.to_d -> bigdecimal
call-seq:
def to_d self end
def to_digits
d.to_digits # => "3.14"
d = BigDecimal("3.14")
require 'bigdecimal/util'
This method is deprecated; use BigDecimal#to_s("F") instead.
Converts a BigDecimal to a String of the form "nnnnnn.mmm".
a.to_digits -> string
call-seq:
def to_digits if self.nan? || self.infinite? || self.zero? self.to_s else i = self.to_i.to_s _,f,_,z = self.frac.split i + "." + ("0"*(-z)) + f end end