BigMath 모듈
BigMath 모듈
수학 함수를 제공하는 모듈이에요. BigDecimal과 함께 고정밀 수학 계산을 할 수 있어요.
require "bigdecimal/math"
include BigMath
a = BigDecimal((PI(100)/2).to_s)
puts sin(a,100) # => 0.99999999999999999999......e0
출처: Ruby 3.3 API
본문
exp(decimal, numeric) → BigDecimal
decimal을 지수로 하는 자연로그의 밑 e의 거듭제곱 값을, 지정한 자릿수의 정밀도(numeric)로 계산해요.
decimal이 무한대면 Infinity를 반환하고, NaN이면 NaN을 반환해요. (내부 C 구현은 BigMath_s_exp이며, 연속 항 d <- d*x/i를 누적하는 테일러 급수 방식으로 e^x를 계산해요.)
log(decimal, numeric) → BigDecimal
decimal의 자연로그를 지정한 자릿수의 정밀도(numeric)로 계산해요.
decimal이 0 또는 음수면 Math::DomainError를 발생시키고, 양의 무한대면 Infinity를, NaN이면 NaN을 반환해요. (내부 C 구현은 BigMath_s_log이며, 인자를 [0, 3) 범위로 정규화한 뒤 급수 전개로 계산해요.)
Public Instance Methods
E(numeric) → BigDecimal
자연로그의 밑 e를 지정한 자릿수의 정밀도(numeric)로 계산해요.
BigMath.E(10).to_s
#=> "0.271828182845904523536028752390026306410273e1"
# File ext/bigdecimal/lib/bigdecimal/math.rb, line 228
def E(prec)
raise ArgumentError, "Zero or negative precision for E" if prec <= 0
BigMath.exp(1, prec)
end
PI(numeric) → BigDecimal
원주율 π를 지정한 자릿수의 정밀도(numeric)로 계산해요.
BigMath.PI(10).to_s
#=> "0.3141592653589793238462643388813853786957412e1"
# File ext/bigdecimal/lib/bigdecimal/math.rb, line 183
def PI(prec)
raise ArgumentError, "Zero or negative precision for PI" if prec <= 0
n = prec + BigDecimal.double_fig
zero = BigDecimal("0")
one = BigDecimal("1")
two = BigDecimal("2")
m25 = BigDecimal("-0.04")
m57121 = BigDecimal("-57121")
pi = zero
d = one
k = one
t = BigDecimal("-80")
while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
t = t*m25
d = t.div(k,m)
k = k+two
pi = pi + d
end
d = one
k = one
t = BigDecimal("956")
while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
t = t.div(m57121,n)
d = t.div(k,m)
pi = pi + d
k = k+two
end
pi
end
atan(decimal, numeric) → BigDecimal
decimal의 아크탄젠트를 지정한 자릿수의 정밀도(numeric)로 계산해요.
decimal이 NaN이면 NaN을 반환해요.
BigMath.atan(BigDecimal('-1'), 16).to_s
#=> "-0.785398163397448309615660845819878471907514682065e0"
# File ext/bigdecimal/lib/bigdecimal/math.rb, line 146
def atan(x, prec)
raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
return BigDecimal("NaN") if x.nan?
pi = PI(prec)
x = -x if neg = x < 0
return pi.div(neg ? -2 : 2, prec) if x.infinite?
return pi / (neg ? -4 : 4) if x.round(prec) == 1
x = BigDecimal("1").div(x, prec) if inv = x > 1
x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5
n = prec + BigDecimal.double_fig
y = x
d = y
t = x
r = BigDecimal("3")
x2 = x.mult(x,n)
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
t = -t.mult(x2,n)
d = t.div(r,m)
y += d
r += 2
end
y *= 2 if dbl
y = pi / 2 - y if inv
y = -y if neg
y
end
cos(decimal, numeric) → BigDecimal
decimal의 코사인 값을 지정한 자릿수의 정밀도(numeric)로 계산해요.
decimal이 Infinity 또는 NaN이면 NaN을 반환해요.
BigMath.cos(BigMath.PI(4), 16).to_s
#=> "-0.999999999999999999999999999999856613163740061349e0"
# File ext/bigdecimal/lib/bigdecimal/math.rb, line 102
def cos(x, prec)
raise ArgumentError, "Zero or negative precision for cos" if prec <= 0
return BigDecimal("NaN") if x.infinite? || x.nan?
n = prec + BigDecimal.double_fig
one = BigDecimal("1")
two = BigDecimal("2")
x = -x if x < 0
if x > (twopi = two * BigMath.PI(prec))
if x > 30
x %= twopi
else
x -= twopi while x > twopi
end
end
x1 = one
x2 = x.mult(x,n)
sign = 1
y = one
d = y
i = BigDecimal("0")
z = one
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
sign = -sign
x1 = x2.mult(x1,n)
i += two
z *= (i-one) * i
d = sign * x1.div(z,m)
y += d
end
y
end
sin(decimal, numeric) → BigDecimal
decimal의 사인 값을 지정한 자릿수의 정밀도(numeric)로 계산해요.
decimal이 Infinity 또는 NaN이면 NaN을 반환해요.
BigMath.sin(BigMath.PI(5)/4, 5).to_s
#=> "0.70710678118654752440082036563292800375e0"
# File ext/bigdecimal/lib/bigdecimal/math.rb, line 58
def sin(x, prec)
raise ArgumentError, "Zero or negative precision for sin" if prec <= 0
return BigDecimal("NaN") if x.infinite? || x.nan?
n = prec + BigDecimal.double_fig
one = BigDecimal("1")
two = BigDecimal("2")
x = -x if neg = x < 0
if x > (twopi = two * BigMath.PI(prec))
if x > 30
x %= twopi
else
x -= twopi while x > twopi
end
end
x1 = x
x2 = x.mult(x,n)
sign = 1
y = x
d = y
i = one
z = one
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
sign = -sign
x1 = x2.mult(x1,n)
i += two
z *= (i-one) * i
d = sign * x1.div(z,m)
y += d
end
neg ? -y : y
end
sqrt(decimal, numeric) → BigDecimal
decimal의 제곱근을 지정한 자릿수의 정밀도(numeric)로 계산해요.
BigMath.sqrt(BigDecimal('2'), 16).to_s
#=> "0.1414213562373095048801688724e1"
# File ext/bigdecimal/lib/bigdecimal/math.rb, line 43
def sqrt(x, prec)
x.sqrt(prec)
end
더 알아보기
BigDecimal— 고정밀 10진 부동소수점을 다루는 클래스.require "bigdecimal/math"로 로드하면BigMath모듈을 사용할 수 있어요.