rubysl-bigdecimal 1.0.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,25 +1,76 @@
1
1
  /*
2
2
  *
3
- * Ruby BigDecimal(Variable decimal precision) extension library.
3
+ * Ruby BigDecimal(Variable decimal precision) extension library.
4
4
  *
5
- * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
5
+ * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
6
6
  *
7
- * You may distribute under the terms of either the GNU General Public
8
- * License or the Artistic License, as specified in the README file
9
- * of this BigDecimal distribution.
7
+ * You may distribute under the terms of either the GNU General Public
8
+ * License or the Artistic License, as specified in the README file
9
+ * of this BigDecimal distribution.
10
10
  *
11
11
  * NOTES:
12
12
  * 2003-03-28 V1.0 checked in.
13
13
  *
14
14
  */
15
15
 
16
- #ifndef ____BIG_DECIMAL__H____
17
- #define ____BIG_DECIMAL__H____
16
+ #ifndef RUBY_BIG_DECIMAL_H
17
+ #define RUBY_BIG_DECIMAL_H 1
18
+
19
+ // Use RSTRING_PTR without caching on Rubinius
20
+ #define RSTRING_NOT_MODIFIED 1
21
+
22
+ #include "ruby/ruby.h"
23
+ #include <float.h>
18
24
 
19
25
  #if defined(__cplusplus)
