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 power(y, prec = nil)
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 = nil) Internal.validate_prec(prec, :power) if prec x = self y = Internal.coerce_to_bigdecimal(y, prec || 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 prec ||= BigDecimal.limit.nonzero? frac_part = y.frac if frac_part.zero? && !prec # 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 prec ||= [x.n_significant_digits, y.n_significant_digits, BigDecimal.double_fig].max + BigDecimal.double_fig if y < 0 inv = x.power(-y, prec) return BigDecimal(0) if inv.infinite? return BigDecimal::Internal.infinity_computation_result if inv.zero? return BigDecimal(1).div(inv, prec) end int_part = y.fix.to_i prec2 = prec + BigDecimal.double_fig pow_prec = prec2 + (int_part > 0 ? y.exponent : 0) ans = BigDecimal(1) n = 1 xn = x 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 unless frac_part.zero? ans = ans.mult(BigMath.exp(BigMath.log(x, prec2).mult(frac_part, prec2), prec2), prec2) end ans.mult(1, prec) end
def sqrt(prec)
Result has at least prec significant digits.
Returns the square root of the value.
def sqrt(prec) Internal.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? limit = BigDecimal.limit.nonzero? if prec == 0 # BigDecimal#sqrt calculates at least n_significant_digits precision. # This feature maybe problematic for some cases. n_digits = n_significant_digits prec = [prec, n_digits].max ex = exponent / 2 x = _decimal_shift(-2 * ex) y = BigDecimal(Math.sqrt(x.to_f)) precs = [prec + BigDecimal.double_fig] precs << 2 + precs.last / 2 while precs.last > BigDecimal.double_fig precs.reverse_each do |p| y = y.add(x.div(y, p), p).div(2, p) end y = y.mult(1, limit) if limit y._decimal_shift(ex) 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