# frozen_string_literal: falserequire'bigdecimal'##--# Contents:# sqrt(x, prec)# sin (x, prec)# cos (x, prec)# atan(x, prec)# PI (prec)# E (prec) == exp(1.0,prec)## where:# x ... BigDecimal number to be computed.# prec ... Number of digits to be obtained.#++## Provides mathematical functions.## Example:## require "bigdecimal/math"## include BigMath## a = BigDecimal((PI(100)/2).to_s)# puts sin(a,100) # => 0.99999999999999999999......e0#moduleBigMathmodule_function# call-seq:# sqrt(decimal, numeric) -> BigDecimal## Computes the square root of +decimal+ to the specified number of digits of# precision, +numeric+.## BigMath.sqrt(BigDecimal('2'), 16).to_s# #=> "0.1414213562373095048801688724e1"#defsqrt(x,prec)x.sqrt(prec)end# call-seq:# sin(decimal, numeric) -> BigDecimal## Computes the sine of +decimal+ to the specified number of digits of# precision, +numeric+.## If +decimal+ is Infinity or NaN, returns NaN.## BigMath.sin(BigMath.PI(5)/4, 5).to_s# #=> "0.70710678118654752440082036563292800375e0"#defsin(x,prec)raiseArgumentError,"Zero or negative precision for sin"ifprec<=0returnBigDecimal("NaN")ifx.infinite?||x.nan?n=prec+BigDecimal.double_figone=BigDecimal("1")two=BigDecimal("2")x=-xifneg=x<0ifx>(twopi=two*BigMath.PI(prec))ifx>30x%=twopielsex-=twopiwhilex>twopiendendx1=xx2=x.mult(x,n)sign=1y=xd=yi=onez=onewhiled.nonzero?&&((m=n-(y.exponent-d.exponent).abs)>0)m=BigDecimal.double_figifm<BigDecimal.double_figsign=-signx1=x2.mult(x1,n)i+=twoz*=(i-one)*id=sign*x1.div(z,m)y+=dendneg?-y:yend# call-seq:# cos(decimal, numeric) -> BigDecimal## Computes the cosine of +decimal+ to the specified number of digits of# precision, +numeric+.## If +decimal+ is Infinity or NaN, returns NaN.## BigMath.cos(BigMath.PI(4), 16).to_s# #=> "-0.999999999999999999999999999999856613163740061349e0"#defcos(x,prec)raiseArgumentError,"Zero or negative precision for cos"ifprec<=0returnBigDecimal("NaN")ifx.infinite?||x.nan?n=prec+BigDecimal.double_figone=BigDecimal("1")two=BigDecimal("2")x=-xifx<0ifx>(twopi=two*BigMath.PI(prec))ifx>30x%=twopielsex-=twopiwhilex>twopiendendx1=onex2=x.mult(x,n)sign=1y=oned=yi=BigDecimal("0")z=onewhiled.nonzero?&&((m=n-(y.exponent-d.exponent).abs)>0)m=BigDecimal.double_figifm<BigDecimal.double_figsign=-signx1=x2.mult(x1,n)i+=twoz*=(i-one)*id=sign*x1.div(z,m)y+=dendyend# call-seq:# atan(decimal, numeric) -> BigDecimal## Computes the arctangent of +decimal+ to the specified number of digits of# precision, +numeric+.## If +decimal+ is NaN, returns NaN.## BigMath.atan(BigDecimal('-1'), 16).to_s# #=> "-0.785398163397448309615660845819878471907514682065e0"#defatan(x,prec)raiseArgumentError,"Zero or negative precision for atan"ifprec<=0returnBigDecimal("NaN")ifx.nan?pi=PI(prec)x=-xifneg=x<0returnpi.div(neg?-2:2,prec)ifx.infinite?returnpi/(neg?-4:4)ifx.round(prec)==1x=BigDecimal("1").div(x,prec)ifinv=x>1x=(-1+sqrt(1+x**2,prec))/xifdbl=x>0.5n=prec+BigDecimal.double_figy=xd=yt=xr=BigDecimal("3")x2=x.mult(x,n)whiled.nonzero?&&((m=n-(y.exponent-d.exponent).abs)>0)m=BigDecimal.double_figifm<BigDecimal.double_figt=-t.mult(x2,n)d=t.div(r,m)y+=dr+=2endy*=2ifdbly=pi/2-yifinvy=-yifnegyend# call-seq:# PI(numeric) -> BigDecimal## Computes the value of pi to the specified number of digits of precision,# +numeric+.## BigMath.PI(10).to_s# #=> "0.3141592653589793238462643388813853786957412e1"#defPI(prec)raiseArgumentError,"Zero or negative precision for PI"ifprec<=0n=prec+BigDecimal.double_figzero=BigDecimal("0")one=BigDecimal("1")two=BigDecimal("2")m25=BigDecimal("-0.04")m57121=BigDecimal("-57121")pi=zerod=onek=onet=BigDecimal("-80")whiled.nonzero?&&((m=n-(pi.exponent-d.exponent).abs)>0)m=BigDecimal.double_figifm<BigDecimal.double_figt=t*m25d=t.div(k,m)k=k+twopi=pi+dendd=onek=onet=BigDecimal("956")whiled.nonzero?&&((m=n-(pi.exponent-d.exponent).abs)>0)m=BigDecimal.double_figifm<BigDecimal.double_figt=t.div(m57121,n)d=t.div(k,m)pi=pi+dk=k+twoendpiend# call-seq:# E(numeric) -> BigDecimal## Computes e (the base of natural logarithms) to the specified number of# digits of precision, +numeric+.## BigMath.E(10).to_s# #=> "0.271828182845904523536028752390026306410273e1"#defE(prec)raiseArgumentError,"Zero or negative precision for E"ifprec<=0BigMath.exp(1,prec)endend