20
26
  extern "C" {
21
27
  #endif
22
28
 
29
+ #ifndef HAVE_LABS
30
+ static inline long
31
+ labs(long const x)
32
+ {
33
+ if (x < 0) return -x;
34
+ return x;
35
+ }
36
+ #endif
37
+
38
+ #ifndef HAVE_LLABS
39
+ static inline LONG_LONG
40
+ llabs(LONG_LONG const x)
41
+ {
42
+ if (x < 0) return -x;
43
+ return x;
44
+ }
45
+ #endif
46
+
47
+ #ifdef vabs
48
+ # undef vabs
49
+ #endif
50
+ #if SIZEOF_VALUE <= SIZEOF_INT
51
+ # define vabs abs
52
+ #elif SIZEOF_VALUE <= SIZEOF_LONG
53
+ # define vabs labs
54
+ #elif SIZEOF_VALUE <= SIZEOF_LONG_LONG
55
+ # define vabs llabs
56
+ #endif
57
+
58
+ extern VALUE rb_cBigDecimal;
59
+
60
+ #if SIZEOF_BDIGITS >= 8
61
+ # define RMPD_COMPONENT_FIGURES 19
62
+ # define RMPD_BASE ((BDIGIT)10000000000000000000U)
63
+ #elif SIZEOF_BDIGITS >= 4
64
+ # define RMPD_COMPONENT_FIGURES 9
65
+ # define RMPD_BASE ((BDIGIT)1000000000U)
66
+ #elif SIZEOF_BDIGITS >= 2
67
+ # define RMPD_COMPONENT_FIGURES 4
68
+ # define RMPD_BASE ((BDIGIT)10000U)
69
+ #else
70
+ # define RMPD_COMPONENT_FIGURES 2
71
+ # define RMPD_BASE ((BDIGIT)100U)
72
+ #endif
73
+
23
74
  /*
24
75
  * NaN & Infinity
25
76
  */
@@ -29,15 +80,10 @@ extern "C" {
29
80
  #define SZ_NINF "-Infinity"
30
81
 
31
82
  /*
32
- * #define VP_EXPORT other than static to let VP_ routines
83
+ * #define VP_EXPORT other than static to let VP_ routines
33
84
  * be called from outside of this module.
34
85
  */
35
- #define VP_EXPORT static
36
-
37
- #define U_LONG unsigned long
38
- #define S_LONG long
39
- #define U_INT unsigned int
40
- #define S_INT int
86
+ #define VP_EXPORT static
41
87
 
42
88
  /* Exception codes */
43
89
  #define VP_EXCEPTION_ALL ((unsigned short)0x00FF)
@@ -45,12 +91,14 @@ extern "C" {
45
91
  #define VP_EXCEPTION_NaN ((unsigned short)0x0002)
46
92
  #define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004)
47
93
  #define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */
48
- #define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0001) /* 0x0010) */
94
+ #define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010)
49
95
 
50
96
  /* Following 2 exceptions cann't controlled by user */
51
97
  #define VP_EXCEPTION_OP ((unsigned short)0x0020)
52
98
  #define VP_EXCEPTION_MEMORY ((unsigned short)0x0040)
53
99
 
100
+ #define RMPD_EXCEPTION_MODE_DEFAULT 0U
101
+
54
102
  /* Computation mode */
55
103
  #define VP_ROUND_MODE ((unsigned short)0x0100)
56
104
  #define VP_ROUND_UP 1
@@ -61,6 +109,8 @@ extern "C" {
61
109
  #define VP_ROUND_FLOOR 6
62
110
  #define VP_ROUND_HALF_EVEN 7
63
111
 
112
+ #define RMPD_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP
113
+
64
114
  #define VP_SIGN_NaN 0 /* NaN */
65
115
  #define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
66
116
  #define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */
@@ -75,13 +125,13 @@ extern "C" {
75
125
  */
76
126
  typedef struct {
77
127
  VALUE obj; /* Back pointer(VALUE) for Ruby object. */
78
- U_LONG MaxPrec; /* Maximum precision size */
128
+ size_t MaxPrec; /* Maximum precision size */
79
129
  /* This is the actual size of pfrac[] */
80
130
  /*(frac[0] to frac[MaxPrec] are available). */
81
- U_LONG Prec; /* Current precision size. */
131
+ size_t Prec; /* Current precision size. */
82
132
  /* This indicates how much the. */
83
133
  /* the array frac[] is actually used. */
84
- S_INT exponent;/* Exponent part. */
134
+ SIGNED_VALUE exponent; /* Exponent part. */
85
135
  short sign; /* Attributes of the value. */
86
136
  /*
87
137
  * ==0 : NaN
@@ -93,23 +143,30 @@ typedef struct {
93
143
  * -3 : Negative infinite number
94
144
  */
95
145
  short flag; /* Not used in vp_routines,space for user. */
96
- U_LONG frac[1]; /* Pointer to array of fraction part. */
146
+ BDIGIT frac[1]; /* Pointer to array of fraction part. */
97
147
  } Real;
98
148
 
99
- /*
149
+ /*
100
150
  * ------------------
101
151
  * EXPORTables.
102
152
  * ------------------
103
153
  */
104
154
 
105
155
  VP_EXPORT Real *
106
- VpNewRbClass(U_LONG mx,char *str,VALUE klass);
156
+ VpNewRbClass(size_t mx, char const *str, VALUE klass);
107
157
 
108
- VP_EXPORT Real *VpCreateRbObject(U_LONG mx,const char *str);
158
+ VP_EXPORT Real *VpCreateRbObject(size_t mx,const char *str);
109
159
 
110
- VP_EXPORT U_LONG VpBaseFig(void);
111
- VP_EXPORT U_LONG VpDblFig(void);
112
- VP_EXPORT U_LONG VpBaseVal(void);
160
+ static inline BDIGIT
161
+ rmpd_base_value(void) { return RMPD_BASE; }
162
+ static inline size_t
163
+ rmpd_component_figures(void) { return RMPD_COMPONENT_FIGURES; }
164
+ static inline size_t
165
+ rmpd_double_figures(void) { return 1+DBL_DIG; }
166
+
167
+ #define VpBaseFig() rmpd_component_figures()
168
+ #define VpDblFig() rmpd_double_figures()
169
+ #define VpBaseVal() rmpd_base_value()
113
170
 
114
171
  /* Zero,Inf,NaN (isinf(),isnan() used to check) */
115
172
  VP_EXPORT double VpGetDoubleNaN(void);
@@ -118,50 +175,50 @@ VP_EXPORT double VpGetDoubleNegInf(void);
118
175
  VP_EXPORT double VpGetDoubleNegZero(void);
119
176
 
120
177
  /* These 2 functions added at v1.1.7 */
121
- VP_EXPORT U_LONG VpGetPrecLimit(void);
122
- VP_EXPORT U_LONG VpSetPrecLimit(U_LONG n);
178
+ VP_EXPORT size_t VpGetPrecLimit(void);
179
+ VP_EXPORT size_t VpSetPrecLimit(size_t n);
123
180
 
124
181
  /* Round mode */
125
- VP_EXPORT int VpIsRoundMode(unsigned long n);
126
- VP_EXPORT unsigned long VpGetRoundMode(void);
127
- VP_EXPORT unsigned long VpSetRoundMode(unsigned long n);
182
+ VP_EXPORT int VpIsRoundMode(unsigned short n);
183
+ VP_EXPORT unsigned short VpGetRoundMode(void);
184
+ VP_EXPORT unsigned short VpSetRoundMode(unsigned short n);
128
185
 
129
186
  VP_EXPORT int VpException(unsigned short f,const char *str,int always);
130
- #if 0
187
+ #if 0 /* unused */
131
188
  VP_EXPORT int VpIsNegDoubleZero(double v);
132
189
  #endif
133
- VP_EXPORT U_LONG VpNumOfChars(Real *vp,const char *pszFmt);
134
- VP_EXPORT U_LONG VpInit(U_LONG BaseVal);
135
- VP_EXPORT void *VpMemAlloc(U_LONG mb);
190
+ VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt);
191
+ VP_EXPORT size_t VpInit(BDIGIT BaseVal);
192
+ VP_EXPORT void *VpMemAlloc(size_t mb);
136
193
  VP_EXPORT void VpFree(Real *pv);
137
- VP_EXPORT Real *VpAlloc(U_LONG mx, const char *szVal);
138
- VP_EXPORT int VpAsgn(Real *c,Real *a,int isw);
139
- VP_EXPORT int VpAddSub(Real *c,Real *a,Real *b,int operation);
140
- VP_EXPORT int VpMult(Real *c,Real *a,Real *b);
141
- VP_EXPORT int VpDivd(Real *c,Real *r,Real *a,Real *b);
194
+ VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal);
195
+ VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
196
+ VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation);
197
+ VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b);
198
+ VP_EXPORT size_t VpDivd(Real *c,Real *r,Real *a,Real *b);
142
199
  VP_EXPORT int VpComp(Real *a,Real *b);
143
- VP_EXPORT S_LONG VpExponent10(Real *a);
200
+ VP_EXPORT ssize_t VpExponent10(Real *a);
144
201
  VP_EXPORT void VpSzMantissa(Real *a,char *psz);
145
202
  VP_EXPORT int VpToSpecialString(Real *a,char *psz,int fPlus);
146
- VP_EXPORT void VpToString(Real *a,char *psz,int fFmt,int fPlus);
147
- VP_EXPORT void VpToFString(Real *a,char *psz,int fFmt,int fPlus);
148
- VP_EXPORT int VpCtoV(Real *a,const char *int_chr,U_LONG ni,const char *frac,U_LONG nf,const char *exp_chr,U_LONG ne);
149
- VP_EXPORT int VpVtoD(double *d,S_LONG *e,Real *m);
203
+ VP_EXPORT void VpToString(Real *a, char *psz, size_t fFmt, int fPlus);
204
+ VP_EXPORT void VpToFString(Real *a, char *psz, size_t fFmt, int fPlus);
205
+ VP_EXPORT int VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne);
206
+ VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m);
150
207
  VP_EXPORT void VpDtoV(Real *m,double d);
151
- #if 0
208
+ #if 0 /* unused */
152
209
  VP_EXPORT void VpItoV(Real *m,S_INT ival);
153
210
  #endif
154
211
  VP_EXPORT int VpSqrt(Real *y,Real *x);
155
- VP_EXPORT int VpActiveRound(Real *y,Real *x,int f,int il);
156
- VP_EXPORT int VpMidRound(Real *y, int f, int nf);
157
- VP_EXPORT int VpLeftRound(Real *y, int f, int nf);
158
- VP_EXPORT void VpFrac(Real *y,Real *x);
159
- VP_EXPORT int VpPower(Real *y,Real *x,S_INT n);
212
+ VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il);
213
+ VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf);
214
+ VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf);
215
+ VP_EXPORT void VpFrac(Real *y, Real *x);
216
+ VP_EXPORT int VpPower(Real *y, Real *x, SIGNED_VALUE n);
160
217
 
161
218
  /* VP constants */
162
219
  VP_EXPORT Real *VpOne(void);
163
220
 
164
- /*
221
+ /*
165
222
  * ------------------
166
223
  * MACRO definitions.
167
224
  * ------------------
@@ -179,12 +236,12 @@ VP_EXPORT Real *VpOne(void);
179
236
  /* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */
180
237
  #define VpGetSign(a) (((a)->sign>0)?1:(-1))
181
238
  /* Change sign of a to a>0,a<0 if s = 1,-1 respectively */
182
- #define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((S_LONG)(a)->sign);else (a)->sign=-(short)Abs((S_LONG)(a)->sign);}
239
+ #define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((ssize_t)(a)->sign);else (a)->sign=-(short)Abs((ssize_t)(a)->sign);}
183
240
  /* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */
184
241
  #define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;}
185
242
 
186
243
  /* 1 */
187
- #define VpSetOne(a) {(a)->frac[0]=(a)->exponent=(a)->Prec=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;}
244
+ #define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;}
188
245
 
189
246
  /* ZEROs */
190
247
  #define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO)
@@ -209,12 +266,12 @@ VP_EXPORT Real *VpOne(void);
209
266
  #define VpHasVal(a) (a->frac[0])
210
267
  #define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1))
211
268
  #define VpExponent(a) (a->exponent)
212
- #ifdef _DEBUG
269
+ #ifdef BIGDECIMAL_DEBUG
213
270
  int VpVarCheck(Real * v);
214
- VP_EXPORT int VPrint(FILE *fp,char *cntl_chr,Real *a);
215
- #endif /* _DEBUG */
271
+ VP_EXPORT int VPrint(FILE *fp,const char *cntl_chr,Real *a);
272
+ #endif /* BIGDECIMAL_DEBUG */
216
273
 
217
274
  #if defined(__cplusplus)
218
275
  } /* extern "C" { */
219
276
  #endif
220
- #endif /* ____BIG_DECIMAL__H____ */
277
+ #endif /* RUBY_BIG_DECIMAL_H */
@@ -21,18 +21,20 @@
21
21
  # fx is f.values(x).
22
22
  #
23
23
  module Jacobian
24
+ module_function
25
+
24
26
  #--
25
27
  def isEqual(a,b,zero=0.0,e=1.0e-8)
26
28
  aa = a.abs
27
29
  bb = b.abs
28
30
  if aa == zero && bb == zero then
29
- true
31
+ true
30
32
  else
31
- if ((a-b)/(aa+bb)).abs < e then
32
- true
33
- else
34
- false
35
- end
33
+ if ((a-b)/(aa+bb)).abs < e then
34
+ true
35
+ else
36
+ false
37
+ end
36
38
  end
37
39
  end
38
40
  #++
@@ -52,17 +54,17 @@ module Jacobian
52
54
  s = f.zero
53
55
  deriv = []
54
56
  if(nRetry>100) then
55
- raize "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
57
+ raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]"
56
58
  end
57
59
  dx = dx*f.two
58
60
  x[i] += dx
59
61
  fxNew = f.values(x)
60
62
  for j in 0...n do
61
63
  if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then
62
- ok += 1
63
- deriv <<= (fxNew[j]-fx[j])/dx
64
+ ok += 1
65
+ deriv <<= (fxNew[j]-fx[j])/dx
64
66
  else
65
- deriv <<= f.zero
67
+ deriv <<= f.zero
66
68
  end
67
69
  end
68
70
  x[i] = xSave
@@ -77,7 +79,7 @@ module Jacobian
77
79
  for i in 0...n do
78
80
  df = dfdxi(f,fx,x,i)
79
81
  for j in 0...n do
80
- dfdx[j*n+i] = df[j]
82
+ dfdx[j*n+i] = df[j]
81
83
  end
82
84
  end
83
85
  dfdx
@@ -1,7 +1,11 @@
1
+ require 'bigdecimal'
2
+
1
3
  #
2
4
  # Solves a*x = b for x, using LU decomposition.
3
5
  #
4
6
  module LUSolve
7
+ module_function
8
+
5
9
  # Performs LU decomposition of the n by n matrix a.
6
10
  def ludecomp(a,n,zero=0,one=1)
7
11
  prec = BigDecimal.limit(nil)
@@ -12,24 +16,24 @@ module LUSolve
12
16
  nrmrow = zero
13
17
  ixn = i*n
14
18
  for j in 0...n do
15
- biggst = a[ixn+j].abs
16
- nrmrow = biggst if biggst>nrmrow
19
+ biggst = a[ixn+j].abs
20
+ nrmrow = biggst if biggst>nrmrow
17
21
  end
18
22
  if nrmrow>zero then
19
- scales <<= one.div(nrmrow,prec)
20
- else
21
- raise "Singular matrix"
23
+ scales <<= one.div(nrmrow,prec)
24
+ else
25
+ raise "Singular matrix"
22
26
  end
23
27
  end
24
28
  n1 = n - 1
25
29
  for k in 0...n1 do # Gaussian elimination with partial pivoting.
26
30
  biggst = zero;
27
31
  for i in k...n do
28
- size = a[ps[i]*n+k].abs*scales[ps[i]]
29
- if size>biggst then
30
- biggst = size
31
- pividx = i
32
- end
32
+ size = a[ps[i]*n+k].abs*scales[ps[i]]
33
+ if size>biggst then
34
+ biggst = size
35
+ pividx = i
36
+ end
33
37
  end
34
38
  raise "Singular matrix" if biggst<=zero
35
39
  if pividx!=k then
@@ -42,10 +46,10 @@ module LUSolve
42
46
  psin = ps[i]*n
43
47
  a[psin+k] = mult = a[psin+k].div(pivot,prec)
44
48
  if mult!=zero then
45
- pskn = ps[k]*n
46
- for j in (k+1)...n do
47
- a[psin+j] -= mult.mult(a[pskn+j],prec)
48
- end
49
+ pskn = ps[k]*n
50
+ for j in (k+1)...n do
51
+ a[psin+j] -= mult.mult(a[pskn+j],prec)
52
+ end
49
53
  end
50
54
  end
51
55
  end
@@ -72,12 +76,12 @@ module LUSolve
72
76
  x <<= b[ps[i]] - dot
73
77
  end
74
78
  (n-1).downto(0) do |i|
75
- dot = zero
76
- psin = ps[i]*n
77
- for j in (i+1)...n do
78
- dot = a[psin+j].mult(x[j],prec) + dot
79
- end
80
- x[i] = (x[i]-dot).div(a[psin+i],prec)
79
+ dot = zero
80
+ psin = ps[i]*n
81
+ for j in (i+1)...n do
82
+ dot = a[psin+j].mult(x[j],prec) + dot
83
+ end
84
+ x[i] = (x[i]-dot).div(a[psin+i],prec)
81
85
  end
82
86
  x
83
87
  end
@@ -1,3 +1,5 @@
1
+ require 'bigdecimal'
2
+
1
3
  #
2
4
  #--
3
5
  # Contents:
@@ -5,7 +7,6 @@
5
7
  # sin (x, prec)
6
8
  # cos (x, prec)
7
9
  # atan(x, prec) Note: |x|<1, x=0.9999 may not converge.
8
- # exp (x, prec)
9
10
  # log (x, prec)
10
11
  # PI (prec)
11
12
  # E (prec) == exp(1.0,prec)
@@ -29,11 +30,12 @@
29
30
  # puts sin(a,100) # -> 0.10000000000000000000......E1
30
31
  #
31
32
  module BigMath
33
+ module_function
32
34
 
33
- # Computes the square root of x to the specified number of digits of
35
+ # Computes the square root of x to the specified number of digits of
34
36
  # precision.
35
37
  #
36
- # BigDecimal.new('2').sqrt(16).to_s
38
+ # BigDecimal.new('2').sqrt(16).to_s
37
39
  # -> "0.14142135623730950488016887242096975E1"
38
40
  #
39
41
  def sqrt(x,prec)
@@ -49,6 +51,14 @@ module BigMath
49
51
  n = prec + BigDecimal.double_fig
50
52
  one = BigDecimal("1")
51
53
  two = BigDecimal("2")
54
+ x = -x if neg = x < 0
55
+ if x > (twopi = two * BigMath.PI(prec))
56
+ if x > 30
57
+ x %= twopi
58
+ else
59
+ x -= twopi while x > twopi
60
+ end
61
+ end
52
62
  x1 = x
53
63
  x2 = x.mult(x,n)
54
64
  sign = 1
@@ -65,7 +75,7 @@ module BigMath
65
75
  d = sign * x1.div(z,m)
66
76
  y += d
67
77
  end
68
- y
78
+ neg ? -y : y
69
79
  end
70
80
 
71
81
  # Computes the cosine of x to the specified number of digits of precision.
@@ -77,6 +87,14 @@ module BigMath
77
87
  n = prec + BigDecimal.double_fig
78
88
  one = BigDecimal("1")
79
89
  two = BigDecimal("2")
90
+ x = -x if x < 0
91
+ if x > (twopi = two * BigMath.PI(prec))
92
+ if x > 30
93
+ x %= twopi
94
+ else
95
+ x -= twopi while x > twopi
96
+ end
97
+ end
80
98
  x1 = one
81
99
  x2 = x.mult(x,n)
82
100
  sign = 1
@@ -98,12 +116,16 @@ module BigMath
98
116
 
99
117
  # Computes the arctangent of x to the specified number of digits of precision.
100
118
  #
101
- # If x is infinite or NaN, returns NaN.
102
- # Raises an argument error if x > 1.
119
+ # If x is NaN, returns NaN.
103
120
  def atan(x, prec)
104
121
  raise ArgumentError, "Zero or negative precision for atan" if prec <= 0
105
- return BigDecimal("NaN") if x.infinite? || x.nan?
106
- raise ArgumentError, "x.abs must be less than 1.0" if x.abs>=1
122
+ return BigDecimal("NaN") if x.nan?
123
+ pi = PI(prec)
124
+ x = -x if neg = x < 0
125
+ return pi.div(neg ? -2 : 2, prec) if x.infinite?
126
+ return pi / (neg ? -4 : 4) if x.round(prec) == 1
127
+ x = BigDecimal("1").div(x, prec) if inv = x > 1
128
+ x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5
107
129
  n = prec + BigDecimal.double_fig
108
130
  y = x
109
131
  d = y
@@ -117,63 +139,12 @@ module BigMath
117
139
  y += d
118
140
  r += 2
119
141
  end
142
+ y *= 2 if dbl
143
+ y = pi / 2 - y if inv
144
+ y = -y if neg
120
145
  y
121
146
  end
122
147
 
123
- # Computes the value of e (the base of natural logarithms) raised to the
124
- # power of x, to the specified number of digits of precision.
125
- #
126
- # If x is infinite or NaN, returns NaN.
127
- #
128
- # BigMath::exp(BigDecimal.new('1'), 10).to_s
129
- # -> "0.271828182845904523536028752390026306410273E1"
130
- def exp(x, prec)
131
- raise ArgumentError, "Zero or negative precision for exp" if prec <= 0
132
- return BigDecimal("NaN") if x.infinite? || x.nan?
133
- n = prec + BigDecimal.double_fig
134
- one = BigDecimal("1")
135
- x1 = one
136
- y = one
137
- d = y
138
- z = one
139
- i = 0
140
- while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
141
- m = BigDecimal.double_fig if m < BigDecimal.double_fig
142
- x1 = x1.mult(x,n)
143
- i += 1
144
- z *= i
145
- d = x1.div(z,m)
146
- y += d
147
- end
148
- y
149
- end
150
-
151
- # Computes the natural logarithm of x to the specified number of digits
152
- # of precision.
153
- #
154
- # Returns x if x is infinite or NaN.
155
- #
156
- def log(x, prec)
157
- raise ArgumentError, "Zero or negative argument for log" if x <= 0 || prec <= 0
158
- return x if x.infinite? || x.nan?
159
- one = BigDecimal("1")
160
- two = BigDecimal("2")
161
- n = prec + BigDecimal.double_fig
162
- x = (x - one).div(x + one,n)
163
- x2 = x.mult(x,n)
164
- y = x
165
- d = y
166
- i = one
167
- while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
168
- m = BigDecimal.double_fig if m < BigDecimal.double_fig
169
- x = x2.mult(x,n)
170
- i += two
171
- d = x.div(i,m)
172
- y += d
173
- end
174
- y*two
175
- end
176
-
177
148
  # Computes the value of pi to the specified number of digits of precision.
178
149
  def PI(prec)
179
150
  raise ArgumentError, "Zero or negative argument for PI" if prec <= 0