Ruby  2.1.4p265(2014-10-27revision48166)
bigdecimal.c
Go to the documentation of this file.
1 /*
2  *
3  * Ruby BigDecimal(Variable decimal precision) extension library.
4  *
5  * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
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.
10  *
11  * NOTE: Change log in this source removed to reduce source code size.
12  * See rev. 1.25 if needed.
13  *
14  */
15 
16 /* #define BIGDECIMAL_DEBUG 1 */
17 #ifdef BIGDECIMAL_DEBUG
18 # define BIGDECIMAL_ENABLE_VPRINT 1
19 #endif
20 #include "bigdecimal.h"
21 
22 #ifndef BIGDECIMAL_DEBUG
23 # define NDEBUG
24 #endif
25 #include <assert.h>
26 
27 #include <ctype.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <math.h>
33 #include "math.h"
34 
35 #ifdef HAVE_IEEEFP_H
36 #include <ieeefp.h>
37 #endif
38 
39 /* #define ENABLE_NUMERIC_STRING */
40 
41 #define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
42  (a) == 0 ? 0 : \
43  (a) == -1 ? (b) < -(max) : \
44  (a) > 0 ? \
45  ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
46  ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
47 #define SIGNED_VALUE_MAX INTPTR_MAX
48 #define SIGNED_VALUE_MIN INTPTR_MIN
49 #define MUL_OVERFLOW_SIGNED_VALUE_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, SIGNED_VALUE_MIN, SIGNED_VALUE_MAX)
50 
53 
57 
58 static ID id_up;
59 static ID id_down;
60 static ID id_truncate;
61 static ID id_half_up;
62 static ID id_default;
65 static ID id_banker;
66 static ID id_ceiling;
67 static ID id_ceil;
68 static ID id_floor;
69 static ID id_to_r;
70 static ID id_eq;
71 
72 /* MACRO's to guard objects from GC by keeping them in stack */
73 #define ENTER(n) volatile VALUE RB_UNUSED_VAR(vStack[n]);int iStack=0
74 #define PUSH(x) vStack[iStack++] = (VALUE)(x);
75 #define SAVE(p) PUSH(p->obj);
76 #define GUARD_OBJ(p,y) {p=y;SAVE(p);}
77 
78 #define BASE_FIG RMPD_COMPONENT_FIGURES
79 #define BASE RMPD_BASE
80 
81 #define HALF_BASE (BASE/2)
82 #define BASE1 (BASE/10)
83 
84 #ifndef DBLE_FIG
85 #define DBLE_FIG (DBL_DIG+1) /* figure of double */
86 #endif
87 
88 #ifndef RBIGNUM_ZERO_P
89 # define RBIGNUM_ZERO_P(x) rb_bigzero_p(x)
90 #endif
91 
92 #ifndef RRATIONAL_ZERO_P
93 # define RRATIONAL_ZERO_P(x) (FIXNUM_P(RRATIONAL(x)->num) && \
94  FIX2LONG(RRATIONAL(x)->num) == 0)
95 #endif
96 
97 #ifndef RRATIONAL_NEGATIVE_P
98 # define RRATIONAL_NEGATIVE_P(x) RTEST(rb_funcall((x), '<', 1, INT2FIX(0)))
99 #endif
100 
101 /*
102  * ================== Ruby Interface part ==========================
103  */
104 #define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f)
105 
106 /*
107  * Returns the BigDecimal version number.
108  */
109 static VALUE
111 {
112  /*
113  * 1.0.0: Ruby 1.8.0
114  * 1.0.1: Ruby 1.8.1
115  * 1.1.0: Ruby 1.9.3
116  */
117  return rb_str_new2("1.1.0");
118 }
119 
120 /*
121  * VP routines used in BigDecimal part
122  */
123 static unsigned short VpGetException(void);
124 static void VpSetException(unsigned short f);
125 static void VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v);
126 static int VpLimitRound(Real *c, size_t ixDigit);
127 static Real *VpCopy(Real *pv, Real const* const x);
128 
129 #ifdef BIGDECIMAL_ENABLE_VPRINT
130 static int VPrint(FILE *fp,const char *cntl_chr,Real *a);
131 #endif
132 
133 /*
134  * **** BigDecimal part ****
135  */
136 
137 static void
139 {
140  VpFree(pv);
141 }
142 
143 static size_t
144 BigDecimal_memsize(const void *ptr)
145 {
146  const Real *pv = ptr;
147  return pv ? (sizeof(*pv) + pv->MaxPrec * sizeof(BDIGIT)) : 0;
148 }
149 
151  "BigDecimal",
153 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
155 #endif
156 };
157 
158 static inline int
160 {
161  return rb_typeddata_is_kind_of(v, &BigDecimal_data_type);
162 }
163 
164 static VALUE
166 {
167  if (VpIsNaN(p)) {
168  VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'(Not a Number)", 0);
169  }
170  else if (VpIsPosInf(p)) {
171  VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0);
172  }
173  else if (VpIsNegInf(p)) {
174  VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 0);
175  }
176  return p->obj;
177 }
178 
180 
181 static void
183 {
184  VALUE str;
185 
186  if (rb_special_const_p(v)) {
187  str = rb_inspect(v);
188  }
189  else {
190  str = rb_class_name(rb_obj_class(v));
191  }
192 
193  str = rb_str_cat2(rb_str_dup(str), " can't be coerced into BigDecimal");
194  rb_exc_raise(rb_exc_new3(exc_class, str));
195 }
196 
197 static inline VALUE BigDecimal_div2(VALUE, VALUE, VALUE);
198 
199 static Real*
200 GetVpValueWithPrec(VALUE v, long prec, int must)
201 {
202  Real *pv;
203  VALUE num, bg;
204  char szD[128];
205  VALUE orig = Qundef;
206  double d;
207 
208 again:
209  switch(TYPE(v)) {
210  case T_FLOAT:
211  if (prec < 0) goto unable_to_coerce_without_prec;
212  if (prec > DBL_DIG+1) goto SomeOneMayDoIt;
213  d = RFLOAT_VALUE(v);
214  if (d != 0.0) {
215  v = rb_funcall(v, id_to_r, 0);
216  goto again;
217  }
218  if (1/d < 0.0) {
219  return VpCreateRbObject(prec, "-0");
220  }
221  return VpCreateRbObject(prec, "0");
222 
223  case T_RATIONAL:
224  if (prec < 0) goto unable_to_coerce_without_prec;
225 
226  if (orig == Qundef ? (orig = v, 1) : orig != v) {
227  num = RRATIONAL(v)->num;
228  pv = GetVpValueWithPrec(num, -1, must);
229  if (pv == NULL) goto SomeOneMayDoIt;
230 
231  v = BigDecimal_div2(ToValue(pv), RRATIONAL(v)->den, LONG2NUM(prec));
232  goto again;
233  }
234 
235  v = orig;
236  goto SomeOneMayDoIt;
237 
238  case T_DATA:
239  if (is_kind_of_BigDecimal(v)) {
240  pv = DATA_PTR(v);
241  return pv;
242  }
243  else {
244  goto SomeOneMayDoIt;
245  }
246  break;
247 
248  case T_FIXNUM:
249  sprintf(szD, "%ld", FIX2LONG(v));
250  return VpCreateRbObject(VpBaseFig() * 2 + 1, szD);
251 
252 #ifdef ENABLE_NUMERIC_STRING
253  case T_STRING:
254  SafeStringValue(v);
255  return VpCreateRbObject(strlen(RSTRING_PTR(v)) + VpBaseFig() + 1,
256  RSTRING_PTR(v));
257 #endif /* ENABLE_NUMERIC_STRING */
258 
259  case T_BIGNUM:
260  bg = rb_big2str(v, 10);
261  return VpCreateRbObject(strlen(RSTRING_PTR(bg)) + VpBaseFig() + 1,
262  RSTRING_PTR(bg));
263  default:
264  goto SomeOneMayDoIt;
265  }
266 
267 SomeOneMayDoIt:
268  if (must) {
270  }
271  return NULL; /* NULL means to coerce */
272 
273 unable_to_coerce_without_prec:
274  if (must) {
276  "%s can't be coerced into BigDecimal without a precision",
277  rb_obj_classname(v));
278  }
279  return NULL;
280 }
281 
282 static Real*
283 GetVpValue(VALUE v, int must)
284 {
285  return GetVpValueWithPrec(v, -1, must);
286 }
287 
288 /* call-seq:
289  * BigDecimal.double_fig
290  *
291  * The BigDecimal.double_fig class method returns the number of digits a
292  * Float number is allowed to have. The result depends upon the CPU and OS
293  * in use.
294  */
295 static VALUE
297 {
298  return INT2FIX(VpDblFig());
299 }
300 
301 /* call-seq:
302  * precs
303  *
304  * Returns an Array of two Integer values.
305  *
306  * The first value is the current number of significant digits in the
307  * BigDecimal. The second value is the maximum number of significant digits
308  * for the BigDecimal.
309  */
310 static VALUE
312 {
313  ENTER(1);
314  Real *p;
315  VALUE obj;
316 
317  GUARD_OBJ(p, GetVpValue(self, 1));
318  obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()),
319  INT2NUM(p->MaxPrec*VpBaseFig()));
320  return obj;
321 }
322 
323 /*
324  * call-seq: hash
325  *
326  * Creates a hash for this BigDecimal.
327  *
328  * Two BigDecimals with equal sign,
329  * fractional part and exponent have the same hash.
330  */
331 static VALUE
333 {
334  ENTER(1);
335  Real *p;
337 
338  GUARD_OBJ(p, GetVpValue(self, 1));
339  hash = (st_index_t)p->sign;
340  /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */
341  if(hash == 2 || hash == (st_index_t)-2) {
342  hash ^= rb_memhash(p->frac, sizeof(BDIGIT)*p->Prec);
343  hash += p->exponent;
344  }
345  return INT2FIX(hash);
346 }
347 
348 /*
349  * call-seq: _dump
350  *
351  * Method used to provide marshalling support.
352  *
353  * inf = BigDecimal.new('Infinity')
354  * => #<BigDecimal:1e16fa8,'Infinity',9(9)>
355  * BigDecimal._load(inf._dump)
356  * => #<BigDecimal:1df8dc8,'Infinity',9(9)>
357  *
358  * See the Marshal module.
359  */
360 static VALUE
362 {
363  ENTER(5);
364  Real *vp;
365  char *psz;
366  VALUE dummy;
367  volatile VALUE dump;
368 
369  rb_scan_args(argc, argv, "01", &dummy);
370  GUARD_OBJ(vp,GetVpValue(self, 1));
371  dump = rb_str_new(0, VpNumOfChars(vp, "E")+50);
372  psz = RSTRING_PTR(dump);
373  sprintf(psz, "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig());
374  VpToString(vp, psz+strlen(psz), 0, 0);
375  rb_str_resize(dump, strlen(psz));
376  return dump;
377 }
378 
379 /*
380  * Internal method used to provide marshalling support. See the Marshal module.
381  */
382 static VALUE
384 {
385  ENTER(2);
386  Real *pv;
387  unsigned char *pch;
388  unsigned char ch;
389  unsigned long m=0;
390 
391  SafeStringValue(str);
392  pch = (unsigned char *)RSTRING_PTR(str);
393  /* First get max prec */
394  while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') {
395  if(!ISDIGIT(ch)) {
396  rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string");
397  }
398  m = m*10 + (unsigned long)(ch-'0');
399  }
400  if (m > VpBaseFig()) m -= VpBaseFig();
401  GUARD_OBJ(pv, VpNewRbClass(m, (char *)pch, self));
402  m /= VpBaseFig();
403  if (m && pv->MaxPrec > m) {
404  pv->MaxPrec = m+1;
405  }
406  return ToValue(pv);
407 }
408 
409 static unsigned short
411 {
412  unsigned short sw;
413  ID id;
414  switch (TYPE(v)) {
415  case T_SYMBOL:
416  id = SYM2ID(v);
417  if (id == id_up)
418  return VP_ROUND_UP;
419  if (id == id_down || id == id_truncate)
420  return VP_ROUND_DOWN;
421  if (id == id_half_up || id == id_default)
422  return VP_ROUND_HALF_UP;
423  if (id == id_half_down)
424  return VP_ROUND_HALF_DOWN;
425  if (id == id_half_even || id == id_banker)
426  return VP_ROUND_HALF_EVEN;
427  if (id == id_ceiling || id == id_ceil)
428  return VP_ROUND_CEIL;
429  if (id == id_floor)
430  return VP_ROUND_FLOOR;
431  rb_raise(rb_eArgError, "invalid rounding mode");
432 
433  default:
434  break;
435  }
436 
437  Check_Type(v, T_FIXNUM);
438  sw = (unsigned short)FIX2UINT(v);
439  if (!VpIsRoundMode(sw)) {
440  rb_raise(rb_eArgError, "invalid rounding mode");
441  }
442  return sw;
443 }
444 
445 /* call-seq:
446  * BigDecimal.mode(mode, value)
447  *
448  * Controls handling of arithmetic exceptions and rounding. If no value
449  * is supplied, the current value is returned.
450  *
451  * Six values of the mode parameter control the handling of arithmetic
452  * exceptions:
453  *
454  * BigDecimal::EXCEPTION_NaN
455  * BigDecimal::EXCEPTION_INFINITY
456  * BigDecimal::EXCEPTION_UNDERFLOW
457  * BigDecimal::EXCEPTION_OVERFLOW
458  * BigDecimal::EXCEPTION_ZERODIVIDE
459  * BigDecimal::EXCEPTION_ALL
460  *
461  * For each mode parameter above, if the value set is false, computation
462  * continues after an arithmetic exception of the appropriate type.
463  * When computation continues, results are as follows:
464  *
465  * EXCEPTION_NaN:: NaN
466  * EXCEPTION_INFINITY:: +Infinity or -Infinity
467  * EXCEPTION_UNDERFLOW:: 0
468  * EXCEPTION_OVERFLOW:: +Infinity or -Infinity
469  * EXCEPTION_ZERODIVIDE:: +Infinity or -Infinity
470  *
471  * One value of the mode parameter controls the rounding of numeric values:
472  * BigDecimal::ROUND_MODE. The values it can take are:
473  *
474  * ROUND_UP, :up:: round away from zero
475  * ROUND_DOWN, :down, :truncate:: round towards zero (truncate)
476  * ROUND_HALF_UP, :half_up, :default:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round away from zero. (default)
477  * ROUND_HALF_DOWN, :half_down:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards zero.
478  * ROUND_HALF_EVEN, :half_even, :banker:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards the even neighbor (Banker's rounding)
479  * ROUND_CEILING, :ceiling, :ceil:: round towards positive infinity (ceil)
480  * ROUND_FLOOR, :floor:: round towards negative infinity (floor)
481  *
482  */
483 static VALUE
485 {
486  VALUE which;
487  VALUE val;
488  unsigned long f,fo;
489 
490  rb_scan_args(argc, argv, "11", &which, &val);
491  Check_Type(which, T_FIXNUM);
492  f = (unsigned long)FIX2INT(which);
493 
494  if (f & VP_EXCEPTION_ALL) {
495  /* Exception mode setting */
496  fo = VpGetException();
497  if (val == Qnil) return INT2FIX(fo);
498  if (val != Qfalse && val!=Qtrue) {
499  rb_raise(rb_eArgError, "second argument must be true or false");
500  return Qnil; /* Not reached */
501  }
502  if (f & VP_EXCEPTION_INFINITY) {
503  VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_INFINITY) :
504  (fo & (~VP_EXCEPTION_INFINITY))));
505  }
506  fo = VpGetException();
507  if (f & VP_EXCEPTION_NaN) {
508  VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_NaN) :
509  (fo & (~VP_EXCEPTION_NaN))));
510  }
511  fo = VpGetException();
512  if (f & VP_EXCEPTION_UNDERFLOW) {
513  VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_UNDERFLOW) :
514  (fo & (~VP_EXCEPTION_UNDERFLOW))));
515  }
516  fo = VpGetException();
517  if(f & VP_EXCEPTION_ZERODIVIDE) {
518  VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_ZERODIVIDE) :
519  (fo & (~VP_EXCEPTION_ZERODIVIDE))));
520  }
521  fo = VpGetException();
522  return INT2FIX(fo);
523  }
524  if (VP_ROUND_MODE == f) {
525  /* Rounding mode setting */
526  unsigned short sw;
527  fo = VpGetRoundMode();
528  if (NIL_P(val)) return INT2FIX(fo);
529  sw = check_rounding_mode(val);
530  fo = VpSetRoundMode(sw);
531  return INT2FIX(fo);
532  }
533  rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
534  return Qnil;
535 }
536 
537 static size_t
539 {
540  size_t mxs;
541  size_t mx = a->Prec;
542  SIGNED_VALUE d;
543 
544  if (!VpIsDef(a) || !VpIsDef(b)) return (size_t)-1L;
545  if (mx < b->Prec) mx = b->Prec;
546  if (a->exponent != b->exponent) {
547  mxs = mx;
548  d = a->exponent - b->exponent;
549  if (d < 0) d = -d;
550  mx = mx + (size_t)d;
551  if (mx < mxs) {
552  return VpException(VP_EXCEPTION_INFINITY, "Exponent overflow", 0);
553  }
554  }
555  return mx;
556 }
557 
558 static SIGNED_VALUE
560 {
561  SIGNED_VALUE n;
562  Check_Type(v, T_FIXNUM);
563  n = FIX2INT(v);
564  if (n < 0) {
565  rb_raise(rb_eArgError, "argument must be positive");
566  }
567  return n;
568 }
569 
570 VP_EXPORT Real *
571 VpNewRbClass(size_t mx, const char *str, VALUE klass)
572 {
573  Real *pv = VpAlloc(mx,str);
574  pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv);
575  return pv;
576 }
577 
578 VP_EXPORT Real *
579 VpCreateRbObject(size_t mx, const char *str)
580 {
581  Real *pv = VpAlloc(mx,str);
582  pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
583  return pv;
584 }
585 
586 #define VpAllocReal(prec) (Real *)VpMemAlloc(offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
587 #define VpReallocReal(ptr, prec) (Real *)VpMemRealloc((ptr), offsetof(Real, frac) + (prec) * sizeof(BDIGIT))
588 
589 static Real *
590 VpCopy(Real *pv, Real const* const x)
591 {
592  assert(x != NULL);
593 
594  pv = VpReallocReal(pv, x->MaxPrec);
595  pv->MaxPrec = x->MaxPrec;
596  pv->Prec = x->Prec;
597  pv->exponent = x->exponent;
598  pv->sign = x->sign;
599  pv->flag = x->flag;
600  MEMCPY(pv->frac, x->frac, BDIGIT, pv->MaxPrec);
601 
602  return pv;
603 }
604 
605 /* Returns True if the value is Not a Number */
606 static VALUE
608 {
609  Real *p = GetVpValue(self, 1);
610  if (VpIsNaN(p)) return Qtrue;
611  return Qfalse;
612 }
613 
614 /* Returns nil, -1, or +1 depending on whether the value is finite,
615  * -Infinity, or +Infinity.
616  */
617 static VALUE
619 {
620  Real *p = GetVpValue(self, 1);
621  if (VpIsPosInf(p)) return INT2FIX(1);
622  if (VpIsNegInf(p)) return INT2FIX(-1);
623  return Qnil;
624 }
625 
626 /* Returns True if the value is finite (not NaN or infinite) */
627 static VALUE
629 {
630  Real *p = GetVpValue(self, 1);
631  if (VpIsNaN(p)) return Qfalse;
632  if (VpIsInf(p)) return Qfalse;
633  return Qtrue;
634 }
635 
636 static void
638 {
639  if (VpIsNaN(p)) {
640  VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'(Not a Number)", 1);
641  }
642  else if (VpIsPosInf(p)) {
643  VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 1);
644  }
645  else if (VpIsNegInf(p)) {
646  VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 1);
647  }
648 }
649 
650 static VALUE BigDecimal_split(VALUE self);
651 
652 /* Returns the value as an integer (Fixnum or Bignum).
653  *
654  * If the BigNumber is infinity or NaN, raises FloatDomainError.
655  */
656 static VALUE
658 {
659  ENTER(5);
660  ssize_t e, nf;
661  Real *p;
662 
663  GUARD_OBJ(p, GetVpValue(self, 1));
665 
666  e = VpExponent10(p);
667  if (e <= 0) return INT2FIX(0);
668  nf = VpBaseFig();
669  if (e <= nf) {
670  return LONG2NUM((long)(VpGetSign(p) * (BDIGIT_DBL_SIGNED)p->frac[0]));
671  }
672  else {
673  VALUE a = BigDecimal_split(self);
674  VALUE digits = RARRAY_PTR(a)[1];
675  VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0);
676  VALUE ret;
677  ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits);
678 
679  if (VpGetSign(p) < 0) {
680  numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
681  }
682  if (dpower < 0) {
683  ret = rb_funcall(numerator, rb_intern("div"), 1,
684  rb_funcall(INT2FIX(10), rb_intern("**"), 1,
685  INT2FIX(-dpower)));
686  }
687  else {
688  ret = rb_funcall(numerator, '*', 1,
689  rb_funcall(INT2FIX(10), rb_intern("**"), 1,
690  INT2FIX(dpower)));
691  }
692  if (RB_TYPE_P(ret, T_FLOAT)) {
693  rb_raise(rb_eFloatDomainError, "Infinity");
694  }
695  return ret;
696  }
697 }
698 
699 /* Returns a new Float object having approximately the same value as the
700  * BigDecimal number. Normal accuracy limits and built-in errors of binary
701  * Float arithmetic apply.
702  */
703 static VALUE
705 {
706  ENTER(1);
707  Real *p;
708  double d;
709  SIGNED_VALUE e;
710  char *buf;
711  volatile VALUE str;
712 
713  GUARD_OBJ(p, GetVpValue(self, 1));
714  if (VpVtoD(&d, &e, p) != 1)
715  return rb_float_new(d);
717  goto overflow;
719  goto underflow;
720 
721  str = rb_str_new(0, VpNumOfChars(p, "E"));
722  buf = RSTRING_PTR(str);
723  VpToString(p, buf, 0, 0);
724  errno = 0;
725  d = strtod(buf, 0);
726  if (errno == ERANGE) {
727  if (d == 0.0) goto underflow;
728  if (fabs(d) >= HUGE_VAL) goto overflow;
729  }
730  return rb_float_new(d);
731 
732 overflow:
733  VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0);
734  if (p->sign >= 0)
736  else
738 
739 underflow:
740  VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0);
741  if (p->sign >= 0)
742  return rb_float_new(0.0);
743  else
744  return rb_float_new(-0.0);
745 }
746 
747 
748 /* Converts a BigDecimal to a Rational.
749  */
750 static VALUE
752 {
753  Real *p;
754  ssize_t sign, power, denomi_power;
755  VALUE a, digits, numerator;
756 
757  p = GetVpValue(self, 1);
759 
760  sign = VpGetSign(p);
761  power = VpExponent10(p);
762  a = BigDecimal_split(self);
763  digits = RARRAY_PTR(a)[1];
764  denomi_power = power - RSTRING_LEN(digits);
765  numerator = rb_funcall(digits, rb_intern("to_i"), 0);
766 
767  if (sign < 0) {
768  numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
769  }
770  if (denomi_power < 0) {
771  return rb_Rational(numerator,
772  rb_funcall(INT2FIX(10), rb_intern("**"), 1,
773  INT2FIX(-denomi_power)));
774  }
775  else {
776  return rb_Rational1(rb_funcall(numerator, '*', 1,
777  rb_funcall(INT2FIX(10), rb_intern("**"), 1,
778  INT2FIX(denomi_power))));
779  }
780 }
781 
782 /* The coerce method provides support for Ruby type coercion. It is not
783  * enabled by default.
784  *
785  * This means that binary operations like + * / or - can often be performed
786  * on a BigDecimal and an object of another type, if the other object can
787  * be coerced into a BigDecimal value.
788  *
789  * e.g.
790  * a = BigDecimal.new("1.0")
791  * b = a / 2.0 -> 0.5
792  *
793  * Note that coercing a String to a BigDecimal is not supported by default;
794  * it requires a special compile-time option when building Ruby.
795  */
796 static VALUE
798 {
799  ENTER(2);
800  VALUE obj;
801  Real *b;
802 
803  if (RB_TYPE_P(other, T_FLOAT)) {
804  GUARD_OBJ(b, GetVpValueWithPrec(other, DBL_DIG+1, 1));
805  obj = rb_assoc_new(ToValue(b), self);
806  }
807  else {
808  if (RB_TYPE_P(other, T_RATIONAL)) {
809  Real* pv = DATA_PTR(self);
810  GUARD_OBJ(b, GetVpValueWithPrec(other, pv->Prec*VpBaseFig(), 1));
811  }
812  else {
813  GUARD_OBJ(b, GetVpValue(other, 1));
814  }
815  obj = rb_assoc_new(b->obj, self);
816  }
817 
818  return obj;
819 }
820 
821 /*
822  * call-seq: +@
823  *
824  * Return self.
825  *
826  * e.g.
827  * b = +a # b == a
828  */
829 static VALUE
831 {
832  return self;
833 }
834 
835  /*
836  * Document-method: BigDecimal#add
837  * Document-method: BigDecimal#+
838  *
839  * call-seq:
840  * add(value, digits)
841  *
842  * Add the specified value.
843  *
844  * e.g.
845  * c = a.add(b,n)
846  * c = a + b
847  *
848  * digits:: If specified and less than the number of significant digits of the
849  * result, the result is rounded to that number of digits, according to
850  * BigDecimal.mode.
851  */
852 static VALUE
854 {
855  ENTER(5);
856  Real *c, *a, *b;
857  size_t mx;
858 
859  GUARD_OBJ(a, GetVpValue(self, 1));
860  if (RB_TYPE_P(r, T_FLOAT)) {
861  b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
862  }
863  else if (RB_TYPE_P(r, T_RATIONAL)) {
864  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
865  }
866  else {
867  b = GetVpValue(r, 0);
868  }
869 
870  if (!b) return DoSomeOne(self,r,'+');
871  SAVE(b);
872 
873  if (VpIsNaN(b)) return b->obj;
874  if (VpIsNaN(a)) return a->obj;
875 
876  mx = GetAddSubPrec(a, b);
877  if (mx == (size_t)-1L) {
878  GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
879  VpAddSub(c, a, b, 1);
880  }
881  else {
882  GUARD_OBJ(c, VpCreateRbObject(mx * (VpBaseFig() + 1), "0"));
883  if(!mx) {
884  VpSetInf(c, VpGetSign(a));
885  }
886  else {
887  VpAddSub(c, a, b, 1);
888  }
889  }
890  return ToValue(c);
891 }
892 
893  /* call-seq:
894  * value - digits -> bigdecimal
895  *
896  * Subtract the specified value.
897  *
898  * e.g.
899  * c = a - b
900  *
901  * The precision of the result value depends on the type of +b+.
902  *
903  * If +b+ is a Float, the precision of the result is Float::DIG+1.
904  *
905  * If +b+ is a BigDecimal, the precision of the result is +b+'s precision of
906  * internal representation from platform. So, it's return value is platform
907  * dependent.
908  *
909  */
910 static VALUE
912 {
913  ENTER(5);
914  Real *c, *a, *b;
915  size_t mx;
916 
917  GUARD_OBJ(a, GetVpValue(self,1));
918  if (RB_TYPE_P(r, T_FLOAT)) {
919  b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
920  }
921  else if (RB_TYPE_P(r, T_RATIONAL)) {
922  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
923  }
924  else {
925  b = GetVpValue(r,0);
926  }
927 
928  if (!b) return DoSomeOne(self,r,'-');
929  SAVE(b);
930 
931  if (VpIsNaN(b)) return b->obj;
932  if (VpIsNaN(a)) return a->obj;
933 
934  mx = GetAddSubPrec(a,b);
935  if (mx == (size_t)-1L) {
936  GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
937  VpAddSub(c, a, b, -1);
938  }
939  else {
940  GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
941  if (!mx) {
942  VpSetInf(c,VpGetSign(a));
943  }
944  else {
945  VpAddSub(c, a, b, -1);
946  }
947  }
948  return ToValue(c);
949 }
950 
951 static VALUE
952 BigDecimalCmp(VALUE self, VALUE r,char op)
953 {
954  ENTER(5);
955  SIGNED_VALUE e;
956  Real *a, *b=0;
957  GUARD_OBJ(a, GetVpValue(self, 1));
958  switch (TYPE(r)) {
959  case T_DATA:
960  if (!is_kind_of_BigDecimal(r)) break;
961  /* fall through */
962  case T_FIXNUM:
963  /* fall through */
964  case T_BIGNUM:
965  GUARD_OBJ(b, GetVpValue(r, 0));
966  break;
967 
968  case T_FLOAT:
969  GUARD_OBJ(b, GetVpValueWithPrec(r, DBL_DIG+1, 0));
970  break;
971 
972  case T_RATIONAL:
973  GUARD_OBJ(b, GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 0));
974  break;
975 
976  default:
977  break;
978  }
979  if (b == NULL) {
980  ID f = 0;
981 
982  switch (op) {
983  case '*':
984  return rb_num_coerce_cmp(self, r, rb_intern("<=>"));
985 
986  case '=':
987  return RTEST(rb_num_coerce_cmp(self, r, rb_intern("=="))) ? Qtrue : Qfalse;
988 
989  case 'G':
990  f = rb_intern(">=");
991  break;
992 
993  case 'L':
994  f = rb_intern("<=");
995  break;
996 
997  case '>':
998  /* fall through */
999  case '<':
1000  f = (ID)op;
1001  break;
1002 
1003  default:
1004  break;
1005  }
1006  return rb_num_coerce_relop(self, r, f);
1007  }
1008  SAVE(b);
1009  e = VpComp(a, b);
1010  if (e == 999)
1011  return (op == '*') ? Qnil : Qfalse;
1012  switch (op) {
1013  case '*':
1014  return INT2FIX(e); /* any op */
1015 
1016  case '=':
1017  if (e == 0) return Qtrue;
1018  return Qfalse;
1019 
1020  case 'G':
1021  if (e >= 0) return Qtrue;
1022  return Qfalse;
1023 
1024  case '>':
1025  if (e > 0) return Qtrue;
1026  return Qfalse;
1027 
1028  case 'L':
1029  if (e <= 0) return Qtrue;
1030  return Qfalse;
1031 
1032  case '<':
1033  if (e < 0) return Qtrue;
1034  return Qfalse;
1035 
1036  default:
1037  break;
1038  }
1039 
1040  rb_bug("Undefined operation in BigDecimalCmp()");
1041 
1042  UNREACHABLE;
1043 }
1044 
1045 /* Returns True if the value is zero. */
1046 static VALUE
1048 {
1049  Real *a = GetVpValue(self, 1);
1050  return VpIsZero(a) ? Qtrue : Qfalse;
1051 }
1052 
1053 /* Returns self if the value is non-zero, nil otherwise. */
1054 static VALUE
1056 {
1057  Real *a = GetVpValue(self, 1);
1058  return VpIsZero(a) ? Qnil : self;
1059 }
1060 
1061 /* The comparison operator.
1062  * a <=> b is 0 if a == b, 1 if a > b, -1 if a < b.
1063  */
1064 static VALUE
1066 {
1067  return BigDecimalCmp(self, r, '*');
1068 }
1069 
1070 /*
1071  * Tests for value equality; returns true if the values are equal.
1072  *
1073  * The == and === operators and the eql? method have the same implementation
1074  * for BigDecimal.
1075  *
1076  * Values may be coerced to perform the comparison:
1077  *
1078  * BigDecimal.new('1.0') == 1.0 -> true
1079  */
1080 static VALUE
1082 {
1083  return BigDecimalCmp(self, r, '=');
1084 }
1085 
1086 /* call-seq:
1087  * a < b
1088  *
1089  * Returns true if a is less than b.
1090  *
1091  * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce).
1092  */
1093 static VALUE
1095 {
1096  return BigDecimalCmp(self, r, '<');
1097 }
1098 
1099 /* call-seq:
1100  * a <= b
1101  *
1102  * Returns true if a is less than or equal to b.
1103  *
1104  * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce).
1105  */
1106 static VALUE
1108 {
1109  return BigDecimalCmp(self, r, 'L');
1110 }
1111 
1112 /* call-seq:
1113  * a > b
1114  *
1115  * Returns true if a is greater than b.
1116  *
1117  * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce).
1118  */
1119 static VALUE
1121 {
1122  return BigDecimalCmp(self, r, '>');
1123 }
1124 
1125 /* call-seq:
1126  * a >= b
1127  *
1128  * Returns true if a is greater than or equal to b.
1129  *
1130  * Values may be coerced to perform the comparison (see ==, BigDecimal#coerce)
1131  */
1132 static VALUE
1134 {
1135  return BigDecimalCmp(self, r, 'G');
1136 }
1137 
1138 /*
1139  * call-seq: -@
1140  *
1141  * Return the negation of self.
1142  *
1143  * e.g.
1144  * b = -a
1145  * b == a * -1
1146  */
1147 static VALUE
1149 {
1150  ENTER(5);
1151  Real *c, *a;
1152  GUARD_OBJ(a, GetVpValue(self, 1));
1153  GUARD_OBJ(c, VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0"));
1154  VpAsgn(c, a, -1);
1155  return ToValue(c);
1156 }
1157 
1158  /*
1159  * Document-method: BigDecimal#mult
1160  *
1161  * call-seq: mult(value, digits)
1162  *
1163  * Multiply by the specified value.
1164  *
1165  * e.g.
1166  * c = a.mult(b,n)
1167  * c = a * b
1168  *
1169  * digits:: If specified and less than the number of significant digits of the
1170  * result, the result is rounded to that number of digits, according to
1171  * BigDecimal.mode.
1172  */
1173 static VALUE
1175 {
1176  ENTER(5);
1177  Real *c, *a, *b;
1178  size_t mx;
1179 
1180  GUARD_OBJ(a, GetVpValue(self, 1));
1181  if (RB_TYPE_P(r, T_FLOAT)) {
1182  b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1183  }
1184  else if (RB_TYPE_P(r, T_RATIONAL)) {
1185  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
1186  }
1187  else {
1188  b = GetVpValue(r,0);
1189  }
1190 
1191  if (!b) return DoSomeOne(self, r, '*');
1192  SAVE(b);
1193 
1194  mx = a->Prec + b->Prec;
1195  GUARD_OBJ(c, VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
1196  VpMult(c, a, b);
1197  return ToValue(c);
1198 }
1199 
1200 static VALUE
1201 BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
1202 /* For c = self.div(r): with round operation */
1203 {
1204  ENTER(5);
1205  Real *a, *b;
1206  size_t mx;
1207 
1208  GUARD_OBJ(a, GetVpValue(self, 1));
1209  if (RB_TYPE_P(r, T_FLOAT)) {
1210  b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1211  }
1212  else if (RB_TYPE_P(r, T_RATIONAL)) {
1213  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
1214  }
1215  else {
1216  b = GetVpValue(r, 0);
1217  }
1218 
1219  if (!b) return DoSomeOne(self, r, '/');
1220  SAVE(b);
1221 
1222  *div = b;
1223  mx = a->Prec + vabs(a->exponent);
1224  if (mx < b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent);
1225  mx++; /* NOTE: An additional digit is needed for the compatibility to
1226  the version 1.2.1 and the former. */
1227  mx = (mx + 1) * VpBaseFig();
1228  GUARD_OBJ((*c), VpCreateRbObject(mx, "#0"));
1229  GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
1230  VpDivd(*c, *res, a, b);
1231  return Qnil;
1232 }
1233 
1234  /* call-seq:
1235  * div(value, digits)
1236  * quo(value)
1237  *
1238  * Divide by the specified value.
1239  *
1240  * e.g.
1241  * c = a.div(b,n)
1242  *
1243  * digits:: If specified and less than the number of significant digits of the
1244  * result, the result is rounded to that number of digits, according to
1245  * BigDecimal.mode.
1246  *
1247  * If digits is 0, the result is the same as the / operator. If not, the
1248  * result is an integer BigDecimal, by analogy with Float#div.
1249  *
1250  * The alias quo is provided since <code>div(value, 0)</code> is the same as
1251  * computing the quotient; see BigDecimal#divmod.
1252  */
1253 static VALUE
1255 /* For c = self/r: with round operation */
1256 {
1257  ENTER(5);
1258  Real *c=NULL, *res=NULL, *div = NULL;
1259  r = BigDecimal_divide(&c, &res, &div, self, r);
1260  if (!NIL_P(r)) return r; /* coerced by other */
1261  SAVE(c); SAVE(res); SAVE(div);
1262  /* a/b = c + r/b */
1263  /* c xxxxx
1264  r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
1265  */
1266  /* Round */
1267  if (VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
1268  VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal() * (BDIGIT_DBL)res->frac[0] / div->frac[0]));
1269  }
1270  return ToValue(c);
1271 }
1272 
1273 /*
1274  * %: mod = a%b = a - (a.to_f/b).floor * b
1275  * div = (a.to_f/b).floor
1276  */
1277 static VALUE
1279 {
1280  ENTER(8);
1281  Real *c=NULL, *d=NULL, *res=NULL;
1282  Real *a, *b;
1283  size_t mx;
1284 
1285  GUARD_OBJ(a, GetVpValue(self, 1));
1286  if (RB_TYPE_P(r, T_FLOAT)) {
1287  b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1288  }
1289  else if (RB_TYPE_P(r, T_RATIONAL)) {
1290  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
1291  }
1292  else {
1293  b = GetVpValue(r, 0);
1294  }
1295 
1296  if (!b) return Qfalse;
1297  SAVE(b);
1298 
1299  if (VpIsNaN(a) || VpIsNaN(b)) goto NaN;
1300  if (VpIsInf(a) && VpIsInf(b)) goto NaN;
1301  if (VpIsZero(b)) {
1302  rb_raise(rb_eZeroDivError, "divided by 0");
1303  }
1304  if (VpIsInf(a)) {
1305  GUARD_OBJ(d, VpCreateRbObject(1, "0"));
1306  VpSetInf(d, (SIGNED_VALUE)(VpGetSign(a) == VpGetSign(b) ? 1 : -1));
1307  GUARD_OBJ(c, VpCreateRbObject(1, "NaN"));
1308  *div = d;
1309  *mod = c;
1310  return Qtrue;
1311  }
1312  if (VpIsInf(b)) {
1313  GUARD_OBJ(d, VpCreateRbObject(1, "0"));
1314  *div = d;
1315  *mod = a;
1316  return Qtrue;
1317  }
1318  if (VpIsZero(a)) {
1319  GUARD_OBJ(c, VpCreateRbObject(1, "0"));
1320  GUARD_OBJ(d, VpCreateRbObject(1, "0"));
1321  *div = d;
1322  *mod = c;
1323  return Qtrue;
1324  }
1325 
1326  mx = a->Prec + vabs(a->exponent);
1327  if (mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent);
1328  mx = (mx + 1) * VpBaseFig();
1329  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1330  GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
1331  VpDivd(c, res, a, b);
1332  mx = c->Prec * (VpBaseFig() + 1);
1333  GUARD_OBJ(d, VpCreateRbObject(mx, "0"));
1334  VpActiveRound(d, c, VP_ROUND_DOWN, 0);
1335  VpMult(res, d, b);
1336  VpAddSub(c, a, res, -1);
1337  if (!VpIsZero(c) && (VpGetSign(a) * VpGetSign(b) < 0)) {
1338  VpAddSub(res, d, VpOne(), -1);
1339  GUARD_OBJ(d, VpCreateRbObject(GetAddSubPrec(c, b)*(VpBaseFig() + 1), "0"));
1340  VpAddSub(d, c, b, 1);
1341  *div = res;
1342  *mod = d;
1343  } else {
1344  *div = d;
1345  *mod = c;
1346  }
1347  return Qtrue;
1348 
1349 NaN:
1350  GUARD_OBJ(c, VpCreateRbObject(1, "NaN"));
1351  GUARD_OBJ(d, VpCreateRbObject(1, "NaN"));
1352  *div = d;
1353  *mod = c;
1354  return Qtrue;
1355 }
1356 
1357 /* call-seq:
1358  * a % b
1359  * a.modulo(b)
1360  *
1361  * Returns the modulus from dividing by b.
1362  *
1363  * See BigDecimal#divmod.
1364  */
1365 static VALUE
1366 BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */
1367 {
1368  ENTER(3);
1369  Real *div = NULL, *mod = NULL;
1370 
1371  if (BigDecimal_DoDivmod(self, r, &div, &mod)) {
1372  SAVE(div); SAVE(mod);
1373  return ToValue(mod);
1374  }
1375  return DoSomeOne(self, r, '%');
1376 }
1377 
1378 static VALUE
1380 {
1381  ENTER(10);
1382  size_t mx;
1383  Real *a = NULL, *b = NULL, *c = NULL, *res = NULL, *d = NULL, *rr = NULL, *ff = NULL;
1384  Real *f = NULL;
1385 
1386  GUARD_OBJ(a, GetVpValue(self, 1));
1387  if (RB_TYPE_P(r, T_FLOAT)) {
1388  b = GetVpValueWithPrec(r, DBL_DIG+1, 1);
1389  }
1390  else if (RB_TYPE_P(r, T_RATIONAL)) {
1391  b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1);
1392  }
1393  else {
1394  b = GetVpValue(r, 0);
1395  }
1396 
1397  if (!b) return DoSomeOne(self, r, rb_intern("remainder"));
1398  SAVE(b);
1399 
1400  mx = (a->MaxPrec + b->MaxPrec) *VpBaseFig();
1401  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1402  GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0"));
1403  GUARD_OBJ(rr, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0"));
1404  GUARD_OBJ(ff, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0"));
1405 
1406  VpDivd(c, res, a, b);
1407 
1408  mx = c->Prec *(VpBaseFig() + 1);
1409 
1410  GUARD_OBJ(d, VpCreateRbObject(mx, "0"));
1411  GUARD_OBJ(f, VpCreateRbObject(mx, "0"));
1412 
1413  VpActiveRound(d, c, VP_ROUND_DOWN, 0); /* 0: round off */
1414 
1415  VpFrac(f, c);
1416  VpMult(rr, f, b);
1417  VpAddSub(ff, res, rr, 1);
1418 
1419  *dv = d;
1420  *rv = ff;
1421  return Qnil;
1422 }
1423 
1424 /* Returns the remainder from dividing by the value.
1425  *
1426  * x.remainder(y) means x-y*(x/y).truncate
1427  */
1428 static VALUE
1429 BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
1430 {
1431  VALUE f;
1432  Real *d, *rv = 0;
1433  f = BigDecimal_divremain(self, r, &d, &rv);
1434  if (!NIL_P(f)) return f;
1435  return ToValue(rv);
1436 }
1437 
1438 /* Divides by the specified value, and returns the quotient and modulus
1439  * as BigDecimal numbers. The quotient is rounded towards negative infinity.
1440  *
1441  * For example:
1442  *
1443  * require 'bigdecimal'
1444  *
1445  * a = BigDecimal.new("42")
1446  * b = BigDecimal.new("9")
1447  *
1448  * q,m = a.divmod(b)
1449  *
1450  * c = q * b + m
1451  *
1452  * a == c -> true
1453  *
1454  * The quotient q is (a/b).floor, and the modulus is the amount that must be
1455  * added to q * b to get a.
1456  */
1457 static VALUE
1459 {
1460  ENTER(5);
1461  Real *div = NULL, *mod = NULL;
1462 
1463  if (BigDecimal_DoDivmod(self, r, &div, &mod)) {
1464  SAVE(div); SAVE(mod);
1465  return rb_assoc_new(ToValue(div), ToValue(mod));
1466  }
1467  return DoSomeOne(self,r,rb_intern("divmod"));
1468 }
1469 
1470 /*
1471  * See BigDecimal#quo
1472  */
1473 static inline VALUE
1475 {
1476  ENTER(5);
1477  SIGNED_VALUE ix;
1478 
1479  if (NIL_P(n)) { /* div in Float sense */
1480  Real *div = NULL;
1481  Real *mod;
1482  if (BigDecimal_DoDivmod(self, b, &div, &mod)) {
1483  return BigDecimal_to_i(ToValue(div));
1484  }
1485  return DoSomeOne(self, b, rb_intern("div"));
1486  }
1487 
1488  /* div in BigDecimal sense */
1489  ix = GetPositiveInt(n);
1490  if (ix == 0) {
1491  return BigDecimal_div(self, b);
1492  }
1493  else {
1494  Real *res = NULL;
1495  Real *av = NULL, *bv = NULL, *cv = NULL;
1496  size_t mx = ix + VpBaseFig()*2;
1497  size_t pl = VpSetPrecLimit(0);
1498 
1499  GUARD_OBJ(cv, VpCreateRbObject(mx, "0"));
1500  GUARD_OBJ(av, GetVpValue(self, 1));
1501  GUARD_OBJ(bv, GetVpValue(b, 1));
1502  mx = av->Prec + bv->Prec + 2;
1503  if (mx <= cv->MaxPrec) mx = cv->MaxPrec + 1;
1504  GUARD_OBJ(res, VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0"));
1505  VpDivd(cv, res, av, bv);
1506  VpSetPrecLimit(pl);
1507  VpLeftRound(cv, VpGetRoundMode(), ix);
1508  return ToValue(cv);
1509  }
1510 }
1511 
1512 static VALUE
1514 {
1515  VALUE b,n;
1516 
1517  rb_scan_args(argc, argv, "11", &b, &n);
1518 
1519  return BigDecimal_div2(self, b, n);
1520 }
1521 
1522 static VALUE
1524 {
1525  ENTER(2);
1526  Real *cv;
1527  SIGNED_VALUE mx = GetPositiveInt(n);
1528  if (mx == 0) return BigDecimal_add(self, b);
1529  else {
1530  size_t pl = VpSetPrecLimit(0);
1531  VALUE c = BigDecimal_add(self, b);
1532  VpSetPrecLimit(pl);
1533  GUARD_OBJ(cv, GetVpValue(c, 1));
1534  VpLeftRound(cv, VpGetRoundMode(), mx);
1535  return ToValue(cv);
1536  }
1537 }
1538 
1539 /*
1540  * sub(value, digits) -> bigdecimal
1541  *
1542  * Subtract the specified value.
1543  *
1544  * e.g.
1545  * c = a.sub(b,n)
1546  *
1547  * digits:: If specified and less than the number of significant digits of the
1548  * result, the result is rounded to that number of digits, according to
1549  * BigDecimal.mode.
1550  *
1551  */
1552 static VALUE
1554 {
1555  ENTER(2);
1556  Real *cv;
1557  SIGNED_VALUE mx = GetPositiveInt(n);
1558  if (mx == 0) return BigDecimal_sub(self, b);
1559  else {
1560  size_t pl = VpSetPrecLimit(0);
1561  VALUE c = BigDecimal_sub(self, b);
1562  VpSetPrecLimit(pl);
1563  GUARD_OBJ(cv, GetVpValue(c, 1));
1564  VpLeftRound(cv, VpGetRoundMode(), mx);
1565  return ToValue(cv);
1566  }
1567 }
1568 
1569 
1570 static VALUE
1572 {
1573  ENTER(2);
1574  Real *cv;
1575  SIGNED_VALUE mx = GetPositiveInt(n);
1576  if (mx == 0) return BigDecimal_mult(self, b);
1577  else {
1578  size_t pl = VpSetPrecLimit(0);
1579  VALUE c = BigDecimal_mult(self, b);
1580  VpSetPrecLimit(pl);
1581  GUARD_OBJ(cv, GetVpValue(c, 1));
1582  VpLeftRound(cv, VpGetRoundMode(), mx);
1583  return ToValue(cv);
1584  }
1585 }
1586 
1587 /* Returns the absolute value.
1588  *
1589  * BigDecimal('5').abs -> 5
1590  *
1591  * BigDecimal('-3').abs -> 3
1592  */
1593 static VALUE
1595 {
1596  ENTER(5);
1597  Real *c, *a;
1598  size_t mx;
1599 
1600  GUARD_OBJ(a, GetVpValue(self, 1));
1601  mx = a->Prec *(VpBaseFig() + 1);
1602  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1603  VpAsgn(c, a, 1);
1604  VpChangeSign(c, 1);
1605  return ToValue(c);
1606 }
1607 
1608 /* call-seq:
1609  * sqrt(n)
1610  *
1611  * Returns the square root of the value.
1612  *
1613  * Result has at least n significant digits.
1614  */
1615 static VALUE
1617 {
1618  ENTER(5);
1619  Real *c, *a;
1620  size_t mx, n;
1621 
1622  GUARD_OBJ(a, GetVpValue(self, 1));
1623  mx = a->Prec * (VpBaseFig() + 1);
1624 
1625  n = GetPositiveInt(nFig) + VpDblFig() + BASE_FIG;
1626  if (mx <= n) mx = n;
1627  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1628  VpSqrt(c, a);
1629  return ToValue(c);
1630 }
1631 
1632 /* Return the integer part of the number.
1633  */
1634 static VALUE
1636 {
1637  ENTER(5);
1638  Real *c, *a;
1639  size_t mx;
1640 
1641  GUARD_OBJ(a, GetVpValue(self, 1));
1642  mx = a->Prec *(VpBaseFig() + 1);
1643  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1644  VpActiveRound(c, a, VP_ROUND_DOWN, 0); /* 0: round off */
1645  return ToValue(c);
1646 }
1647 
1648 /* call-seq:
1649  * round(n, mode)
1650  *
1651  * Round to the nearest 1 (by default), returning the result as a BigDecimal.
1652  *
1653  * BigDecimal('3.14159').round #=> 3
1654  * BigDecimal('8.7').round #=> 9
1655  *
1656  * If n is specified and positive, the fractional part of the result has no
1657  * more than that many digits.
1658  *
1659  * If n is specified and negative, at least that many digits to the left of the
1660  * decimal point will be 0 in the result.
1661  *
1662  * BigDecimal('3.14159').round(3) #=> 3.142
1663  * BigDecimal('13345.234').round(-2) #=> 13300.0
1664  *
1665  * The value of the optional mode argument can be used to determine how
1666  * rounding is performed; see BigDecimal.mode.
1667  */
1668 static VALUE
1670 {
1671  ENTER(5);
1672  Real *c, *a;
1673  int iLoc = 0;
1674  VALUE vLoc;
1675  VALUE vRound;
1676  size_t mx, pl;
1677 
1678  unsigned short sw = VpGetRoundMode();
1679 
1680  switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) {
1681  case 0:
1682  iLoc = 0;
1683  break;
1684  case 1:
1685  Check_Type(vLoc, T_FIXNUM);
1686  iLoc = FIX2INT(vLoc);
1687  break;
1688  case 2:
1689  Check_Type(vLoc, T_FIXNUM);
1690  iLoc = FIX2INT(vLoc);
1691  sw = check_rounding_mode(vRound);
1692  break;
1693  default:
1694  break;
1695  }
1696 
1697  pl = VpSetPrecLimit(0);
1698  GUARD_OBJ(a, GetVpValue(self, 1));
1699  mx = a->Prec * (VpBaseFig() + 1);
1700  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1701  VpSetPrecLimit(pl);
1702  VpActiveRound(c, a, sw, iLoc);
1703  if (argc == 0) {
1704  return BigDecimal_to_i(ToValue(c));
1705  }
1706  return ToValue(c);
1707 }
1708 
1709 /* call-seq:
1710  * truncate(n)
1711  *
1712  * Truncate to the nearest 1, returning the result as a BigDecimal.
1713  *
1714  * BigDecimal('3.14159').truncate #=> 3
1715  * BigDecimal('8.7').truncate #=> 8
1716  *
1717  * If n is specified and positive, the fractional part of the result has no
1718  * more than that many digits.
1719  *
1720  * If n is specified and negative, at least that many digits to the left of the
1721  * decimal point will be 0 in the result.
1722  *
1723  * BigDecimal('3.14159').truncate(3) #=> 3.141
1724  * BigDecimal('13345.234').truncate(-2) #=> 13300.0
1725  */
1726 static VALUE
1728 {
1729  ENTER(5);
1730  Real *c, *a;
1731  int iLoc;
1732  VALUE vLoc;
1733  size_t mx, pl = VpSetPrecLimit(0);
1734 
1735  if (rb_scan_args(argc, argv, "01", &vLoc) == 0) {
1736  iLoc = 0;
1737  }
1738  else {
1739  Check_Type(vLoc, T_FIXNUM);
1740  iLoc = FIX2INT(vLoc);
1741  }
1742 
1743  GUARD_OBJ(a, GetVpValue(self, 1));
1744  mx = a->Prec * (VpBaseFig() + 1);
1745  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1746  VpSetPrecLimit(pl);
1747  VpActiveRound(c, a, VP_ROUND_DOWN, iLoc); /* 0: truncate */
1748  if (argc == 0) {
1749  return BigDecimal_to_i(ToValue(c));
1750  }
1751  return ToValue(c);
1752 }
1753 
1754 /* Return the fractional part of the number.
1755  */
1756 static VALUE
1758 {
1759  ENTER(5);
1760  Real *c, *a;
1761  size_t mx;
1762 
1763  GUARD_OBJ(a, GetVpValue(self, 1));
1764  mx = a->Prec * (VpBaseFig() + 1);
1765  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1766  VpFrac(c, a);
1767  return ToValue(c);
1768 }
1769 
1770 /* call-seq:
1771  * floor(n)
1772  *
1773  * Return the largest integer less than or equal to the value, as a BigDecimal.
1774  *
1775  * BigDecimal('3.14159').floor #=> 3
1776  * BigDecimal('-9.1').floor #=> -10
1777  *
1778  * If n is specified and positive, the fractional part of the result has no
1779  * more than that many digits.
1780  *
1781  * If n is specified and negative, at least that
1782  * many digits to the left of the decimal point will be 0 in the result.
1783  *
1784  * BigDecimal('3.14159').floor(3) #=> 3.141
1785  * BigDecimal('13345.234').floor(-2) #=> 13300.0
1786  */
1787 static VALUE
1789 {
1790  ENTER(5);
1791  Real *c, *a;
1792  int iLoc;
1793  VALUE vLoc;
1794  size_t mx, pl = VpSetPrecLimit(0);
1795 
1796  if (rb_scan_args(argc, argv, "01", &vLoc)==0) {
1797  iLoc = 0;
1798  }
1799  else {
1800  Check_Type(vLoc, T_FIXNUM);
1801  iLoc = FIX2INT(vLoc);
1802  }
1803 
1804  GUARD_OBJ(a, GetVpValue(self, 1));
1805  mx = a->Prec * (VpBaseFig() + 1);
1806  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1807  VpSetPrecLimit(pl);
1808  VpActiveRound(c, a, VP_ROUND_FLOOR, iLoc);
1809 #ifdef BIGDECIMAL_DEBUG
1810  VPrint(stderr, "floor: c=%\n", c);
1811 #endif
1812  if (argc == 0) {
1813  return BigDecimal_to_i(ToValue(c));
1814  }
1815  return ToValue(c);
1816 }
1817 
1818 /* call-seq:
1819  * ceil(n)
1820  *
1821  * Return the smallest integer greater than or equal to the value, as a BigDecimal.
1822  *
1823  * BigDecimal('3.14159').ceil #=> 4
1824  * BigDecimal('-9.1').ceil #=> -9
1825  *
1826  * If n is specified and positive, the fractional part of the result has no
1827  * more than that many digits.
1828  *
1829  * If n is specified and negative, at least that
1830  * many digits to the left of the decimal point will be 0 in the result.
1831  *
1832  * BigDecimal('3.14159').ceil(3) #=> 3.142
1833  * BigDecimal('13345.234').ceil(-2) #=> 13400.0
1834  */
1835 static VALUE
1837 {
1838  ENTER(5);
1839  Real *c, *a;
1840  int iLoc;
1841  VALUE vLoc;
1842  size_t mx, pl = VpSetPrecLimit(0);
1843 
1844  if (rb_scan_args(argc, argv, "01", &vLoc) == 0) {
1845  iLoc = 0;
1846  } else {
1847  Check_Type(vLoc, T_FIXNUM);
1848  iLoc = FIX2INT(vLoc);
1849  }
1850 
1851  GUARD_OBJ(a, GetVpValue(self, 1));
1852  mx = a->Prec * (VpBaseFig() + 1);
1853  GUARD_OBJ(c, VpCreateRbObject(mx, "0"));
1854  VpSetPrecLimit(pl);
1855  VpActiveRound(c, a, VP_ROUND_CEIL, iLoc);
1856  if (argc == 0) {
1857  return BigDecimal_to_i(ToValue(c));
1858  }
1859  return ToValue(c);
1860 }
1861 
1862 /* call-seq:
1863  * to_s(s)
1864  *
1865  * Converts the value to a string.
1866  *
1867  * The default format looks like 0.xxxxEnn.
1868  *
1869  * The optional parameter s consists of either an integer; or an optional '+'
1870  * or ' ', followed by an optional number, followed by an optional 'E' or 'F'.
1871  *
1872  * If there is a '+' at the start of s, positive values are returned with
1873  * a leading '+'.
1874  *
1875  * A space at the start of s returns positive values with a leading space.
1876  *
1877  * If s contains a number, a space is inserted after each group of that many
1878  * fractional digits.
1879  *
1880  * If s ends with an 'E', engineering notation (0.xxxxEnn) is used.
1881  *
1882  * If s ends with an 'F', conventional floating point notation is used.
1883  *
1884  * Examples:
1885  *
1886  * BigDecimal.new('-123.45678901234567890').to_s('5F')
1887  * #=> '-123.45678 90123 45678 9'
1888  *
1889  * BigDecimal.new('123.45678901234567890').to_s('+8F')
1890  * #=> '+123.45678901 23456789'
1891  *
1892  * BigDecimal.new('123.45678901234567890').to_s(' F')
1893  * #=> ' 123.4567890123456789'
1894  */
1895 static VALUE
1897 {
1898  ENTER(5);
1899  int fmt = 0; /* 0:E format */
1900  int fPlus = 0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */
1901  Real *vp;
1902  volatile VALUE str;
1903  char *psz;
1904  char ch;
1905  size_t nc, mc = 0;
1906  VALUE f;
1907 
1908  GUARD_OBJ(vp, GetVpValue(self, 1));
1909 
1910  if (rb_scan_args(argc, argv, "01", &f) == 1) {
1911  if (RB_TYPE_P(f, T_STRING)) {
1912  SafeStringValue(f);
1913  psz = RSTRING_PTR(f);
1914  if (*psz == ' ') {
1915  fPlus = 1;
1916  psz++;
1917  }
1918  else if (*psz == '+') {
1919  fPlus = 2;
1920  psz++;
1921  }
1922  while ((ch = *psz++) != 0) {
1923  if (ISSPACE(ch)) {
1924  continue;
1925  }
1926  if (!ISDIGIT(ch)) {
1927  if (ch == 'F' || ch == 'f') {
1928  fmt = 1; /* F format */
1929  }
1930  break;
1931  }
1932  mc = mc*10 + ch - '0';
1933  }
1934  }
1935  else {
1936  mc = (size_t)GetPositiveInt(f);
1937  }
1938  }
1939  if (fmt) {
1940  nc = VpNumOfChars(vp, "F");
1941  }
1942  else {
1943  nc = VpNumOfChars(vp, "E");
1944  }
1945  if (mc > 0) {
1946  nc += (nc + mc - 1) / mc + 1;
1947  }
1948 
1949  str = rb_str_new(0, nc);
1950  psz = RSTRING_PTR(str);
1951 
1952  if (fmt) {
1953  VpToFString(vp, psz, mc, fPlus);
1954  }
1955  else {
1956  VpToString (vp, psz, mc, fPlus);
1957  }
1958  rb_str_resize(str, strlen(psz));
1959  return str;
1960 }
1961 
1962 /* Splits a BigDecimal number into four parts, returned as an array of values.
1963  *
1964  * The first value represents the sign of the BigDecimal, and is -1 or 1, or 0
1965  * if the BigDecimal is Not a Number.
1966  *
1967  * The second value is a string representing the significant digits of the
1968  * BigDecimal, with no leading zeros.
1969  *
1970  * The third value is the base used for arithmetic (currently always 10) as an
1971  * Integer.
1972  *
1973  * The fourth value is an Integer exponent.
1974  *
1975  * If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the
1976  * string of significant digits with no leading zeros, and n is the exponent.
1977  *
1978  * From these values, you can translate a BigDecimal to a float as follows:
1979  *
1980  * sign, significant_digits, base, exponent = a.split
1981  * f = sign * "0.#{significant_digits}".to_f * (base ** exponent)
1982  *
1983  * (Note that the to_f method is provided as a more convenient way to translate
1984  * a BigDecimal to a Float.)
1985  */
1986 static VALUE
1988 {
1989  ENTER(5);
1990  Real *vp;
1991  VALUE obj,str;
1992  ssize_t e, s;
1993  char *psz1;
1994 
1995  GUARD_OBJ(vp, GetVpValue(self, 1));
1996  str = rb_str_new(0, VpNumOfChars(vp, "E"));
1997  psz1 = RSTRING_PTR(str);
1998  VpSzMantissa(vp, psz1);
1999  s = 1;
2000  if(psz1[0] == '-') {
2001  size_t len = strlen(psz1 + 1);
2002 
2003  memmove(psz1, psz1 + 1, len);
2004  psz1[len] = '\0';
2005  s = -1;
2006  }
2007  if (psz1[0] == 'N') s = 0; /* NaN */
2008  e = VpExponent10(vp);
2009  obj = rb_ary_new2(4);
2010  rb_ary_push(obj, INT2FIX(s));
2011  rb_ary_push(obj, str);
2012  rb_str_resize(str, strlen(psz1));
2013  rb_ary_push(obj, INT2FIX(10));
2014  rb_ary_push(obj, INT2NUM(e));
2015  return obj;
2016 }
2017 
2018 /* Returns the exponent of the BigDecimal number, as an Integer.
2019  *
2020  * If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string
2021  * of digits with no leading zeros, then n is the exponent.
2022  */
2023 static VALUE
2025 {
2026  ssize_t e = VpExponent10(GetVpValue(self, 1));
2027  return INT2NUM(e);
2028 }
2029 
2030 /* Returns debugging information about the value as a string of comma-separated
2031  * values in angle brackets with a leading #:
2032  *
2033  * BigDecimal.new("1234.5678").inspect ->
2034  * "#<BigDecimal:b7ea1130,'0.12345678E4',8(12)>"
2035  *
2036  * The first part is the address, the second is the value as a string, and
2037  * the final part ss(mm) is the current number of significant digits and the
2038  * maximum number of significant digits, respectively.
2039  */
2040 static VALUE
2042 {
2043  ENTER(5);
2044  Real *vp;
2045  volatile VALUE obj;
2046  size_t nc;
2047  char *psz, *tmp;
2048 
2049  GUARD_OBJ(vp, GetVpValue(self, 1));
2050  nc = VpNumOfChars(vp, "E");
2051  nc += (nc + 9) / 10;
2052 
2053  obj = rb_str_new(0, nc+256);
2054  psz = RSTRING_PTR(obj);
2055  sprintf(psz, "#<BigDecimal:%"PRIxVALUE",'", self);
2056  tmp = psz + strlen(psz);
2057  VpToString(vp, tmp, 10, 0);
2058  tmp += strlen(tmp);
2059  sprintf(tmp, "',%"PRIuSIZE"(%"PRIuSIZE")>", VpPrec(vp)*VpBaseFig(), VpMaxPrec(vp)*VpBaseFig());
2060  rb_str_resize(obj, strlen(psz));
2061  return obj;
2062 }
2063 
2064 static VALUE BigMath_s_exp(VALUE, VALUE, VALUE);
2065 static VALUE BigMath_s_log(VALUE, VALUE, VALUE);
2066 
2067 #define BigMath_exp(x, n) BigMath_s_exp(rb_mBigMath, (x), (n))
2068 #define BigMath_log(x, n) BigMath_s_log(rb_mBigMath, (x), (n))
2069 
2070 inline static int
2072 {
2073  return (RB_TYPE_P(x, T_FIXNUM) || RB_TYPE_P(x, T_BIGNUM));
2074 }
2075 
2076 inline static int
2078 {
2079  if (FIXNUM_P(x)) {
2080  return FIX2LONG(x) < 0;
2081  }
2082  else if (RB_TYPE_P(x, T_BIGNUM)) {
2083  return RBIGNUM_NEGATIVE_P(x);
2084  }
2085  else if (RB_TYPE_P(x, T_FLOAT)) {
2086  return RFLOAT_VALUE(x) < 0.0;
2087  }
2088  return RTEST(rb_funcall(x, '<', 1, INT2FIX(0)));
2089 }
2090 
2091 #define is_positive(x) (!is_negative(x))
2092 
2093 inline static int
2095 {
2096  VALUE num;
2097 
2098  switch (TYPE(x)) {
2099  case T_FIXNUM:
2100  return FIX2LONG(x) == 0;
2101 
2102  case T_BIGNUM:
2103  return Qfalse;
2104 
2105  case T_RATIONAL:
2106  num = RRATIONAL(x)->num;
2107  return FIXNUM_P(num) && FIX2LONG(num) == 0;
2108 
2109  default:
2110  break;
2111  }
2112 
2113  return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(0)));
2114 }
2115 
2116 inline static int
2118 {
2119  VALUE num, den;
2120 
2121  switch (TYPE(x)) {
2122  case T_FIXNUM:
2123  return FIX2LONG(x) == 1;
2124 
2125  case T_BIGNUM:
2126  return Qfalse;
2127 
2128  case T_RATIONAL:
2129  num = RRATIONAL(x)->num;
2130  den = RRATIONAL(x)->den;
2131  return FIXNUM_P(den) && FIX2LONG(den) == 1 &&
2132  FIXNUM_P(num) && FIX2LONG(num) == 1;
2133 
2134  default:
2135  break;
2136  }
2137 
2138  return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(1)));
2139 }
2140 
2141 inline static int
2143 {
2144  switch (TYPE(x)) {
2145  case T_FIXNUM:
2146  return (FIX2LONG(x) % 2) == 0;
2147 
2148  case T_BIGNUM:
2149  {
2150  unsigned long l;
2151  rb_big_pack(x, &l, 1);
2152  return l % 2 == 0;
2153  }
2154 
2155  default:
2156  break;
2157  }
2158 
2159  return 0;
2160 }
2161 
2162 static VALUE
2163 rmpd_power_by_big_decimal(Real const* x, Real const* exp, ssize_t const n)
2164 {
2165  VALUE log_x, multiplied, y;
2166  volatile VALUE obj = exp->obj;
2167 
2168  if (VpIsZero(exp)) {
2169  return ToValue(VpCreateRbObject(n, "1"));
2170  }
2171 
2172  log_x = BigMath_log(x->obj, SSIZET2NUM(n+1));
2173  multiplied = BigDecimal_mult2(exp->obj, log_x, SSIZET2NUM(n+1));
2174  y = BigMath_exp(multiplied, SSIZET2NUM(n));
2175  RB_GC_GUARD(obj);
2176 
2177  return y;
2178 }
2179 
2180 /* call-seq:
2181  * power(n)
2182  * power(n, prec)
2183  *
2184  * Returns the value raised to the power of n.
2185  *
2186  * Note that n must be an Integer.
2187  *
2188  * Also available as the operator **
2189  */
2190 static VALUE
2192 {
2193  ENTER(5);
2194  VALUE vexp, prec;
2195  Real* exp = NULL;
2196  Real *x, *y;
2197  ssize_t mp, ma, n;
2198  SIGNED_VALUE int_exp;
2199  double d;
2200 
2201  rb_scan_args(argc, argv, "11", &vexp, &prec);
2202 
2203  GUARD_OBJ(x, GetVpValue(self, 1));
2204  n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec);
2205 
2206  if (VpIsNaN(x)) {
2207  y = VpCreateRbObject(n, "0#");
2208  RB_GC_GUARD(y->obj);
2209  VpSetNaN(y);
2210  return ToValue(y);
2211  }
2212 
2213  retry:
2214  switch (TYPE(vexp)) {
2215  case T_FIXNUM:
2216  break;
2217 
2218  case T_BIGNUM:
2219  break;
2220 
2221  case T_FLOAT:
2222  d = RFLOAT_VALUE(vexp);
2223  if (d == round(d)) {
2224  if (FIXABLE(d)) {
2225  vexp = LONG2FIX((long)d);
2226  }
2227  else {
2228  vexp = rb_dbl2big(d);
2229  }
2230  goto retry;
2231  }
2232  exp = GetVpValueWithPrec(vexp, DBL_DIG+1, 1);
2233  break;
2234 
2235  case T_RATIONAL:
2236  if (is_zero(RRATIONAL(vexp)->num)) {
2237  if (is_positive(vexp)) {
2238  vexp = INT2FIX(0);
2239  goto retry;
2240  }
2241  }
2242  else if (is_one(RRATIONAL(vexp)->den)) {
2243  vexp = RRATIONAL(vexp)->num;
2244  goto retry;
2245  }
2246  exp = GetVpValueWithPrec(vexp, n, 1);
2247  break;
2248 
2249  case T_DATA:
2250  if (is_kind_of_BigDecimal(vexp)) {
2251  VALUE zero = INT2FIX(0);
2252  VALUE rounded = BigDecimal_round(1, &zero, vexp);
2253  if (RTEST(BigDecimal_eq(vexp, rounded))) {
2254  vexp = BigDecimal_to_i(vexp);
2255  goto retry;
2256  }
2257  exp = DATA_PTR(vexp);
2258  break;
2259  }
2260  /* fall through */
2261  default:
2263  "wrong argument type %s (expected scalar Numeric)",
2264  rb_obj_classname(vexp));
2265  }
2266 
2267  if (VpIsZero(x)) {
2268  if (is_negative(vexp)) {
2269  y = VpCreateRbObject(n, "#0");
2270  RB_GC_GUARD(y->obj);
2271  if (VpGetSign(x) < 0) {
2272  if (is_integer(vexp)) {
2273  if (is_even(vexp)) {
2274  /* (-0) ** (-even_integer) -> Infinity */
2275  VpSetPosInf(y);
2276  }
2277  else {
2278  /* (-0) ** (-odd_integer) -> -Infinity */
2279  VpSetNegInf(y);
2280  }
2281  }
2282  else {
2283  /* (-0) ** (-non_integer) -> Infinity */
2284  VpSetPosInf(y);
2285  }
2286  }
2287  else {
2288  /* (+0) ** (-num) -> Infinity */
2289  VpSetPosInf(y);
2290  }
2291  return ToValue(y);
2292  }
2293  else if (is_zero(vexp)) {
2294  return ToValue(VpCreateRbObject(n, "1"));
2295  }
2296  else {
2297  return ToValue(VpCreateRbObject(n, "0"));
2298  }
2299  }
2300 
2301  if (is_zero(vexp)) {
2302  return ToValue(VpCreateRbObject(n, "1"));
2303  }
2304  else if (is_one(vexp)) {
2305  return self;
2306  }
2307 
2308  if (VpIsInf(x)) {
2309  if (is_negative(vexp)) {
2310  if (VpGetSign(x) < 0) {
2311  if (is_integer(vexp)) {
2312  if (is_even(vexp)) {
2313  /* (-Infinity) ** (-even_integer) -> +0 */
2314  return ToValue(VpCreateRbObject(n, "0"));
2315  }
2316  else {
2317  /* (-Infinity) ** (-odd_integer) -> -0 */
2318  return ToValue(VpCreateRbObject(n, "-0"));
2319  }
2320  }
2321  else {
2322  /* (-Infinity) ** (-non_integer) -> -0 */
2323  return ToValue(VpCreateRbObject(n, "-0"));
2324  }
2325  }
2326  else {
2327  return ToValue(VpCreateRbObject(n, "0"));
2328  }
2329  }
2330  else {
2331  y = VpCreateRbObject(n, "0#");
2332  if (VpGetSign(x) < 0) {
2333  if (is_integer(vexp)) {
2334  if (is_even(vexp)) {
2335  VpSetPosInf(y);
2336  }
2337  else {
2338  VpSetNegInf(y);
2339  }
2340  }
2341  else {
2342  /* TODO: support complex */
2344  "a non-integral exponent for a negative base");
2345  }
2346  }
2347  else {
2348  VpSetPosInf(y);
2349  }
2350  return ToValue(y);
2351  }
2352  }
2353 
2354  if (exp != NULL) {
2355  return rmpd_power_by_big_decimal(x, exp, n);
2356  }
2357  else if (RB_TYPE_P(vexp, T_BIGNUM)) {
2358  VALUE abs_value = BigDecimal_abs(self);
2359  if (is_one(abs_value)) {
2360  return ToValue(VpCreateRbObject(n, "1"));
2361  }
2362  else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) {
2363  if (is_negative(vexp)) {
2364  y = VpCreateRbObject(n, "0#");
2365  if (is_even(vexp)) {
2366  VpSetInf(y, VpGetSign(x));
2367  }
2368  else {
2369  VpSetInf(y, -VpGetSign(x));
2370  }
2371  return ToValue(y);
2372  }
2373  else if (VpGetSign(x) < 0 && is_even(vexp)) {
2374  return ToValue(VpCreateRbObject(n, "-0"));
2375  }
2376  else {
2377  return ToValue(VpCreateRbObject(n, "0"));
2378  }
2379  }
2380  else {
2381  if (is_positive(vexp)) {
2382  y = VpCreateRbObject(n, "0#");
2383  if (is_even(vexp)) {
2384  VpSetInf(y, VpGetSign(x));
2385  }
2386  else {
2387  VpSetInf(y, -VpGetSign(x));
2388  }
2389  return ToValue(y);
2390  }
2391  else if (VpGetSign(x) < 0 && is_even(vexp)) {
2392  return ToValue(VpCreateRbObject(n, "-0"));
2393  }
2394  else {
2395  return ToValue(VpCreateRbObject(n, "0"));
2396  }
2397  }
2398  }
2399 
2400  int_exp = FIX2LONG(vexp);
2401  ma = int_exp;
2402  if (ma < 0) ma = -ma;
2403  if (ma == 0) ma = 1;
2404 
2405  if (VpIsDef(x)) {
2406  mp = x->Prec * (VpBaseFig() + 1);
2407  GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0"));
2408  }
2409  else {
2410  GUARD_OBJ(y, VpCreateRbObject(1, "0"));
2411  }
2412  VpPower(y, x, int_exp);
2413  if (!NIL_P(prec) && VpIsDef(y)) {
2414  VpMidRound(y, VpGetRoundMode(), n);
2415  }
2416  return ToValue(y);
2417 }
2418 
2419 /* call-seq:
2420  * big_decimal ** exp -> big_decimal
2421  *
2422  * It is a synonym of BigDecimal#power(exp).
2423  */
2424 static VALUE
2426 {
2427  return BigDecimal_power(1, &exp, self);
2428 }
2429 
2430 static VALUE
2432 {
2433  return VpNewRbClass(0, NULL, klass)->obj;
2434 }
2435 
2436 static Real *BigDecimal_new(int argc, VALUE *argv);
2437 
2438 /* call-seq:
2439  * new(initial, digits)
2440  *
2441  * Create a new BigDecimal object.
2442  *
2443  * initial:: The initial value, as an Integer, a Float, a Rational,
2444  * a BigDecimal, or a String.
2445  *
2446  * If it is a String, spaces are ignored and unrecognized characters
2447  * terminate the value.
2448  *
2449  * digits:: The number of significant digits, as a Fixnum. If omitted or 0,
2450  * the number of significant digits is determined from the initial
2451  * value.
2452  *
2453  * The actual number of significant digits used in computation is usually
2454  * larger than the specified number.
2455  */
2456 static VALUE
2458 {
2459  ENTER(1);
2460  Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
2461  Real *x;
2462 
2463  GUARD_OBJ(x, BigDecimal_new(argc, argv));
2464  if (ToValue(x)) {
2465  pv = VpCopy(pv, x);
2466  }
2467  else {
2468  VpFree(pv);
2469  pv = x;
2470  }
2471  DATA_PTR(self) = pv;
2472  pv->obj = self;
2473  return self;
2474 }
2475 
2476 /* :nodoc:
2477  *
2478  * private method to dup and clone the provided BigDecimal +other+
2479  */
2480 static VALUE
2482 {
2483  Real *pv = rb_check_typeddata(self, &BigDecimal_data_type);
2484  Real *x = rb_check_typeddata(other, &BigDecimal_data_type);
2485 
2486  if (self != other) {
2487  DATA_PTR(self) = VpCopy(pv, x);
2488  }
2489  return self;
2490 }
2491 
2492 static Real *
2494 {
2495  size_t mf;
2496  VALUE nFig;
2497  VALUE iniValue;
2498 
2499  if (rb_scan_args(argc, argv, "11", &iniValue, &nFig) == 1) {
2500  mf = 0;
2501  }
2502  else {
2503  mf = GetPositiveInt(nFig);
2504  }
2505 
2506  switch (TYPE(iniValue)) {
2507  case T_DATA:
2508  if (is_kind_of_BigDecimal(iniValue)) {
2509  return DATA_PTR(iniValue);
2510  }
2511  break;
2512 
2513  case T_FIXNUM:
2514  /* fall through */
2515  case T_BIGNUM:
2516  return GetVpValue(iniValue, 1);
2517 
2518  case T_FLOAT:
2519  if (mf > DBL_DIG+1) {
2520  rb_raise(rb_eArgError, "precision too large.");
2521  }
2522  /* fall through */
2523  case T_RATIONAL:
2524  if (NIL_P(nFig)) {
2526  "can't omit precision for a %"PRIsVALUE".",
2527  rb_obj_class(iniValue));
2528  }
2529  return GetVpValueWithPrec(iniValue, mf, 1);
2530 
2531  case T_STRING:
2532  /* fall through */
2533  default:
2534  break;
2535  }
2536  StringValueCStr(iniValue);
2537  return VpAlloc(mf, RSTRING_PTR(iniValue));
2538 }
2539 
2540 /* See also BigDecimal::new */
2541 static VALUE
2543 {
2544  ENTER(1);
2545  Real *pv;
2546 
2547  GUARD_OBJ(pv, BigDecimal_new(argc, argv));
2548  if (ToValue(pv)) pv = VpCopy(NULL, pv);
2549  pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
2550  return pv->obj;
2551 }
2552 
2553  /* call-seq:
2554  * BigDecimal.limit(digits)
2555  *
2556  * Limit the number of significant digits in newly created BigDecimal
2557  * numbers to the specified value. Rounding is performed as necessary,
2558  * as specified by BigDecimal.mode.
2559  *
2560  * A limit of 0, the default, means no upper limit.
2561  *
2562  * The limit specified by this method takes less priority over any limit
2563  * specified to instance methods such as ceil, floor, truncate, or round.
2564  */
2565 static VALUE
2567 {
2568  VALUE nFig;
2569  VALUE nCur = INT2NUM(VpGetPrecLimit());
2570 
2571  if (rb_scan_args(argc, argv, "01", &nFig) == 1) {
2572  int nf;
2573  if (NIL_P(nFig)) return nCur;
2574  Check_Type(nFig, T_FIXNUM);
2575  nf = FIX2INT(nFig);
2576  if (nf < 0) {
2577  rb_raise(rb_eArgError, "argument must be positive");
2578  }
2579  VpSetPrecLimit(nf);
2580  }
2581  return nCur;
2582 }
2583 
2584 /* Returns the sign of the value.
2585  *
2586  * Returns a positive value if > 0, a negative value if < 0, and a
2587  * zero if == 0.
2588  *
2589  * The specific value returned indicates the type and sign of the BigDecimal,
2590  * as follows:
2591  *
2592  * BigDecimal::SIGN_NaN:: value is Not a Number
2593  * BigDecimal::SIGN_POSITIVE_ZERO:: value is +0
2594  * BigDecimal::SIGN_NEGATIVE_ZERO:: value is -0
2595  * BigDecimal::SIGN_POSITIVE_INFINITE:: value is +Infinity
2596  * BigDecimal::SIGN_NEGATIVE_INFINITE:: value is -Infinity
2597  * BigDecimal::SIGN_POSITIVE_FINITE:: value is positive
2598  * BigDecimal::SIGN_NEGATIVE_FINITE:: value is negative
2599  */
2600 static VALUE
2602 { /* sign */
2603  int s = GetVpValue(self, 1)->sign;
2604  return INT2FIX(s);
2605 }
2606 
2607 /*
2608  * call-seq: BigDecimal.save_exception_mode { ... }
2609  *
2610  * Execute the provided block, but preserve the exception mode
2611  *
2612  * BigDecimal.save_exception_mode do
2613  * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
2614  * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
2615  *
2616  * BigDecimal.new(BigDecimal('Infinity'))
2617  * BigDecimal.new(BigDecimal('-Infinity'))
2618  * BigDecimal(BigDecimal.new('NaN'))
2619  * end
2620  *
2621  * For use with the BigDecimal::EXCEPTION_*
2622  *
2623  * See BigDecimal.mode
2624  */
2625 static VALUE
2627 {
2628  unsigned short const exception_mode = VpGetException();
2629  int state;
2630  VALUE ret = rb_protect(rb_yield, Qnil, &state);
2631  VpSetException(exception_mode);
2632  if (state) rb_jump_tag(state);
2633  return ret;
2634 }
2635 
2636 /*
2637  * call-seq: BigDecimal.save_rounding_mode { ... }
2638  *
2639  * Execute the provided block, but preserve the rounding mode
2640  *
2641  * BigDecimal.save_rounding_mode do
2642  * BigDecimal.mode(BigDecimal::ROUND_MODE, :up)
2643  * puts BigDecimal.mode(BigDecimal::ROUND_MODE)
2644  * end
2645  *
2646  * For use with the BigDecimal::ROUND_*
2647  *
2648  * See BigDecimal.mode
2649  */
2650 static VALUE
2652 {
2653  unsigned short const round_mode = VpGetRoundMode();
2654  int state;
2655  VALUE ret = rb_protect(rb_yield, Qnil, &state);
2656  VpSetRoundMode(round_mode);
2657  if (state) rb_jump_tag(state);
2658  return ret;
2659 }
2660 
2661 /*
2662  * call-seq: BigDecimal.save_limit { ... }
2663  *
2664  * Execute the provided block, but preserve the precision limit
2665  *
2666  * BigDecimal.limit(100)
2667  * puts BigDecimal.limit
2668  * BigDecimal.save_limit do
2669  * BigDecimal.limit(200)
2670  * puts BigDecimal.limit
2671  * end
2672  * puts BigDecimal.limit
2673  *
2674  */
2675 static VALUE
2677 {
2678  size_t const limit = VpGetPrecLimit();
2679  int state;
2680  VALUE ret = rb_protect(rb_yield, Qnil, &state);
2681  VpSetPrecLimit(limit);
2682  if (state) rb_jump_tag(state);
2683  return ret;
2684 }
2685 
2686 /* call-seq:
2687  * BigMath.exp(decimal, numeric) -> BigDecimal
2688  *
2689  * Computes the value of e (the base of natural logarithms) raised to the
2690  * power of +decimal+, to the specified number of digits of precision.
2691  *
2692  * If +decimal+ is infinity, returns Infinity.
2693  *
2694  * If +decimal+ is NaN, returns NaN.
2695  */
2696 static VALUE
2697 BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
2698 {
2699  ssize_t prec, n, i;
2700  Real* vx = NULL;
2701  VALUE one, d, y;
2702  int negative = 0;
2703  int infinite = 0;
2704  int nan = 0;
2705  double flo;
2706 
2707  prec = NUM2SSIZET(vprec);
2708  if (prec <= 0) {
2709  rb_raise(rb_eArgError, "Zero or negative precision for exp");
2710  }
2711 
2712  /* TODO: the following switch statement is almostly the same as one in the
2713  * BigDecimalCmp function. */
2714  switch (TYPE(x)) {
2715  case T_DATA:
2716  if (!is_kind_of_BigDecimal(x)) break;
2717  vx = DATA_PTR(x);
2718  negative = VpGetSign(vx) < 0;
2719  infinite = VpIsPosInf(vx) || VpIsNegInf(vx);
2720  nan = VpIsNaN(vx);
2721  break;
2722 
2723  case T_FIXNUM:
2724  /* fall through */
2725  case T_BIGNUM:
2726  vx = GetVpValue(x, 0);
2727  break;
2728 
2729  case T_FLOAT:
2730  flo = RFLOAT_VALUE(x);
2731  negative = flo < 0;
2732  infinite = isinf(flo);
2733  nan = isnan(flo);
2734  if (!infinite && !nan) {
2735  vx = GetVpValueWithPrec(x, DBL_DIG+1, 0);
2736  }
2737  break;
2738 
2739  case T_RATIONAL:
2740  vx = GetVpValueWithPrec(x, prec, 0);
2741  break;
2742 
2743  default:
2744  break;
2745  }
2746  if (infinite) {
2747  if (negative) {
2748  return ToValue(GetVpValueWithPrec(INT2FIX(0), prec, 1));
2749  }
2750  else {
2751  Real* vy;
2752  vy = VpCreateRbObject(prec, "#0");
2754  RB_GC_GUARD(vy->obj);
2755  return ToValue(vy);
2756  }
2757  }
2758  else if (nan) {
2759  Real* vy;
2760  vy = VpCreateRbObject(prec, "#0");
2761  VpSetNaN(vy);
2762  RB_GC_GUARD(vy->obj);
2763  return ToValue(vy);
2764  }
2765  else if (vx == NULL) {
2767  }
2768  x = vx->obj;
2769 
2770  n = prec + rmpd_double_figures();
2771  negative = VpGetSign(vx) < 0;
2772  if (negative) {
2773  VpSetSign(vx, 1);
2774  }
2775 
2776  one = ToValue(VpCreateRbObject(1, "1"));
2777  y = one;
2778  d = y;
2779  i = 1;
2780 
2781  while (!VpIsZero((Real*)DATA_PTR(d))) {
2782  SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y));
2783  SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d));
2784  ssize_t m = n - vabs(ey - ed);
2785 
2787 
2788  if (m <= 0) {
2789  break;
2790  }
2791  else if ((size_t)m < rmpd_double_figures()) {
2792  m = rmpd_double_figures();
2793  }
2794 
2795  d = BigDecimal_mult(d, x); /* d <- d * x */
2796  d = BigDecimal_div2(d, SSIZET2NUM(i), SSIZET2NUM(m)); /* d <- d / i */
2797  y = BigDecimal_add(y, d); /* y <- y + d */
2798  ++i; /* i <- i + 1 */
2799  }
2800 
2801  if (negative) {
2802  return BigDecimal_div2(one, y, vprec);
2803  }
2804  else {
2805  vprec = SSIZET2NUM(prec - VpExponent10(DATA_PTR(y)));
2806  return BigDecimal_round(1, &vprec, y);
2807  }
2808 
2809  RB_GC_GUARD(one);
2810  RB_GC_GUARD(x);
2811  RB_GC_GUARD(y);
2812  RB_GC_GUARD(d);
2813 }
2814 
2815 /* call-seq:
2816  * BigMath.log(decimal, numeric) -> BigDecimal
2817  *
2818  * Computes the natural logarithm of +decimal+ to the specified number of
2819  * digits of precision, +numeric+.
2820  *
2821  * If +decimal+ is zero or negative, raises Math::DomainError.
2822  *
2823  * If +decimal+ is positive infinity, returns Infinity.
2824  *
2825  * If +decimal+ is NaN, returns NaN.
2826  */
2827 static VALUE
2828 BigMath_s_log(VALUE klass, VALUE x, VALUE vprec)
2829 {
2830  ssize_t prec, n, i;
2831  SIGNED_VALUE expo;
2832  Real* vx = NULL;
2833  VALUE vn, one, two, w, x2, y, d;
2834  int zero = 0;
2835  int negative = 0;
2836  int infinite = 0;
2837  int nan = 0;
2838  double flo;
2839  long fix;
2840 
2841  if (!is_integer(vprec)) {
2842  rb_raise(rb_eArgError, "precision must be an Integer");
2843  }
2844 
2845  prec = NUM2SSIZET(vprec);
2846  if (prec <= 0) {
2847  rb_raise(rb_eArgError, "Zero or negative precision for exp");
2848  }
2849 
2850  /* TODO: the following switch statement is almostly the same as one in the
2851  * BigDecimalCmp function. */
2852  switch (TYPE(x)) {
2853  case T_DATA:
2854  if (!is_kind_of_BigDecimal(x)) break;
2855  vx = DATA_PTR(x);
2856  zero = VpIsZero(vx);
2857  negative = VpGetSign(vx) < 0;
2858  infinite = VpIsPosInf(vx) || VpIsNegInf(vx);
2859  nan = VpIsNaN(vx);
2860  break;
2861 
2862  case T_FIXNUM:
2863  fix = FIX2LONG(x);
2864  zero = fix == 0;
2865  negative = fix < 0;
2866  goto get_vp_value;
2867 
2868  case T_BIGNUM:
2869  zero = RBIGNUM_ZERO_P(x);
2870  negative = RBIGNUM_NEGATIVE_P(x);
2871 get_vp_value:
2872  if (zero || negative) break;
2873  vx = GetVpValue(x, 0);
2874  break;
2875 
2876  case T_FLOAT:
2877  flo = RFLOAT_VALUE(x);
2878  zero = flo == 0;
2879  negative = flo < 0;
2880  infinite = isinf(flo);
2881  nan = isnan(flo);
2882  if (!zero && !negative && !infinite && !nan) {
2883  vx = GetVpValueWithPrec(x, DBL_DIG+1, 1);
2884  }
2885  break;
2886 
2887  case T_RATIONAL:
2888  zero = RRATIONAL_ZERO_P(x);
2889  negative = RRATIONAL_NEGATIVE_P(x);
2890  if (zero || negative) break;
2891  vx = GetVpValueWithPrec(x, prec, 1);
2892  break;
2893 
2894  case T_COMPLEX:
2896  "Complex argument for BigMath.log");
2897 
2898  default:
2899  break;
2900  }
2901  if (infinite && !negative) {
2902  Real* vy;
2903  vy = VpCreateRbObject(prec, "#0");
2904  RB_GC_GUARD(vy->obj);
2906  return ToValue(vy);
2907  }
2908  else if (nan) {
2909  Real* vy;
2910  vy = VpCreateRbObject(prec, "#0");
2911  RB_GC_GUARD(vy->obj);
2912  VpSetNaN(vy);
2913  return ToValue(vy);
2914  }
2915  else if (zero || negative) {
2917  "Zero or negative argument for log");
2918  }
2919  else if (vx == NULL) {
2921  }
2922  x = ToValue(vx);
2923 
2924  RB_GC_GUARD(one) = ToValue(VpCreateRbObject(1, "1"));
2925  RB_GC_GUARD(two) = ToValue(VpCreateRbObject(1, "2"));
2926 
2927  n = prec + rmpd_double_figures();
2928  RB_GC_GUARD(vn) = SSIZET2NUM(n);
2929  expo = VpExponent10(vx);
2930  if (expo < 0 || expo >= 3) {
2931  char buf[16];
2932  snprintf(buf, 16, "1E%"PRIdVALUE, -expo);
2933  x = BigDecimal_mult2(x, ToValue(VpCreateRbObject(1, buf)), vn);
2934  }
2935  else {
2936  expo = 0;
2937  }
2938  w = BigDecimal_sub(x, one);
2939  x = BigDecimal_div2(w, BigDecimal_add(x, one), vn);
2940  RB_GC_GUARD(x2) = BigDecimal_mult2(x, x, vn);
2941  RB_GC_GUARD(y) = x;
2942  RB_GC_GUARD(d) = y;
2943  i = 1;
2944  while (!VpIsZero((Real*)DATA_PTR(d))) {
2945  SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y));
2946  SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d));
2947  ssize_t m = n - vabs(ey - ed);
2948  if (m <= 0) {
2949  break;
2950  }
2951  else if ((size_t)m < rmpd_double_figures()) {
2952  m = rmpd_double_figures();
2953  }
2954 
2955  x = BigDecimal_mult2(x2, x, vn);
2956  i += 2;
2957  d = BigDecimal_div2(x, SSIZET2NUM(i), SSIZET2NUM(m));
2958  y = BigDecimal_add(y, d);
2959  }
2960 
2961  y = BigDecimal_mult(y, two);
2962  if (expo != 0) {
2963  VALUE log10, vexpo, dy;
2964  log10 = BigMath_s_log(klass, INT2FIX(10), vprec);
2965  vexpo = ToValue(GetVpValue(SSIZET2NUM(expo), 1));
2966  dy = BigDecimal_mult(log10, vexpo);
2967  y = BigDecimal_add(y, dy);
2968  }
2969 
2970  return y;
2971 }
2972 
2973 /* Document-class: BigDecimal
2974  * BigDecimal provides arbitrary-precision floating point decimal arithmetic.
2975  *
2976  * == Introduction
2977  *
2978  * Ruby provides built-in support for arbitrary precision integer arithmetic.
2979  *
2980  * For example:
2981  *
2982  * 42**13 #=> 1265437718438866624512
2983  *
2984  * BigDecimal provides similar support for very large or very accurate floating
2985  * point numbers.
2986  *
2987  * Decimal arithmetic is also useful for general calculation, because it
2988  * provides the correct answers people expect--whereas normal binary floating
2989  * point arithmetic often introduces subtle errors because of the conversion
2990  * between base 10 and base 2.
2991  *
2992  * For example, try:
2993  *
2994  * sum = 0
2995  * 10_000.times do
2996  * sum = sum + 0.0001
2997  * end
2998  * print sum #=> 0.9999999999999062
2999  *
3000  * and contrast with the output from:
3001  *
3002  * require 'bigdecimal'
3003  *
3004  * sum = BigDecimal.new("0")
3005  * 10_000.times do
3006  * sum = sum + BigDecimal.new("0.0001")
3007  * end
3008  * print sum #=> 0.1E1
3009  *
3010  * Similarly:
3011  *
3012  * (BigDecimal.new("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true
3013  *
3014  * (1.2 - 1.0) == 0.2 #=> false
3015  *
3016  * == Special features of accurate decimal arithmetic
3017  *
3018  * Because BigDecimal is more accurate than normal binary floating point
3019  * arithmetic, it requires some special values.
3020  *
3021  * === Infinity
3022  *
3023  * BigDecimal sometimes needs to return infinity, for example if you divide
3024  * a value by zero.
3025  *
3026  * BigDecimal.new("1.0") / BigDecimal.new("0.0") #=> Infinity
3027  * BigDecimal.new("-1.0") / BigDecimal.new("0.0") #=> -Infinity
3028  *
3029  * You can represent infinite numbers to BigDecimal using the strings
3030  * <code>'Infinity'</code>, <code>'+Infinity'</code> and
3031  * <code>'-Infinity'</code> (case-sensitive)
3032  *
3033  * === Not a Number
3034  *
3035  * When a computation results in an undefined value, the special value +NaN+
3036  * (for 'not a number') is returned.
3037  *
3038  * Example:
3039  *
3040  * BigDecimal.new("0.0") / BigDecimal.new("0.0") #=> NaN
3041  *
3042  * You can also create undefined values.
3043  *
3044  * NaN is never considered to be the same as any other value, even NaN itself:
3045  *
3046  * n = BigDecimal.new('NaN')
3047  * n == 0.0 #=> false
3048  * n == n #=> false
3049  *
3050  * === Positive and negative zero
3051  *
3052  * If a computation results in a value which is too small to be represented as
3053  * a BigDecimal within the currently specified limits of precision, zero must
3054  * be returned.
3055  *
3056  * If the value which is too small to be represented is negative, a BigDecimal
3057  * value of negative zero is returned.
3058  *
3059  * BigDecimal.new("1.0") / BigDecimal.new("-Infinity") #=> -0.0
3060  *
3061  * If the value is positive, a value of positive zero is returned.
3062  *
3063  * BigDecimal.new("1.0") / BigDecimal.new("Infinity") #=> 0.0
3064  *
3065  * (See BigDecimal.mode for how to specify limits of precision.)
3066  *
3067  * Note that +-0.0+ and +0.0+ are considered to be the same for the purposes of
3068  * comparison.
3069  *
3070  * Note also that in mathematics, there is no particular concept of negative
3071  * or positive zero; true mathematical zero has no sign.
3072  *
3073  * == License
3074  *
3075  * Copyright (C) 2002 by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>.
3076  *
3077  * You may distribute under the terms of either the GNU General Public
3078  * License or the Artistic License, as specified in the README file
3079  * of the BigDecimal distribution.
3080  *
3081  * Maintained by mrkn <mrkn@mrkn.jp> and ruby-core members.
3082  *
3083  * Documented by zzak <zachary@zacharyscott.net>, mathew <meta@pobox.com>, and
3084  * many other contributors.
3085  */
3086 void
3088 {
3089  VALUE arg;
3090 
3091  id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode");
3092  id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode");
3093  id_BigDecimal_precision_limit = rb_intern_const("BigDecimal.precision_limit");
3094 
3095  /* Initialize VP routines */
3096  VpInit(0UL);
3097 
3098  /* Class and method registration */
3099  rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric);
3101 
3102  /* Global function */
3104 
3105  /* Class methods */
3111 
3115 
3116  /* Constants definition */
3117 
3118  /*
3119  * Base value used in internal calculations. On a 32 bit system, BASE
3120  * is 10000, indicating that calculation is done in groups of 4 digits.
3121  * (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't
3122  * guarantee that two groups could always be multiplied together without
3123  * overflow.)
3124  */
3126 
3127  /* Exceptions */
3128 
3129  /*
3130  * 0xff: Determines whether overflow, underflow or zero divide result in
3131  * an exception being thrown. See BigDecimal.mode.
3132  */
3134 
3135  /*
3136  * 0x02: Determines what happens when the result of a computation is not a
3137  * number (NaN). See BigDecimal.mode.
3138  */
3140 
3141  /*
3142  * 0x01: Determines what happens when the result of a computation is
3143  * infinity. See BigDecimal.mode.
3144  */
3146 
3147  /*
3148  * 0x04: Determines what happens when the result of a computation is an
3149  * underflow (a result too small to be represented). See BigDecimal.mode.
3150  */
3152 
3153  /*
3154  * 0x01: Determines what happens when the result of a computation is an
3155  * overflow (a result too large to be represented). See BigDecimal.mode.
3156  */
3158 
3159  /*
3160  * 0x01: Determines what happens when a division by zero is performed.
3161  * See BigDecimal.mode.
3162  */
3164 
3165  /*
3166  * 0x100: Determines what happens when a result must be rounded in order to
3167  * fit in the appropriate number of significant digits. See
3168  * BigDecimal.mode.
3169  */
3171 
3172  /* 1: Indicates that values should be rounded away from zero. See
3173  * BigDecimal.mode.
3174  */
3176 
3177  /* 2: Indicates that values should be rounded towards zero. See
3178  * BigDecimal.mode.
3179  */
3181 
3182  /* 3: Indicates that digits >= 5 should be rounded up, others rounded down.
3183  * See BigDecimal.mode. */
3185 
3186  /* 4: Indicates that digits >= 6 should be rounded up, others rounded down.
3187  * See BigDecimal.mode.
3188  */
3190  /* 5: Round towards +Infinity. See BigDecimal.mode. */
3192 
3193  /* 6: Round towards -Infinity. See BigDecimal.mode. */
3195 
3196  /* 7: Round towards the even neighbor. See BigDecimal.mode. */
3198 
3199  /* 0: Indicates that a value is not a number. See BigDecimal.sign. */
3201 
3202  /* 1: Indicates that a value is +0. See BigDecimal.sign. */
3204 
3205  /* -1: Indicates that a value is -0. See BigDecimal.sign. */
3207 
3208  /* 2: Indicates that a value is positive and finite. See BigDecimal.sign. */
3210 
3211  /* -2: Indicates that a value is negative and finite. See BigDecimal.sign. */
3213 
3214  /* 3: Indicates that a value is positive and infinite. See BigDecimal.sign. */
3215  rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_INFINITE", INT2FIX(VP_SIGN_POSITIVE_INFINITE));
3216 
3217  /* -3: Indicates that a value is negative and infinite. See BigDecimal.sign. */
3218  rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE));
3219 
3220  arg = rb_str_new2("+Infinity");
3221  /* Positive infinity value. */
3223  arg = rb_str_new2("NaN");
3224  /* 'Not a Number' value. */
3226 
3227 
3228  /* instance methods */
3232 
3254  /* rb_define_method(rb_cBigDecimal, "dup", BigDecimal_dup, 0); */
3284 
3285  rb_mBigMath = rb_define_module("BigMath");
3288 
3289  id_up = rb_intern_const("up");
3290  id_down = rb_intern_const("down");
3291  id_truncate = rb_intern_const("truncate");
3292  id_half_up = rb_intern_const("half_up");
3293  id_default = rb_intern_const("default");
3294  id_half_down = rb_intern_const("half_down");
3295  id_half_even = rb_intern_const("half_even");
3296  id_banker = rb_intern_const("banker");
3297  id_ceiling = rb_intern_const("ceiling");
3298  id_ceil = rb_intern_const("ceil");
3299  id_floor = rb_intern_const("floor");
3300  id_to_r = rb_intern_const("to_r");
3301  id_eq = rb_intern_const("==");
3302 }
3303 
3304 /*
3305  *
3306  * ============================================================================
3307  *
3308  * vp_ routines begin from here.
3309  *
3310  * ============================================================================
3311  *
3312  */
3313 #ifdef BIGDECIMAL_DEBUG
3314 static int gfDebug = 1; /* Debug switch */
3315 #if 0
3316 static int gfCheckVal = 1; /* Value checking flag in VpNmlz() */
3317 #endif
3318 #endif /* BIGDECIMAL_DEBUG */
3319 
3320 static Real *VpConstOne; /* constant 1.0 */
3321 static Real *VpPt5; /* constant 0.5 */
3322 #define maxnr 100UL /* Maximum iterations for calculating sqrt. */
3323  /* used in VpSqrt() */
3324 
3325 /* ETC */
3326 #define MemCmp(x,y,z) memcmp(x,y,z)
3327 #define StrCmp(x,y) strcmp(x,y)
3328 
3329 static int VpIsDefOP(Real *c,Real *a,Real *b,int sw);
3330 static int AddExponent(Real *a, SIGNED_VALUE n);
3331 static BDIGIT VpAddAbs(Real *a,Real *b,Real *c);
3332 static BDIGIT VpSubAbs(Real *a,Real *b,Real *c);
3333 static size_t VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, BDIGIT *av, BDIGIT *bv);
3334 static int VpNmlz(Real *a);
3335 static void VpFormatSt(char *psz, size_t fFmt);
3336 static int VpRdup(Real *m, size_t ind_m);
3337 
3338 #ifdef BIGDECIMAL_DEBUG
3339 static int gnAlloc = 0; /* Memory allocation counter */
3340 #endif /* BIGDECIMAL_DEBUG */
3341 
3342 VP_EXPORT void *
3343 VpMemAlloc(size_t mb)
3344 {
3345  void *p = xmalloc(mb);
3346  if (!p) {
3347  VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1);
3348  }
3349  memset(p, 0, mb);
3350 #ifdef BIGDECIMAL_DEBUG
3351  gnAlloc++; /* Count allocation call */
3352 #endif /* BIGDECIMAL_DEBUG */
3353  return p;
3354 }
3355 
3356  VP_EXPORT void *
3357 VpMemRealloc(void *ptr, size_t mb)
3358 {
3359  void *p = xrealloc(ptr, mb);
3360  if (!p) {
3361  VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1);
3362  }
3363  return p;
3364 }
3365 
3366 VP_EXPORT void
3368 {
3369  if (pv != NULL) {
3370  xfree(pv);
3371 #ifdef BIGDECIMAL_DEBUG
3372  gnAlloc--; /* Decrement allocation count */
3373  if (gnAlloc == 0) {
3374  printf(" *************** All memories allocated freed ****************");
3375  getchar();
3376  }
3377  if (gnAlloc < 0) {
3378  printf(" ??????????? Too many memory free calls(%d) ?????????????\n", gnAlloc);
3379  getchar();
3380  }
3381 #endif /* BIGDECIMAL_DEBUG */
3382  }
3383 }
3384 
3385 /*
3386  * EXCEPTION Handling.
3387  */
3388 
3389 #define rmpd_set_thread_local_exception_mode(mode) \
3390  rb_thread_local_aset( \
3391  rb_thread_current(), \
3392  id_BigDecimal_exception_mode, \
3393  INT2FIX((int)(mode)) \
3394  )
3395 
3396 static unsigned short
3398 {
3399  VALUE const vmode = rb_thread_local_aref(
3402  );
3403 
3404  if (NIL_P(vmode)) {
3407  }
3408 
3409  return (unsigned short)FIX2UINT(vmode);
3410 }
3411 
3412 static void
3413 VpSetException(unsigned short f)
3414 {
3416 }
3417 
3418 /*
3419  * Precision limit.
3420  */
3421 
3422 #define rmpd_set_thread_local_precision_limit(limit) \
3423  rb_thread_local_aset( \
3424  rb_thread_current(), \
3425  id_BigDecimal_precision_limit, \
3426  SIZET2NUM(limit) \
3427  )
3428 #define RMPD_PRECISION_LIMIT_DEFAULT ((size_t)0)
3429 
3430 /* These 2 functions added at v1.1.7 */
3431 VP_EXPORT size_t
3433 {
3434  VALUE const vlimit = rb_thread_local_aref(
3437  );
3438 
3439  if (NIL_P(vlimit)) {
3442  }
3443 
3444  return NUM2SIZET(vlimit);
3445 }
3446 
3447 VP_EXPORT size_t
3449 {
3450  size_t const s = VpGetPrecLimit();
3452  return s;
3453 }
3454 
3455 /*
3456  * Rounding mode.
3457  */
3458 
3459 #define rmpd_set_thread_local_rounding_mode(mode) \
3460  rb_thread_local_aset( \
3461  rb_thread_current(), \
3462  id_BigDecimal_rounding_mode, \
3463  INT2FIX((int)(mode)) \
3464  )
3465 
3466 VP_EXPORT unsigned short
3468 {
3469  VALUE const vmode = rb_thread_local_aref(
3472  );
3473 
3474  if (NIL_P(vmode)) {
3477  }
3478 
3479  return (unsigned short)FIX2INT(vmode);
3480 }
3481 
3482 VP_EXPORT int
3483 VpIsRoundMode(unsigned short n)
3484 {
3485  switch (n) {
3486  case VP_ROUND_UP:
3487  case VP_ROUND_DOWN:
3488  case VP_ROUND_HALF_UP:
3489  case VP_ROUND_HALF_DOWN:
3490  case VP_ROUND_CEIL:
3491  case VP_ROUND_FLOOR:
3492  case VP_ROUND_HALF_EVEN:
3493  return 1;
3494 
3495  default:
3496  return 0;
3497  }
3498 }
3499 
3500 VP_EXPORT unsigned short
3501 VpSetRoundMode(unsigned short n)
3502 {
3503  if (VpIsRoundMode(n)) {
3505  return n;
3506  }
3507 
3508  return VpGetRoundMode();
3509 }
3510 
3511 /*
3512  * 0.0 & 1.0 generator
3513  * These gZero_..... and gOne_..... can be any name
3514  * referenced from nowhere except Zero() and One().
3515  * gZero_..... and gOne_..... must have global scope
3516  * (to let the compiler know they may be changed in outside
3517  * (... but not actually..)).
3518  */
3519 volatile const double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
3520 volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
3521 static double
3522 Zero(void)
3523 {
3525 }
3526 
3527 static double
3528 One(void)
3529 {
3531 }
3532 
3533 /*
3534  ----------------------------------------------------------------
3535  Value of sign in Real structure is reserved for future use.
3536  short sign;
3537  ==0 : NaN
3538  1 : Positive zero
3539  -1 : Negative zero
3540  2 : Positive number
3541  -2 : Negative number
3542  3 : Positive infinite number
3543  -3 : Negative infinite number
3544  ----------------------------------------------------------------
3545 */
3546 
3547 VP_EXPORT double
3548 VpGetDoubleNaN(void) /* Returns the value of NaN */
3549 {
3550  static double fNaN = 0.0;
3551  if (fNaN == 0.0) fNaN = Zero()/Zero();
3552  return fNaN;
3553 }
3554 
3555 VP_EXPORT double
3556 VpGetDoublePosInf(void) /* Returns the value of +Infinity */
3557 {
3558  static double fInf = 0.0;
3559  if (fInf == 0.0) fInf = One()/Zero();
3560  return fInf;
3561 }
3562 
3563 VP_EXPORT double
3564 VpGetDoubleNegInf(void) /* Returns the value of -Infinity */
3565 {
3566  static double fInf = 0.0;
3567  if (fInf == 0.0) fInf = -(One()/Zero());
3568  return fInf;
3569 }
3570 
3571 VP_EXPORT double
3572 VpGetDoubleNegZero(void) /* Returns the value of -0 */
3573 {
3574  static double nzero = 1000.0;
3575  if (nzero != 0.0) nzero = (One()/VpGetDoubleNegInf());
3576  return nzero;
3577 }
3578 
3579 #if 0 /* unused */
3580 VP_EXPORT int
3581 VpIsNegDoubleZero(double v)
3582 {
3583  double z = VpGetDoubleNegZero();
3584  return MemCmp(&v,&z,sizeof(v))==0;
3585 }
3586 #endif
3587 
3588 VP_EXPORT int
3589 VpException(unsigned short f, const char *str,int always)
3590 {
3591  unsigned short const exception_mode = VpGetException();
3592 
3593  if (f == VP_EXCEPTION_OP || f == VP_EXCEPTION_MEMORY) always = 1;
3594 
3595  if (always || (exception_mode & f)) {
3596  switch(f) {
3597  /* case VP_EXCEPTION_OVERFLOW: */
3599  case VP_EXCEPTION_INFINITY:
3600  case VP_EXCEPTION_NaN:
3602  case VP_EXCEPTION_OP:
3603  rb_raise(rb_eFloatDomainError, "%s", str);
3604  break;
3605  case VP_EXCEPTION_MEMORY:
3606  default:
3607  rb_fatal("%s", str);
3608  }
3609  }
3610  return 0; /* 0 Means VpException() raised no exception */
3611 }
3612 
3613 /* Throw exception or returns 0,when resulting c is Inf or NaN */
3614 /* sw=1:+ 2:- 3:* 4:/ */
3615 static int
3616 VpIsDefOP(Real *c,Real *a,Real *b,int sw)
3617 {
3618  if (VpIsNaN(a) || VpIsNaN(b)) {
3619  /* at least a or b is NaN */
3620  VpSetNaN(c);
3621  goto NaN;
3622  }
3623 
3624  if (VpIsInf(a)) {
3625  if (VpIsInf(b)) {
3626  switch(sw) {
3627  case 1: /* + */
3628  if (VpGetSign(a) == VpGetSign(b)) {
3629  VpSetInf(c, VpGetSign(a));
3630  goto Inf;
3631  }
3632  else {
3633  VpSetNaN(c);
3634  goto NaN;
3635  }
3636  case 2: /* - */
3637  if (VpGetSign(a) != VpGetSign(b)) {
3638  VpSetInf(c, VpGetSign(a));
3639  goto Inf;
3640  }
3641  else {
3642  VpSetNaN(c);
3643  goto NaN;
3644  }
3645  break;
3646  case 3: /* * */
3647  VpSetInf(c, VpGetSign(a)*VpGetSign(b));
3648  goto Inf;
3649  break;
3650  case 4: /* / */
3651  VpSetNaN(c);
3652  goto NaN;
3653  }
3654  VpSetNaN(c);
3655  goto NaN;
3656  }
3657  /* Inf op Finite */
3658  switch(sw) {
3659  case 1: /* + */
3660  case 2: /* - */
3661  VpSetInf(c, VpGetSign(a));
3662  break;
3663  case 3: /* * */
3664  if (VpIsZero(b)) {
3665  VpSetNaN(c);
3666  goto NaN;
3667  }
3668  VpSetInf(c, VpGetSign(a)*VpGetSign(b));
3669  break;
3670  case 4: /* / */
3671  VpSetInf(c, VpGetSign(a)*VpGetSign(b));
3672  }
3673  goto Inf;
3674  }
3675 
3676  if (VpIsInf(b)) {
3677  switch(sw) {
3678  case 1: /* + */
3679  VpSetInf(c, VpGetSign(b));
3680  break;
3681  case 2: /* - */
3682  VpSetInf(c, -VpGetSign(b));
3683  break;
3684  case 3: /* * */
3685  if (VpIsZero(a)) {
3686  VpSetNaN(c);
3687  goto NaN;
3688  }
3689  VpSetInf(c, VpGetSign(a)*VpGetSign(b));
3690  break;
3691  case 4: /* / */
3692  VpSetZero(c, VpGetSign(a)*VpGetSign(b));
3693  }
3694  goto Inf;
3695  }
3696  return 1; /* Results OK */
3697 
3698 Inf:
3699  return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0);
3700 NaN:
3701  return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0);
3702 }
3703 
3704 /*
3705  ----------------------------------------------------------------
3706 */
3707 
3708 /*
3709  * returns number of chars needed to represent vp in specified format.
3710  */
3711 VP_EXPORT size_t
3712 VpNumOfChars(Real *vp,const char *pszFmt)
3713 {
3714  SIGNED_VALUE ex;
3715  size_t nc;
3716 
3717  if (vp == NULL) return BASE_FIG*2+6;
3718  if (!VpIsDef(vp)) return 32; /* not sure,may be OK */
3719 
3720  switch(*pszFmt) {
3721  case 'F':
3722  nc = BASE_FIG*(vp->Prec + 1)+2;
3723  ex = vp->exponent;
3724  if (ex < 0) {
3725  nc += BASE_FIG*(size_t)(-ex);
3726  }
3727  else {
3728  if ((size_t)ex > vp->Prec) {
3729  nc += BASE_FIG*((size_t)ex - vp->Prec);
3730  }
3731  }
3732  break;
3733  case 'E':
3734  /* fall through */
3735  default:
3736  nc = BASE_FIG*(vp->Prec + 2)+6; /* 3: sign + exponent chars */
3737  }
3738  return nc;
3739 }
3740 
3741 /*
3742  * Initializer for Vp routines and constants used.
3743  * [Input]
3744  * BaseVal: Base value(assigned to BASE) for Vp calculation.
3745  * It must be the form BaseVal=10**n.(n=1,2,3,...)
3746  * If Base <= 0L,then the BASE will be calculated so
3747  * that BASE is as large as possible satisfying the
3748  * relation MaxVal <= BASE*(BASE+1). Where the value
3749  * MaxVal is the largest value which can be represented
3750  * by one BDIGIT word in the computer used.
3751  *
3752  * [Returns]
3753  * 1+DBL_DIG ... OK
3754  */
3755 VP_EXPORT size_t
3756 VpInit(BDIGIT BaseVal)
3757 {
3758  /* Setup +/- Inf NaN -0 */
3759  VpGetDoubleNaN();
3763 
3764  /* Allocates Vp constants. */
3765  VpConstOne = VpAlloc(1UL, "1");
3766  VpPt5 = VpAlloc(1UL, ".5");
3767 
3768 #ifdef BIGDECIMAL_DEBUG
3769  gnAlloc = 0;
3770 #endif /* BIGDECIMAL_DEBUG */
3771 
3772 #ifdef BIGDECIMAL_DEBUG
3773  if (gfDebug) {
3774  printf("VpInit: BaseVal = %lu\n", BaseVal);
3775  printf(" BASE = %lu\n", BASE);
3776  printf(" HALF_BASE = %lu\n", HALF_BASE);
3777  printf(" BASE1 = %lu\n", BASE1);
3778  printf(" BASE_FIG = %u\n", BASE_FIG);
3779  printf(" DBLE_FIG = %d\n", DBLE_FIG);
3780  }
3781 #endif /* BIGDECIMAL_DEBUG */
3782 
3783  return rmpd_double_figures();
3784 }
3785 
3786 VP_EXPORT Real *
3787 VpOne(void)
3788 {
3789  return VpConstOne;
3790 }
3791 
3792 /* If exponent overflows,then raise exception or returns 0 */
3793 static int
3795 {
3796  SIGNED_VALUE e = a->exponent;
3797  SIGNED_VALUE m = e+n;
3798  SIGNED_VALUE eb, mb;
3799  if (e > 0) {
3800  if (n > 0) {
3803  goto overflow;
3804  mb = m*(SIGNED_VALUE)BASE_FIG;
3805  eb = e*(SIGNED_VALUE)BASE_FIG;
3806  if (mb < eb) goto overflow;
3807  }
3808  }
3809  else if (n < 0) {
3812  goto underflow;
3813  mb = m*(SIGNED_VALUE)BASE_FIG;
3814  eb = e*(SIGNED_VALUE)BASE_FIG;
3815  if (mb > eb) goto underflow;
3816  }
3817  a->exponent = m;
3818  return 1;
3819 
3820 /* Overflow/Underflow ==> Raise exception or returns 0 */
3821 underflow:
3822  VpSetZero(a, VpGetSign(a));
3823  return VpException(VP_EXCEPTION_UNDERFLOW, "Exponent underflow", 0);
3824 
3825 overflow:
3826  VpSetInf(a, VpGetSign(a));
3827  return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0);
3828 }
3829 
3830 /*
3831  * Allocates variable.
3832  * [Input]
3833  * mx ... allocation unit, if zero then mx is determined by szVal.
3834  * The mx is the number of effective digits can to be stored.
3835  * szVal ... value assigned(char). If szVal==NULL,then zero is assumed.
3836  * If szVal[0]=='#' then Max. Prec. will not be considered(1.1.7),
3837  * full precision specified by szVal is allocated.
3838  *
3839  * [Returns]
3840  * Pointer to the newly allocated variable, or
3841  * NULL be returned if memory allocation is failed,or any error.
3842  */
3843 VP_EXPORT Real *
3844 VpAlloc(size_t mx, const char *szVal)
3845 {
3846  size_t i, ni, ipn, ipf, nf, ipe, ne, nalloc;
3847  char v, *psz;
3848  int sign=1;
3849  Real *vp = NULL;
3850  size_t mf = VpGetPrecLimit();
3851  VALUE buf;
3852 
3853  mx = (mx + BASE_FIG - 1) / BASE_FIG; /* Determine allocation unit. */
3854  if (mx == 0) ++mx;
3855 
3856  if (szVal) {
3857  while (ISSPACE(*szVal)) szVal++;
3858  if (*szVal != '#') {
3859  if (mf) {
3860  mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */
3861  if (mx > mf) {
3862  mx = mf;
3863  }
3864  }
3865  }
3866  else {
3867  ++szVal;
3868  }
3869  }
3870  else {
3871  /* necessary to be able to store */
3872  /* at least mx digits. */
3873  /* szVal==NULL ==> allocate zero value. */
3874  vp = VpAllocReal(mx);
3875  /* xmalloc() alway returns(or throw interruption) */
3876  vp->MaxPrec = mx; /* set max precision */
3877  VpSetZero(vp, 1); /* initialize vp to zero. */
3878  return vp;
3879  }
3880 
3881  /* Skip all '_' after digit: 2006-6-30 */
3882  ni = 0;
3883  buf = rb_str_tmp_new(strlen(szVal) + 1);
3884  psz = RSTRING_PTR(buf);
3885  i = 0;
3886  ipn = 0;
3887  while ((psz[i] = szVal[ipn]) != 0) {
3888  if (ISDIGIT(psz[i])) ++ni;
3889  if (psz[i] == '_') {
3890  if (ni > 0) {
3891  ipn++;
3892  continue;
3893  }
3894  psz[i] = 0;
3895  break;
3896  }
3897  ++i;
3898  ++ipn;
3899  }
3900  /* Skip trailing spaces */
3901  while (--i > 0) {
3902  if (ISSPACE(psz[i])) psz[i] = 0;
3903  else break;
3904  }
3905  szVal = psz;
3906 
3907  /* Check on Inf & NaN */
3908  if (StrCmp(szVal, SZ_PINF) == 0 || StrCmp(szVal, SZ_INF) == 0 ) {
3909  vp = VpAllocReal(1);
3910  vp->MaxPrec = 1; /* set max precision */
3911  VpSetPosInf(vp);
3912  return vp;
3913  }
3914  if (StrCmp(szVal, SZ_NINF) == 0) {
3915  vp = VpAllocReal(1);
3916  vp->MaxPrec = 1; /* set max precision */
3917  VpSetNegInf(vp);
3918  return vp;
3919  }
3920  if (StrCmp(szVal, SZ_NaN) == 0) {
3921  vp = VpAllocReal(1);
3922  vp->MaxPrec = 1; /* set max precision */
3923  VpSetNaN(vp);
3924  return vp;
3925  }
3926 
3927  /* check on number szVal[] */
3928  ipn = i = 0;
3929  if (szVal[i] == '-') { sign=-1; ++i; }
3930  else if (szVal[i] == '+') ++i;
3931  /* Skip digits */
3932  ni = 0; /* digits in mantissa */
3933  while ((v = szVal[i]) != 0) {
3934  if (!ISDIGIT(v)) break;
3935  ++i;
3936  ++ni;
3937  }
3938  nf = 0;
3939  ipf = 0;
3940  ipe = 0;
3941  ne = 0;
3942  if (v) {
3943  /* other than digit nor \0 */
3944  if (szVal[i] == '.') { /* xxx. */
3945  ++i;
3946  ipf = i;
3947  while ((v = szVal[i]) != 0) { /* get fraction part. */
3948  if (!ISDIGIT(v)) break;
3949  ++i;
3950  ++nf;
3951  }
3952  }
3953  ipe = 0; /* Exponent */
3954 
3955  switch (szVal[i]) {
3956  case '\0':
3957  break;
3958  case 'e': case 'E':
3959  case 'd': case 'D':
3960  ++i;
3961  ipe = i;
3962  v = szVal[i];
3963  if ((v == '-') || (v == '+')) ++i;
3964  while ((v=szVal[i]) != 0) {
3965  if (!ISDIGIT(v)) break;
3966  ++i;
3967  ++ne;
3968  }
3969  break;
3970  default:
3971  break;
3972  }
3973  }
3974  nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */
3975  /* units for szVal[] */
3976  if (mx == 0) mx = 1;
3977  nalloc = Max(nalloc, mx);
3978  mx = nalloc;
3979  vp = VpAllocReal(mx);
3980  /* xmalloc() alway returns(or throw interruption) */
3981  vp->MaxPrec = mx; /* set max precision */
3982  VpSetZero(vp, sign);
3983  VpCtoV(vp, &szVal[ipn], ni, &szVal[ipf], nf, &szVal[ipe], ne);
3984  rb_str_resize(buf, 0);
3985  return vp;
3986 }
3987 
3988 /*
3989  * Assignment(c=a).
3990  * [Input]
3991  * a ... RHSV
3992  * isw ... switch for assignment.
3993  * c = a when isw > 0
3994  * c = -a when isw < 0
3995  * if c->MaxPrec < a->Prec,then round operation
3996  * will be performed.
3997  * [Output]
3998  * c ... LHSV
3999  */
4000 VP_EXPORT size_t
4001 VpAsgn(Real *c, Real *a, int isw)
4002 {
4003  size_t n;
4004  if (VpIsNaN(a)) {
4005  VpSetNaN(c);
4006  return 0;
4007  }
4008  if (VpIsInf(a)) {
4009  VpSetInf(c, isw * VpGetSign(a));
4010  return 0;
4011  }
4012 
4013  /* check if the RHS is zero */
4014  if (!VpIsZero(a)) {
4015  c->exponent = a->exponent; /* store exponent */
4016  VpSetSign(c, isw * VpGetSign(a)); /* set sign */
4017  n = (a->Prec < c->MaxPrec) ? (a->Prec) : (c->MaxPrec);
4018  c->Prec = n;
4019  memcpy(c->frac, a->frac, n * sizeof(BDIGIT));
4020  /* Needs round ? */
4021  if (isw != 10) {
4022  /* Not in ActiveRound */
4023  if(c->Prec < a->Prec) {
4024  VpInternalRound(c, n, (n>0) ? a->frac[n-1] : 0, a->frac[n]);
4025  }
4026  else {
4027  VpLimitRound(c,0);
4028  }
4029  }
4030  }
4031  else {
4032  /* The value of 'a' is zero. */
4033  VpSetZero(c, isw * VpGetSign(a));
4034  return 1;
4035  }
4036  return c->Prec * BASE_FIG;
4037 }
4038 
4039 /*
4040  * c = a + b when operation = 1 or 2
4041  * = a - b when operation = -1 or -2.
4042  * Returns number of significant digits of c
4043  */
4044 VP_EXPORT size_t
4045 VpAddSub(Real *c, Real *a, Real *b, int operation)
4046 {
4047  short sw, isw;
4048  Real *a_ptr, *b_ptr;
4049  size_t n, na, nb, i;
4050  BDIGIT mrv;
4051 
4052 #ifdef BIGDECIMAL_DEBUG
4053  if (gfDebug) {
4054  VPrint(stdout, "VpAddSub(enter) a=% \n", a);
4055  VPrint(stdout, " b=% \n", b);
4056  printf(" operation=%d\n", operation);
4057  }
4058 #endif /* BIGDECIMAL_DEBUG */
4059 
4060  if (!VpIsDefOP(c, a, b, (operation > 0) ? 1 : 2)) return 0; /* No significant digits */
4061 
4062  /* check if a or b is zero */
4063  if (VpIsZero(a)) {
4064  /* a is zero,then assign b to c */
4065  if (!VpIsZero(b)) {
4066  VpAsgn(c, b, operation);
4067  }
4068  else {
4069  /* Both a and b are zero. */
4070  if (VpGetSign(a) < 0 && operation * VpGetSign(b) < 0) {
4071  /* -0 -0 */
4072  VpSetZero(c, -1);
4073  }
4074  else {
4075  VpSetZero(c, 1);
4076  }
4077  return 1; /* 0: 1 significant digits */
4078  }
4079  return c->Prec * BASE_FIG;
4080  }
4081  if (VpIsZero(b)) {
4082  /* b is zero,then assign a to c. */
4083  VpAsgn(c, a, 1);
4084  return c->Prec*BASE_FIG;
4085  }
4086 
4087  if (operation < 0) sw = -1;
4088  else sw = 1;
4089 
4090  /* compare absolute value. As a result,|a_ptr|>=|b_ptr| */
4091  if (a->exponent > b->exponent) {
4092  a_ptr = a;
4093  b_ptr = b;
4094  } /* |a|>|b| */
4095  else if (a->exponent < b->exponent) {
4096  a_ptr = b;
4097  b_ptr = a;
4098  } /* |a|<|b| */
4099  else {
4100  /* Exponent part of a and b is the same,then compare fraction */
4101  /* part */
4102  na = a->Prec;
4103  nb = b->Prec;
4104  n = Min(na, nb);
4105  for (i=0; i < n; ++i) {
4106  if (a->frac[i] > b->frac[i]) {
4107  a_ptr = a;
4108  b_ptr = b;
4109  goto end_if;
4110  }
4111  else if (a->frac[i] < b->frac[i]) {
4112  a_ptr = b;
4113  b_ptr = a;
4114  goto end_if;
4115  }
4116  }
4117  if (na > nb) {
4118  a_ptr = a;
4119  b_ptr = b;
4120  goto end_if;
4121  }
4122  else if (na < nb) {
4123  a_ptr = b;
4124  b_ptr = a;
4125  goto end_if;
4126  }
4127  /* |a| == |b| */
4128  if (VpGetSign(a) + sw *VpGetSign(b) == 0) {
4129  VpSetZero(c, 1); /* abs(a)=abs(b) and operation = '-' */
4130  return c->Prec * BASE_FIG;
4131  }
4132  a_ptr = a;
4133  b_ptr = b;
4134  }
4135 
4136 end_if:
4137  isw = VpGetSign(a) + sw *VpGetSign(b);
4138  /*
4139  * isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1)
4140  * = 2 ...( 1)+( 1),( 1)-(-1)
4141  * =-2 ...(-1)+(-1),(-1)-( 1)
4142  * If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|)
4143  * else c =(Sign ofisw)(|a_ptr|+|b_ptr|)
4144  */
4145  if (isw) { /* addition */
4146  VpSetSign(c, 1);
4147  mrv = VpAddAbs(a_ptr, b_ptr, c);
4148  VpSetSign(c, isw / 2);
4149  }
4150  else { /* subtraction */
4151  VpSetSign(c, 1);
4152  mrv = VpSubAbs(a_ptr, b_ptr, c);
4153  if (a_ptr == a) {
4154  VpSetSign(c,VpGetSign(a));
4155  }
4156  else {
4157  VpSetSign(c, VpGetSign(a_ptr) * sw);
4158  }
4159  }
4160  VpInternalRound(c, 0, (c->Prec > 0) ? c->frac[c->Prec-1] : 0, mrv);
4161 
4162 #ifdef BIGDECIMAL_DEBUG
4163  if (gfDebug) {
4164  VPrint(stdout, "VpAddSub(result) c=% \n", c);
4165  VPrint(stdout, " a=% \n", a);
4166  VPrint(stdout, " b=% \n", b);
4167  printf(" operation=%d\n", operation);
4168  }
4169 #endif /* BIGDECIMAL_DEBUG */
4170  return c->Prec * BASE_FIG;
4171 }
4172 
4173 /*
4174  * Addition of two variable precisional variables
4175  * a and b assuming abs(a)>abs(b).
4176  * c = abs(a) + abs(b) ; where |a|>=|b|
4177  */
4178 static BDIGIT
4179 VpAddAbs(Real *a, Real *b, Real *c)
4180 {
4181  size_t word_shift;
4182  size_t ap;
4183  size_t bp;
4184  size_t cp;
4185  size_t a_pos;
4186  size_t b_pos, b_pos_with_word_shift;
4187  size_t c_pos;
4188  BDIGIT av, bv, carry, mrv;
4189 
4190 #ifdef BIGDECIMAL_DEBUG
4191  if (gfDebug) {
4192  VPrint(stdout, "VpAddAbs called: a = %\n", a);
4193  VPrint(stdout, " b = %\n", b);
4194  }
4195 #endif /* BIGDECIMAL_DEBUG */
4196 
4197  word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv);
4198  a_pos = ap;
4199  b_pos = bp;
4200  c_pos = cp;
4201 
4202  if (word_shift == (size_t)-1L) return 0; /* Overflow */
4203  if (b_pos == (size_t)-1L) goto Assign_a;
4204 
4205  mrv = av + bv; /* Most right val. Used for round. */
4206 
4207  /* Just assign the last few digits of b to c because a has no */
4208  /* corresponding digits to be added. */
4209  if (b_pos > 0) {
4210  while (b_pos > 0 && b_pos + word_shift > a_pos) {
4211  c->frac[--c_pos] = b->frac[--b_pos];
4212  }
4213  }
4214  if (b_pos == 0 && word_shift > a_pos) {
4215  while (word_shift-- > a_pos) {
4216  c->frac[--c_pos] = 0;
4217  }
4218  }
4219 
4220  /* Just assign the last few digits of a to c because b has no */
4221  /* corresponding digits to be added. */
4222  b_pos_with_word_shift = b_pos + word_shift;
4223  while (a_pos > b_pos_with_word_shift) {
4224  c->frac[--c_pos] = a->frac[--a_pos];
4225  }
4226  carry = 0; /* set first carry be zero */
4227 
4228  /* Now perform addition until every digits of b will be */
4229  /* exhausted. */
4230  while (b_pos > 0) {
4231  c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry;
4232  if (c->frac[c_pos] >= BASE) {
4233  c->frac[c_pos] -= BASE;
4234  carry = 1;
4235  }
4236  else {
4237  carry = 0;
4238  }
4239  }
4240 
4241  /* Just assign the first few digits of a with considering */
4242  /* the carry obtained so far because b has been exhausted. */
4243  while (a_pos > 0) {
4244  c->frac[--c_pos] = a->frac[--a_pos] + carry;
4245  if (c->frac[c_pos] >= BASE) {
4246  c->frac[c_pos] -= BASE;
4247  carry = 1;
4248  }
4249  else {
4250  carry = 0;
4251  }
4252  }
4253  if (c_pos) c->frac[c_pos - 1] += carry;
4254  goto Exit;
4255 
4256 Assign_a:
4257  VpAsgn(c, a, 1);
4258  mrv = 0;
4259 
4260 Exit:
4261 
4262 #ifdef BIGDECIMAL_DEBUG
4263  if (gfDebug) {
4264  VPrint(stdout, "VpAddAbs exit: c=% \n", c);
4265  }
4266 #endif /* BIGDECIMAL_DEBUG */
4267  return mrv;
4268 }
4269 
4270 /*
4271  * c = abs(a) - abs(b)
4272  */
4273 static BDIGIT
4274 VpSubAbs(Real *a, Real *b, Real *c)
4275 {
4276  size_t word_shift;
4277  size_t ap;
4278  size_t bp;
4279  size_t cp;
4280  size_t a_pos;
4281  size_t b_pos, b_pos_with_word_shift;
4282  size_t c_pos;
4283  BDIGIT av, bv, borrow, mrv;
4284 
4285 #ifdef BIGDECIMAL_DEBUG
4286  if (gfDebug) {
4287  VPrint(stdout, "VpSubAbs called: a = %\n", a);
4288  VPrint(stdout, " b = %\n", b);
4289  }
4290 #endif /* BIGDECIMAL_DEBUG */
4291 
4292  word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv);
4293  a_pos = ap;
4294  b_pos = bp;
4295  c_pos = cp;
4296  if (word_shift == (size_t)-1L) return 0; /* Overflow */
4297  if (b_pos == (size_t)-1L) goto Assign_a;
4298 
4299  if (av >= bv) {
4300  mrv = av - bv;
4301  borrow = 0;
4302  }
4303  else {
4304  mrv = 0;
4305  borrow = 1;
4306  }
4307 
4308  /* Just assign the values which are the BASE subtracted by */
4309  /* each of the last few digits of the b because the a has no */
4310  /* corresponding digits to be subtracted. */
4311  if (b_pos + word_shift > a_pos) {
4312  while (b_pos > 0 && b_pos + word_shift > a_pos) {
4313  c->frac[--c_pos] = BASE - b->frac[--b_pos] - borrow;
4314  borrow = 1;
4315  }
4316  if (b_pos == 0) {
4317  while (word_shift > a_pos) {
4318  --word_shift;
4319  c->frac[--c_pos] = BASE - borrow;
4320  borrow = 1;
4321  }
4322  }
4323  }
4324  /* Just assign the last few digits of a to c because b has no */
4325  /* corresponding digits to subtract. */
4326 
4327  b_pos_with_word_shift = b_pos + word_shift;
4328  while (a_pos > b_pos_with_word_shift) {
4329  c->frac[--c_pos] = a->frac[--a_pos];
4330  }
4331 
4332  /* Now perform subtraction until every digits of b will be */
4333  /* exhausted. */
4334  while (b_pos > 0) {
4335  --c_pos;
4336  if (a->frac[--a_pos] < b->frac[--b_pos] + borrow) {
4337  c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow;
4338  borrow = 1;
4339  }
4340  else {
4341  c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow;
4342  borrow = 0;
4343  }
4344  }
4345 
4346  /* Just assign the first few digits of a with considering */
4347  /* the borrow obtained so far because b has been exhausted. */
4348  while (a_pos > 0) {
4349  --c_pos;
4350  if (a->frac[--a_pos] < borrow) {
4351  c->frac[c_pos] = BASE + a->frac[a_pos] - borrow;
4352  borrow = 1;
4353  }
4354  else {
4355  c->frac[c_pos] = a->frac[a_pos] - borrow;
4356  borrow = 0;
4357  }
4358  }
4359  if (c_pos) c->frac[c_pos - 1] -= borrow;
4360  goto Exit;
4361 
4362 Assign_a:
4363  VpAsgn(c, a, 1);
4364  mrv = 0;
4365 
4366 Exit:
4367 #ifdef BIGDECIMAL_DEBUG
4368  if (gfDebug) {
4369  VPrint(stdout, "VpSubAbs exit: c=% \n", c);
4370  }
4371 #endif /* BIGDECIMAL_DEBUG */
4372  return mrv;
4373 }
4374 
4375 /*
4376  * Note: If(av+bv)>= HALF_BASE,then 1 will be added to the least significant
4377  * digit of c(In case of addition).
4378  * ------------------------- figure of output -----------------------------------
4379  * a = xxxxxxxxxxx
4380  * b = xxxxxxxxxx
4381  * c =xxxxxxxxxxxxxxx
4382  * word_shift = | |
4383  * right_word = | | (Total digits in RHSV)
4384  * left_word = | | (Total digits in LHSV)
4385  * a_pos = |
4386  * b_pos = |
4387  * c_pos = |
4388  */
4389 static size_t
4390 VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, BDIGIT *av, BDIGIT *bv)
4391 {
4392  size_t left_word, right_word, word_shift;
4393 
4394  size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG;
4395 
4396  assert(a->exponent >= b->expoennt);
4397 
4398  c->frac[0] = 0;
4399  *av = *bv = 0;
4400 
4401  word_shift = (a->exponent - b->exponent);
4402  left_word = b->Prec + word_shift;
4403  right_word = Max(a->Prec, left_word);
4404  left_word = c->MaxPrec - 1; /* -1 ... prepare for round up */
4405 
4406  /*
4407  * check if 'round' is needed.
4408  */
4409  if (right_word > left_word) { /* round ? */
4410  /*---------------------------------
4411  * Actual size of a = xxxxxxAxx
4412  * Actual size of b = xxxBxxxxx
4413  * Max. size of c = xxxxxx
4414  * Round off = |-----|
4415  * c_pos = |
4416  * right_word = |
4417  * a_pos = |
4418  */
4419  *c_pos = right_word = left_word + 1; /* Set resulting precision */
4420  /* be equal to that of c */
4421  if (a->Prec >= c->MaxPrec) {
4422  /*
4423  * a = xxxxxxAxxx
4424  * c = xxxxxx
4425  * a_pos = |
4426  */
4427  *a_pos = left_word;
4428  if (*a_pos <= round_limit) {
4429  *av = a->frac[*a_pos]; /* av is 'A' shown in above. */
4430  }
4431  }
4432  else {
4433  /*
4434  * a = xxxxxxx
4435  * c = xxxxxxxxxx
4436  * a_pos = |
4437  */
4438  *a_pos = a->Prec;
4439  }
4440  if (b->Prec + word_shift >= c->MaxPrec) {
4441  /*
4442  * a = xxxxxxxxx
4443  * b = xxxxxxxBxxx
4444  * c = xxxxxxxxxxx
4445  * b_pos = |
4446  */
4447  if (c->MaxPrec >= word_shift + 1) {
4448  *b_pos = c->MaxPrec - word_shift - 1;
4449  if (*b_pos + word_shift <= round_limit) {
4450  *bv = b->frac[*b_pos];
4451  }
4452  }
4453  else {
4454  *b_pos = -1L;
4455  }
4456  }
4457  else {
4458  /*
4459  * a = xxxxxxxxxxxxxxxx
4460  * b = xxxxxx
4461  * c = xxxxxxxxxxxxx
4462  * b_pos = |
4463  */
4464  *b_pos = b->Prec;
4465  }
4466  }
4467  else { /* The MaxPrec of c - 1 > The Prec of a + b */
4468  /*
4469  * a = xxxxxxx
4470  * b = xxxxxx
4471  * c = xxxxxxxxxxx
4472  * c_pos = |
4473  */
4474  *b_pos = b->Prec;
4475  *a_pos = a->Prec;
4476  *c_pos = right_word + 1;
4477  }
4478  c->Prec = *c_pos;
4479  c->exponent = a->exponent;
4480  if (!AddExponent(c, 1)) return (size_t)-1L;
4481  return word_shift;
4482 }
4483 
4484 /*
4485  * Return number of significant digits
4486  * c = a * b , Where a = a0a1a2 ... an
4487  * b = b0b1b2 ... bm
4488  * c = c0c1c2 ... cl
4489  * a0 a1 ... an * bm
4490  * a0 a1 ... an * bm-1
4491  * . . .
4492  * . . .
4493  * a0 a1 .... an * b0
4494  * +_____________________________
4495  * c0 c1 c2 ...... cl
4496  * nc <---|
4497  * MaxAB |--------------------|
4498  */
4499 VP_EXPORT size_t
4500 VpMult(Real *c, Real *a, Real *b)
4501 {
4502  size_t MxIndA, MxIndB, MxIndAB, MxIndC;
4503  size_t ind_c, i, ii, nc;
4504  size_t ind_as, ind_ae, ind_bs;
4505  BDIGIT carry;
4506  BDIGIT_DBL s;
4507  Real *w;
4508 
4509 #ifdef BIGDECIMAL_DEBUG
4510  if (gfDebug) {
4511  VPrint(stdout, "VpMult(Enter): a=% \n", a);
4512  VPrint(stdout, " b=% \n", b);
4513  }
4514 #endif /* BIGDECIMAL_DEBUG */
4515 
4516  if (!VpIsDefOP(c, a, b, 3)) return 0; /* No significant digit */
4517 
4518  if (VpIsZero(a) || VpIsZero(b)) {
4519  /* at least a or b is zero */
4520  VpSetZero(c, VpGetSign(a) * VpGetSign(b));
4521  return 1; /* 0: 1 significant digit */
4522  }
4523 
4524  if (VpIsOne(a)) {
4525  VpAsgn(c, b, VpGetSign(a));
4526  goto Exit;
4527  }
4528  if (VpIsOne(b)) {
4529  VpAsgn(c, a, VpGetSign(b));
4530  goto Exit;
4531  }
4532  if (b->Prec > a->Prec) {
4533  /* Adjust so that digits(a)>digits(b) */
4534  w = a;
4535  a = b;
4536  b = w;
4537  }
4538  w = NULL;
4539  MxIndA = a->Prec - 1;
4540  MxIndB = b->Prec - 1;
4541  MxIndC = c->MaxPrec - 1;
4542  MxIndAB = a->Prec + b->Prec - 1;
4543 
4544  if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */
4545  w = c;
4546  c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0");
4547  MxIndC = MxIndAB;
4548  }
4549 
4550  /* set LHSV c info */
4551 
4552  c->exponent = a->exponent; /* set exponent */
4553  if (!AddExponent(c, b->exponent)) {
4554  if (w) VpFree(c);
4555  return 0;
4556  }
4557  VpSetSign(c, VpGetSign(a) * VpGetSign(b)); /* set sign */
4558  carry = 0;
4559  nc = ind_c = MxIndAB;
4560  memset(c->frac, 0, (nc + 1) * sizeof(BDIGIT)); /* Initialize c */
4561  c->Prec = nc + 1; /* set precision */
4562  for (nc = 0; nc < MxIndAB; ++nc, --ind_c) {
4563  if (nc < MxIndB) { /* The left triangle of the Fig. */
4564  ind_as = MxIndA - nc;
4565  ind_ae = MxIndA;
4566  ind_bs = MxIndB;
4567  }
4568  else if (nc <= MxIndA) { /* The middle rectangular of the Fig. */
4569  ind_as = MxIndA - nc;
4570  ind_ae = MxIndA - (nc - MxIndB);
4571  ind_bs = MxIndB;
4572  }
4573  else /* if (nc > MxIndA) */ { /* The right triangle of the Fig. */
4574  ind_as = 0;
4575  ind_ae = MxIndAB - nc - 1;
4576  ind_bs = MxIndB - (nc - MxIndA);
4577  }
4578 
4579  for (i = ind_as; i <= ind_ae; ++i) {
4580  s = (BDIGIT_DBL)a->frac[i] * b->frac[ind_bs--];
4581  carry = (BDIGIT)(s / BASE);
4582  s -= (BDIGIT_DBL)carry * BASE;
4583  c->frac[ind_c] += (BDIGIT)s;
4584  if (c->frac[ind_c] >= BASE) {
4585  s = c->frac[ind_c] / BASE;
4586  carry += (BDIGIT)s;
4587  c->frac[ind_c] -= (BDIGIT)(s * BASE);
4588  }
4589  if (carry) {
4590  ii = ind_c;
4591  while (ii-- > 0) {
4592  c->frac[ii] += carry;
4593  if (c->frac[ii] >= BASE) {
4594  carry = c->frac[ii] / BASE;
4595  c->frac[ii] -= (carry * BASE);
4596  }
4597  else {
4598  break;
4599  }
4600  }
4601  }
4602  }
4603  }
4604  if (w != NULL) { /* free work variable */
4605  VpNmlz(c);
4606  VpAsgn(w, c, 1);
4607  VpFree(c);
4608  c = w;
4609  }
4610  else {
4611  VpLimitRound(c,0);
4612  }
4613 
4614 Exit:
4615 #ifdef BIGDECIMAL_DEBUG
4616  if (gfDebug) {
4617  VPrint(stdout, "VpMult(c=a*b): c=% \n", c);
4618  VPrint(stdout, " a=% \n", a);
4619  VPrint(stdout, " b=% \n", b);
4620  }
4621 #endif /*BIGDECIMAL_DEBUG */
4622  return c->Prec*BASE_FIG;
4623 }
4624 
4625 /*
4626  * c = a / b, remainder = r
4627  */
4628  VP_EXPORT size_t
4629 VpDivd(Real *c, Real *r, Real *a, Real *b)
4630 {
4631  size_t word_a, word_b, word_c, word_r;
4632  size_t i, n, ind_a, ind_b, ind_c, ind_r;
4633  size_t nLoop;
4634  BDIGIT_DBL q, b1, b1p1, b1b2, b1b2p1, r1r2;
4635  BDIGIT borrow, borrow1, borrow2;
4636  BDIGIT_DBL qb;
4637 
4638 #ifdef BIGDECIMAL_DEBUG
4639  if (gfDebug) {
4640  VPrint(stdout, " VpDivd(c=a/b) a=% \n", a);
4641  VPrint(stdout, " b=% \n", b);
4642  }
4643 #endif /*BIGDECIMAL_DEBUG */
4644 
4645  VpSetNaN(r);
4646  if (!VpIsDefOP(c, a, b, 4)) goto Exit;
4647  if (VpIsZero(a) && VpIsZero(b)) {
4648  VpSetNaN(c);
4649  return VpException(VP_EXCEPTION_NaN, "(VpDivd) 0/0 not defined(NaN)", 0);
4650  }
4651  if (VpIsZero(b)) {
4652  VpSetInf(c, VpGetSign(a) * VpGetSign(b));
4653  return VpException(VP_EXCEPTION_ZERODIVIDE, "(VpDivd) Divide by zero", 0);
4654  }
4655  if (VpIsZero(a)) {
4656  /* numerator a is zero */
4657  VpSetZero(c, VpGetSign(a) * VpGetSign(b));
4658  VpSetZero(r, VpGetSign(a) * VpGetSign(b));
4659  goto Exit;
4660  }
4661  if (VpIsOne(b)) {
4662  /* divide by one */
4663  VpAsgn(c, a, VpGetSign(b));
4664  VpSetZero(r, VpGetSign(a));
4665  goto Exit;
4666  }
4667 
4668  word_a = a->Prec;
4669  word_b = b->Prec;
4670  word_c = c->MaxPrec;
4671  word_r = r->MaxPrec;
4672 
4673  ind_c = 0;
4674  ind_r = 1;
4675 
4676  if (word_a >= word_r) goto space_error;
4677 
4678  r->frac[0] = 0;
4679  while (ind_r <= word_a) {
4680  r->frac[ind_r] = a->frac[ind_r - 1];
4681  ++ind_r;
4682  }
4683 
4684  while (ind_r < word_r) r->frac[ind_r++] = 0;
4685  while (ind_c < word_c) c->frac[ind_c++] = 0;
4686 
4687  /* initial procedure */
4688  b1 = b1p1 = b->frac[0];
4689  if (b->Prec <= 1) {
4690  b1b2p1 = b1b2 = b1p1 * BASE;
4691  }
4692  else {
4693  b1p1 = b1 + 1;
4694  b1b2p1 = b1b2 = b1 * BASE + b->frac[1];
4695  if (b->Prec > 2) ++b1b2p1;
4696  }
4697 
4698  /* */
4699  /* loop start */
4700  ind_c = word_r - 1;
4701  nLoop = Min(word_c,ind_c);
4702  ind_c = 1;
4703  while (ind_c < nLoop) {
4704  if (r->frac[ind_c] == 0) {
4705  ++ind_c;
4706  continue;
4707  }
4708  r1r2 = (BDIGIT_DBL)r->frac[ind_c] * BASE + r->frac[ind_c + 1];
4709  if (r1r2 == b1b2) {
4710  /* The first two word digits is the same */
4711  ind_b = 2;
4712  ind_a = ind_c + 2;
4713  while (ind_b < word_b) {
4714  if (r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1;
4715  if (r->frac[ind_a] > b->frac[ind_b]) break;
4716  ++ind_a;
4717  ++ind_b;
4718  }
4719  /* The first few word digits of r and b is the same and */
4720  /* the first different word digit of w is greater than that */
4721  /* of b, so quotient is 1 and just subtract b from r. */
4722  borrow = 0; /* quotient=1, then just r-b */
4723  ind_b = b->Prec - 1;
4724  ind_r = ind_c + ind_b;
4725  if (ind_r >= word_r) goto space_error;
4726  n = ind_b;
4727  for (i = 0; i <= n; ++i) {
4728  if (r->frac[ind_r] < b->frac[ind_b] + borrow) {
4729  r->frac[ind_r] += (BASE - (b->frac[ind_b] + borrow));
4730  borrow = 1;
4731  }
4732  else {
4733  r->frac[ind_r] = r->frac[ind_r] - b->frac[ind_b] - borrow;
4734  borrow = 0;
4735  }
4736  --ind_r;
4737  --ind_b;
4738  }
4739  ++c->frac[ind_c];
4740  goto carry;
4741  }
4742  /* The first two word digits is not the same, */
4743  /* then compare magnitude, and divide actually. */
4744  if (r1r2 >= b1b2p1) {
4745  q = r1r2 / b1b2p1; /* q == (BDIGIT)q */
4746  c->frac[ind_c] += (BDIGIT)q;
4747  ind_r = b->Prec + ind_c - 1;
4748  goto sub_mult;
4749  }
4750 
4751 div_b1p1:
4752  if (ind_c + 1 >= word_c) goto out_side;
4753  q = r1r2 / b1p1; /* q == (BDIGIT)q */
4754  c->frac[ind_c + 1] += (BDIGIT)q;
4755  ind_r = b->Prec + ind_c;
4756 
4757 sub_mult:
4758  borrow1 = borrow2 = 0;
4759  ind_b = word_b - 1;
4760  if (ind_r >= word_r) goto space_error;
4761  n = ind_b;
4762  for (i = 0; i <= n; ++i) {
4763  /* now, perform r = r - q * b */
4764  qb = q * b->frac[ind_b];
4765  if (qb < BASE) borrow1 = 0;
4766  else {
4767  borrow1 = (BDIGIT)(qb / BASE);
4768  qb -= (BDIGIT_DBL)borrow1 * BASE; /* get qb < BASE */
4769  }
4770  if(r->frac[ind_r] < qb) {
4771  r->frac[ind_r] += (BDIGIT)(BASE - qb);
4772  borrow2 = borrow2 + borrow1 + 1;
4773  }
4774  else {
4775  r->frac[ind_r] -= (BDIGIT)qb;
4776  borrow2 += borrow1;
4777  }
4778  if (borrow2) {
4779  if(r->frac[ind_r - 1] < borrow2) {
4780  r->frac[ind_r - 1] += (BASE - borrow2);
4781  borrow2 = 1;
4782  }
4783  else {
4784  r->frac[ind_r - 1] -= borrow2;
4785  borrow2 = 0;
4786  }
4787  }
4788  --ind_r;
4789  --ind_b;
4790  }
4791 
4792  r->frac[ind_r] -= borrow2;
4793 carry:
4794  ind_r = ind_c;
4795  while (c->frac[ind_r] >= BASE) {
4796  c->frac[ind_r] -= BASE;
4797  --ind_r;
4798  ++c->frac[ind_r];
4799  }
4800  }
4801  /* End of operation, now final arrangement */
4802 out_side:
4803  c->Prec = word_c;
4804  c->exponent = a->exponent;
4805  if (!AddExponent(c, 2)) return 0;
4806  if (!AddExponent(c, -(b->exponent))) return 0;
4807 
4808  VpSetSign(c, VpGetSign(a) * VpGetSign(b));
4809  VpNmlz(c); /* normalize c */
4810  r->Prec = word_r;
4811  r->exponent = a->exponent;
4812  if (!AddExponent(r, 1)) return 0;
4813  VpSetSign(r, VpGetSign(a));
4814  VpNmlz(r); /* normalize r(remainder) */
4815  goto Exit;
4816 
4817 space_error:
4818 #ifdef BIGDECIMAL_DEBUG
4819  if (gfDebug) {
4820  printf(" word_a=%lu\n", word_a);
4821  printf(" word_b=%lu\n", word_b);
4822  printf(" word_c=%lu\n", word_c);
4823  printf(" word_r=%lu\n", word_r);
4824  printf(" ind_r =%lu\n", ind_r);
4825  }
4826 #endif /* BIGDECIMAL_DEBUG */
4827  rb_bug("ERROR(VpDivd): space for remainder too small.");
4828 
4829 Exit:
4830 #ifdef BIGDECIMAL_DEBUG
4831  if (gfDebug) {
4832  VPrint(stdout, " VpDivd(c=a/b), c=% \n", c);
4833  VPrint(stdout, " r=% \n", r);
4834  }
4835 #endif /* BIGDECIMAL_DEBUG */
4836  return c->Prec * BASE_FIG;
4837 }
4838 
4839 /*
4840  * Input a = 00000xxxxxxxx En(5 preceding zeros)
4841  * Output a = xxxxxxxx En-5
4842  */
4843 static int
4845 {
4846  size_t ind_a, i;
4847 
4848  if (!VpIsDef(a)) goto NoVal;
4849  if (VpIsZero(a)) goto NoVal;
4850 
4851  ind_a = a->Prec;
4852  while (ind_a--) {
4853  if (a->frac[ind_a]) {
4854  a->Prec = ind_a + 1;
4855  i = 0;
4856  while (a->frac[i] == 0) ++i; /* skip the first few zeros */
4857  if (i) {
4858  a->Prec -= i;
4859  if (!AddExponent(a, -(SIGNED_VALUE)i)) return 0;
4860  memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(BDIGIT));
4861  }
4862  return 1;
4863  }
4864  }
4865  /* a is zero(no non-zero digit) */
4866  VpSetZero(a, VpGetSign(a));
4867  return 0;
4868 
4869 NoVal:
4870  a->frac[0] = 0;
4871  a->Prec = 1;
4872  return 0;
4873 }
4874 
4875 /*
4876  * VpComp = 0 ... if a=b,
4877  * Pos ... a>b,
4878  * Neg ... a<b.
4879  * 999 ... result undefined(NaN)
4880  */
4881 VP_EXPORT int
4883 {
4884  int val;
4885  size_t mx, ind;
4886  int e;
4887  val = 0;
4888  if (VpIsNaN(a) || VpIsNaN(b)) return 999;
4889  if (!VpIsDef(a)) {
4890  if (!VpIsDef(b)) e = a->sign - b->sign;
4891  else e = a->sign;
4892 
4893  if (e > 0) return 1;
4894  else if (e < 0) return -1;
4895  else return 0;
4896  }
4897  if (!VpIsDef(b)) {
4898  e = -b->sign;
4899  if (e > 0) return 1;
4900  else return -1;
4901  }
4902  /* Zero check */
4903  if (VpIsZero(a)) {
4904  if (VpIsZero(b)) return 0; /* both zero */
4905  val = -VpGetSign(b);
4906  goto Exit;
4907  }
4908  if (VpIsZero(b)) {
4909  val = VpGetSign(a);
4910  goto Exit;
4911  }
4912 
4913  /* compare sign */
4914  if (VpGetSign(a) > VpGetSign(b)) {
4915  val = 1; /* a>b */
4916  goto Exit;
4917  }
4918  if (VpGetSign(a) < VpGetSign(b)) {
4919  val = -1; /* a<b */
4920  goto Exit;
4921  }
4922 
4923  /* a and b have same sign, && sign!=0,then compare exponent */
4924  if (a->exponent > b->exponent) {
4925  val = VpGetSign(a);
4926  goto Exit;
4927  }
4928  if (a->exponent < b->exponent) {
4929  val = -VpGetSign(b);
4930  goto Exit;
4931  }
4932 
4933  /* a and b have same exponent, then compare significand. */
4934  mx = (a->Prec < b->Prec) ? a->Prec : b->Prec;
4935  ind = 0;
4936  while (ind < mx) {
4937  if (a->frac[ind] > b->frac[ind]) {
4938  val = VpGetSign(a);
4939  goto Exit;
4940  }
4941  if (a->frac[ind] < b->frac[ind]) {
4942  val = -VpGetSign(b);
4943  goto Exit;
4944  }
4945  ++ind;
4946  }
4947  if (a->Prec > b->Prec) {
4948  val = VpGetSign(a);
4949  }
4950  else if (a->Prec < b->Prec) {
4951  val = -VpGetSign(b);
4952  }
4953 
4954 Exit:
4955  if (val > 1) val = 1;
4956  else if (val < -1) val = -1;
4957 
4958 #ifdef BIGDECIMAL_DEBUG
4959  if (gfDebug) {
4960  VPrint(stdout, " VpComp a=%\n", a);
4961  VPrint(stdout, " b=%\n", b);
4962  printf(" ans=%d\n", val);
4963  }
4964 #endif /* BIGDECIMAL_DEBUG */
4965  return (int)val;
4966 }
4967 
4968 /*
4969  * cntl_chr ... ASCIIZ Character, print control characters
4970  * Available control codes:
4971  * % ... VP variable. To print '%', use '%%'.
4972  * \n ... new line
4973  * \b ... backspace
4974  * ... tab
4975  * Note: % must must not appear more than once
4976  * a ... VP variable to be printed
4977  */
4978 #ifdef BIGDECIMAL_ENABLE_VPRINT
4979 static int
4980 VPrint(FILE *fp, const char *cntl_chr, Real *a)
4981 {
4982  size_t i, j, nc, nd, ZeroSup, sep = 10;
4983  BDIGIT m, e, nn;
4984 
4985  /* Check if NaN & Inf. */
4986  if (VpIsNaN(a)) {
4987  fprintf(fp, SZ_NaN);
4988  return 8;
4989  }
4990  if (VpIsPosInf(a)) {
4991  fprintf(fp, SZ_INF);
4992  return 8;
4993  }
4994  if (VpIsNegInf(a)) {
4995  fprintf(fp, SZ_NINF);
4996  return 9;
4997  }
4998  if (VpIsZero(a)) {
4999  fprintf(fp, "0.0");
5000  return 3;
5001  }
5002 
5003  j = 0;
5004  nd = nc = 0; /* nd : number of digits in fraction part(every 10 digits, */
5005  /* nd<=10). */
5006  /* nc : number of characters printed */
5007  ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
5008  while (*(cntl_chr + j)) {
5009  if (*(cntl_chr + j) == '%' && *(cntl_chr + j + 1) != '%') {
5010  nc = 0;
5011  if (!VpIsZero(a)) {
5012  if (VpGetSign(a) < 0) {
5013  fprintf(fp, "-");
5014  ++nc;
5015  }
5016  nc += fprintf(fp, "0.");
5017  switch (*(cntl_chr + j + 1)) {
5018  default:
5019  break;
5020 
5021  case '0': case 'z':
5022  ZeroSup = 0;
5023  ++j;
5024  sep = cntl_chr[j] == 'z' ? RMPD_COMPONENT_FIGURES : 10;
5025  break;
5026  }
5027  for (i = 0; i < a->Prec; ++i) {
5028  m = BASE1;
5029  e = a->frac[i];
5030  while (m) {
5031  nn = e / m;
5032  if (!ZeroSup || nn) {
5033  nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */
5034  /* as 0.00xx will not */
5035  /* be printed. */
5036  ++nd;
5037  ZeroSup = 0; /* Set to print succeeding zeros */
5038  }
5039  if (nd >= sep) { /* print ' ' after every 10 digits */
5040  nd = 0;
5041  nc += fprintf(fp, " ");
5042  }
5043  e = e - nn * m;
5044  m /= 10;
5045  }
5046  }
5047  nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a));
5048  nc += fprintf(fp, " (%"PRIdVALUE", %lu, %lu)", a->exponent, a->Prec, a->MaxPrec);
5049  }
5050  else {
5051  nc += fprintf(fp, "0.0");
5052  }
5053  }
5054  else {
5055  ++nc;
5056  if (*(cntl_chr + j) == '\\') {
5057  switch (*(cntl_chr + j + 1)) {
5058  case 'n':
5059  fprintf(fp, "\n");
5060  ++j;
5061  break;
5062  case 't':
5063  fprintf(fp, "\t");
5064  ++j;
5065  break;
5066  case 'b':
5067  fprintf(fp, "\n");
5068  ++j;
5069  break;
5070  default:
5071  fprintf(fp, "%c", *(cntl_chr + j));
5072  break;
5073  }
5074  }
5075  else {
5076  fprintf(fp, "%c", *(cntl_chr + j));
5077  if (*(cntl_chr + j) == '%') ++j;
5078  }
5079  }
5080  j++;
5081  }
5082 
5083  return (int)nc;
5084 }
5085 #endif
5086 
5087 static void
5088 VpFormatSt(char *psz, size_t fFmt)
5089 {
5090  size_t ie, i, nf = 0;
5091  char ch;
5092 
5093  if (fFmt == 0) return;
5094 
5095  ie = strlen(psz);
5096  for (i = 0; i < ie; ++i) {
5097  ch = psz[i];
5098  if (!ch) break;
5099  if (ISSPACE(ch) || ch=='-' || ch=='+') continue;
5100  if (ch == '.') { nf = 0; continue; }
5101  if (ch == 'E') break;
5102 
5103  if (++nf > fFmt) {
5104  memmove(psz + i + 1, psz + i, ie - i + 1);
5105  ++ie;
5106  nf = 0;
5107  psz[i] = ' ';
5108  }
5109  }
5110 }
5111 
5112 VP_EXPORT ssize_t
5114 {
5115  ssize_t ex;
5116  size_t n;
5117 
5118  if (!VpHasVal(a)) return 0;
5119 
5120  ex = a->exponent * (ssize_t)BASE_FIG;
5121  n = BASE1;
5122  while ((a->frac[0] / n) == 0) {
5123  --ex;
5124  n /= 10;
5125  }
5126  return ex;
5127 }
5128 
5129 VP_EXPORT void
5130 VpSzMantissa(Real *a,char *psz)
5131 {
5132  size_t i, n, ZeroSup;
5133  BDIGIT_DBL m, e, nn;
5134 
5135  if (VpIsNaN(a)) {
5136  sprintf(psz, SZ_NaN);
5137  return;
5138  }
5139  if (VpIsPosInf(a)) {
5140  sprintf(psz, SZ_INF);
5141  return;
5142  }
5143  if (VpIsNegInf(a)) {
5144  sprintf(psz, SZ_NINF);
5145  return;
5146  }
5147 
5148  ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
5149  if (!VpIsZero(a)) {
5150  if (VpGetSign(a) < 0) *psz++ = '-';
5151  n = a->Prec;
5152  for (i = 0; i < n; ++i) {
5153  m = BASE1;
5154  e = a->frac[i];
5155  while (m) {
5156  nn = e / m;
5157  if (!ZeroSup || nn) {
5158  sprintf(psz, "%lu", (unsigned long)nn); /* The leading zero(s) */
5159  psz += strlen(psz);
5160  /* as 0.00xx will be ignored. */
5161  ZeroSup = 0; /* Set to print succeeding zeros */
5162  }
5163  e = e - nn * m;
5164  m /= 10;
5165  }
5166  }
5167  *psz = 0;
5168  while (psz[-1] == '0') *(--psz) = 0;
5169  }
5170  else {
5171  if (VpIsPosZero(a)) sprintf(psz, "0");
5172  else sprintf(psz, "-0");
5173  }
5174 }
5175 
5176 VP_EXPORT int
5177 VpToSpecialString(Real *a,char *psz,int fPlus)
5178  /* fPlus =0:default, =1: set ' ' before digits , =2: set '+' before digits. */
5179 {
5180  if (VpIsNaN(a)) {
5181  sprintf(psz,SZ_NaN);
5182  return 1;
5183  }
5184 
5185  if (VpIsPosInf(a)) {
5186  if (fPlus == 1) {
5187  *psz++ = ' ';
5188  }
5189  else if (fPlus == 2) {
5190  *psz++ = '+';
5191  }
5192  sprintf(psz, SZ_INF);
5193  return 1;
5194  }
5195  if (VpIsNegInf(a)) {
5196  sprintf(psz, SZ_NINF);
5197  return 1;
5198  }
5199  if (VpIsZero(a)) {
5200  if (VpIsPosZero(a)) {
5201  if (fPlus == 1) sprintf(psz, " 0.0");
5202  else if (fPlus == 2) sprintf(psz, "+0.0");
5203  else sprintf(psz, "0.0");
5204  }
5205  else sprintf(psz, "-0.0");
5206  return 1;
5207  }
5208  return 0;
5209 }
5210 
5211 VP_EXPORT void
5212 VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
5213 /* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */
5214 {
5215  size_t i, n, ZeroSup;
5216  BDIGIT shift, m, e, nn;
5217  char *pszSav = psz;
5218  ssize_t ex;
5219 
5220  if (VpToSpecialString(a, psz, fPlus)) return;
5221 
5222  ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
5223 
5224  if (VpGetSign(a) < 0) *psz++ = '-';
5225  else if (fPlus == 1) *psz++ = ' ';
5226  else if (fPlus == 2) *psz++ = '+';
5227 
5228  *psz++ = '0';
5229  *psz++ = '.';
5230  n = a->Prec;
5231  for (i = 0; i < n; ++i) {
5232  m = BASE1;
5233  e = a->frac[i];
5234  while (m) {
5235  nn = e / m;
5236  if (!ZeroSup || nn) {
5237  sprintf(psz, "%lu", (unsigned long)nn); /* The reading zero(s) */
5238  psz += strlen(psz);
5239  /* as 0.00xx will be ignored. */
5240  ZeroSup = 0; /* Set to print succeeding zeros */
5241  }
5242  e = e - nn * m;
5243  m /= 10;
5244  }
5245  }
5246  ex = a->exponent * (ssize_t)BASE_FIG;
5247  shift = BASE1;
5248  while (a->frac[0] / shift == 0) {
5249  --ex;
5250  shift /= 10;
5251  }
5252  while (psz[-1] == '0') {
5253  *(--psz) = 0;
5254  }
5255  sprintf(psz, "E%"PRIdSIZE, ex);
5256  if (fFmt) VpFormatSt(pszSav, fFmt);
5257 }
5258 
5259 VP_EXPORT void
5260 VpToFString(Real *a, char *psz, size_t fFmt, int fPlus)
5261 /* fPlus =0:default,=1: set ' ' before digits ,set '+' before digits. */
5262 {
5263  size_t i, n;
5264  BDIGIT m, e, nn;
5265  char *pszSav = psz;
5266  ssize_t ex;
5267 
5268  if (VpToSpecialString(a, psz, fPlus)) return;
5269 
5270  if (VpGetSign(a) < 0) *psz++ = '-';
5271  else if (fPlus == 1) *psz++ = ' ';
5272  else if (fPlus == 2) *psz++ = '+';
5273 
5274  n = a->Prec;
5275  ex = a->exponent;
5276  if (ex <= 0) {
5277  *psz++ = '0';*psz++ = '.';
5278  while (ex < 0) {
5279  for (i=0; i < BASE_FIG; ++i) *psz++ = '0';
5280  ++ex;
5281  }
5282  ex = -1;
5283  }
5284 
5285  for (i = 0; i < n; ++i) {
5286  --ex;
5287  if (i == 0 && ex >= 0) {
5288  sprintf(psz, "%lu", (unsigned long)a->frac[i]);
5289  psz += strlen(psz);
5290  }
5291  else {
5292  m = BASE1;
5293  e = a->frac[i];
5294  while (m) {
5295  nn = e / m;
5296  *psz++ = (char)(nn + '0');
5297  e = e - nn * m;
5298  m /= 10;
5299  }
5300  }
5301  if (ex == 0) *psz++ = '.';
5302  }
5303  while (--ex>=0) {
5304  m = BASE;
5305  while (m /= 10) *psz++ = '0';
5306  if (ex == 0) *psz++ = '.';
5307  }
5308  *psz = 0;
5309  while (psz[-1] == '0') *(--psz) = 0;
5310  if (psz[-1] == '.') sprintf(psz, "0");
5311  if (fFmt) VpFormatSt(pszSav, fFmt);
5312 }
5313 
5314 /*
5315  * [Output]
5316  * a[] ... variable to be assigned the value.
5317  * [Input]
5318  * int_chr[] ... integer part(may include '+/-').
5319  * ni ... number of characters in int_chr[],not including '+/-'.
5320  * frac[] ... fraction part.
5321  * nf ... number of characters in frac[].
5322  * exp_chr[] ... exponent part(including '+/-').
5323  * ne ... number of characters in exp_chr[],not including '+/-'.
5324  */
5325 VP_EXPORT int
5326 VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne)
5327 {
5328  size_t i, j, ind_a, ma, mi, me;
5329  SIGNED_VALUE e, es, eb, ef;
5330  int sign, signe, exponent_overflow;
5331 
5332  /* get exponent part */
5333  e = 0;
5334  ma = a->MaxPrec;
5335  mi = ni;
5336  me = ne;
5337  signe = 1;
5338  exponent_overflow = 0;
5339  memset(a->frac, 0, ma * sizeof(BDIGIT));
5340  if (ne > 0) {
5341  i = 0;
5342  if (exp_chr[0] == '-') {
5343  signe = -1;
5344  ++i;
5345  ++me;
5346  }
5347  else if (exp_chr[0] == '+') {
5348  ++i;
5349  ++me;
5350  }
5351  while (i < me) {
5353  es = e;
5354  goto exp_overflow;
5355  }
5356  es = e * (SIGNED_VALUE)BASE_FIG;
5357  if (MUL_OVERFLOW_SIGNED_VALUE_P(e, 10) ||
5358  SIGNED_VALUE_MAX - (exp_chr[i] - '0') < e * 10)
5359  goto exp_overflow;
5360  e = e * 10 + exp_chr[i] - '0';
5362  goto exp_overflow;
5363  if (es > (SIGNED_VALUE)(e * BASE_FIG)) {
5364  exp_overflow:
5365  exponent_overflow = 1;
5366  e = es; /* keep sign */
5367  break;
5368  }
5369  ++i;
5370  }
5371  }
5372 
5373  /* get integer part */
5374  i = 0;
5375  sign = 1;
5376  if (1 /*ni >= 0*/) {
5377  if (int_chr[0] == '-') {
5378  sign = -1;
5379  ++i;
5380  ++mi;
5381  }
5382  else if (int_chr[0] == '+') {
5383  ++i;
5384  ++mi;
5385  }
5386  }
5387 
5388  e = signe * e; /* e: The value of exponent part. */
5389  e = e + ni; /* set actual exponent size. */
5390 
5391  if (e > 0) signe = 1;
5392  else signe = -1;
5393 
5394  /* Adjust the exponent so that it is the multiple of BASE_FIG. */
5395  j = 0;
5396  ef = 1;
5397  while (ef) {
5398  if (e >= 0) eb = e;
5399  else eb = -e;
5400  ef = eb / (SIGNED_VALUE)BASE_FIG;
5401  ef = eb - ef * (SIGNED_VALUE)BASE_FIG;
5402  if (ef) {
5403  ++j; /* Means to add one more preceding zero */
5404  ++e;
5405  }
5406  }
5407 
5408  eb = e / (SIGNED_VALUE)BASE_FIG;
5409 
5410  if (exponent_overflow) {
5411  int zero = 1;
5412  for ( ; i < mi && zero; i++) zero = int_chr[i] == '0';
5413  for (i = 0; i < nf && zero; i++) zero = frac[i] == '0';
5414  if (!zero && signe > 0) {
5415  VpSetInf(a, sign);
5416  VpException(VP_EXCEPTION_INFINITY, "exponent overflow",0);
5417  }
5418  else VpSetZero(a, sign);
5419  return 1;
5420  }
5421 
5422  ind_a = 0;
5423  while (i < mi) {
5424  a->frac[ind_a] = 0;
5425  while (j < BASE_FIG && i < mi) {
5426  a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0';
5427  ++j;
5428  ++i;
5429  }
5430  if (i < mi) {
5431  ++ind_a;
5432  if (ind_a >= ma) goto over_flow;
5433  j = 0;
5434  }
5435  }
5436 
5437  /* get fraction part */
5438 
5439  i = 0;
5440  while (i < nf) {
5441  while (j < BASE_FIG && i < nf) {
5442  a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0';
5443  ++j;
5444  ++i;
5445  }
5446  if (i < nf) {
5447  ++ind_a;
5448  if (ind_a >= ma) goto over_flow;
5449  j = 0;
5450  }
5451  }
5452  goto Final;
5453 
5454 over_flow:
5455  rb_warn("Conversion from String to BigDecimal overflow (last few digits discarded).");
5456 
5457 Final:
5458  if (ind_a >= ma) ind_a = ma - 1;
5459  while (j < BASE_FIG) {
5460  a->frac[ind_a] = a->frac[ind_a] * 10;
5461  ++j;
5462  }
5463  a->Prec = ind_a + 1;
5464  a->exponent = eb;
5465  VpSetSign(a, sign);
5466  VpNmlz(a);
5467  return 1;
5468 }
5469 
5470 /*
5471  * [Input]
5472  * *m ... Real
5473  * [Output]
5474  * *d ... fraction part of m(d = 0.xxxxxxx). where # of 'x's is fig.
5475  * *e ... exponent of m.
5476  * DBLE_FIG ... Number of digits in a double variable.
5477  *
5478  * m -> d*10**e, 0<d<BASE
5479  * [Returns]
5480  * 0 ... Zero
5481  * 1 ... Normal
5482  * 2 ... Infinity
5483  * -1 ... NaN
5484  */
5485 VP_EXPORT int
5486 VpVtoD(double *d, SIGNED_VALUE *e, Real *m)
5487 {
5488  size_t ind_m, mm, fig;
5489  double div;
5490  int f = 1;
5491 
5492  if (VpIsNaN(m)) {
5493  *d = VpGetDoubleNaN();
5494  *e = 0;
5495  f = -1; /* NaN */
5496  goto Exit;
5497  }
5498  else if (VpIsPosZero(m)) {
5499  *d = 0.0;
5500  *e = 0;
5501  f = 0;
5502  goto Exit;
5503  }
5504  else if (VpIsNegZero(m)) {
5505  *d = VpGetDoubleNegZero();
5506  *e = 0;
5507  f = 0;
5508  goto Exit;
5509  }
5510  else if (VpIsPosInf(m)) {
5511  *d = VpGetDoublePosInf();
5512  *e = 0;
5513  f = 2;
5514  goto Exit;
5515  }
5516  else if (VpIsNegInf(m)) {
5517  *d = VpGetDoubleNegInf();
5518  *e = 0;
5519  f = 2;
5520  goto Exit;
5521  }
5522  /* Normal number */
5523  fig = (DBLE_FIG + BASE_FIG - 1) / BASE_FIG;
5524  ind_m = 0;
5525  mm = Min(fig, m->Prec);
5526  *d = 0.0;
5527  div = 1.;
5528  while (ind_m < mm) {
5529  div /= (double)BASE;
5530  *d = *d + (double)m->frac[ind_m++] * div;
5531  }
5532  *e = m->exponent * (SIGNED_VALUE)BASE_FIG;
5533  *d *= VpGetSign(m);
5534 
5535 Exit:
5536 #ifdef BIGDECIMAL_DEBUG
5537  if (gfDebug) {
5538  VPrint(stdout, " VpVtoD: m=%\n", m);
5539  printf(" d=%e * 10 **%ld\n", *d, *e);
5540  printf(" DBLE_FIG = %d\n", DBLE_FIG);
5541  }
5542 #endif /*BIGDECIMAL_DEBUG */
5543  return f;
5544 }
5545 
5546 /*
5547  * m <- d
5548  */
5549 VP_EXPORT void
5550 VpDtoV(Real *m, double d)
5551 {
5552  size_t ind_m, mm;
5553  SIGNED_VALUE ne;
5554  BDIGIT i;
5555  double val, val2;
5556 
5557  if (isnan(d)) {
5558  VpSetNaN(m);
5559  goto Exit;
5560  }
5561  if (isinf(d)) {
5562  if (d > 0.0) VpSetPosInf(m);
5563  else VpSetNegInf(m);
5564  goto Exit;
5565  }
5566 
5567  if (d == 0.0) {
5568  VpSetZero(m, 1);
5569  goto Exit;
5570  }
5571  val = (d > 0.) ? d : -d;
5572  ne = 0;
5573  if (val >= 1.0) {
5574  while (val >= 1.0) {
5575  val /= (double)BASE;
5576  ++ne;
5577  }
5578  }
5579  else {
5580  val2 = 1.0 / (double)BASE;
5581  while (val < val2) {
5582  val *= (double)BASE;
5583  --ne;
5584  }
5585  }
5586  /* Now val = 0.xxxxx*BASE**ne */
5587 
5588  mm = m->MaxPrec;
5589  memset(m->frac, 0, mm * sizeof(BDIGIT));
5590  for (ind_m = 0; val > 0.0 && ind_m < mm; ind_m++) {
5591  val *= (double)BASE;
5592  i = (BDIGIT)val;
5593  val -= (double)i;
5594  m->frac[ind_m] = i;
5595  }
5596  if (ind_m >= mm) ind_m = mm - 1;
5597  VpSetSign(m, (d > 0.0) ? 1 : -1);
5598  m->Prec = ind_m + 1;
5599  m->exponent = ne;
5600 
5601  VpInternalRound(m, 0, (m->Prec > 0) ? m->frac[m->Prec-1] : 0,
5602  (BDIGIT)(val*(double)BASE));
5603 
5604 Exit:
5605 #ifdef BIGDECIMAL_DEBUG
5606  if (gfDebug) {
5607  printf("VpDtoV d=%30.30e\n", d);
5608  VPrint(stdout, " m=%\n", m);
5609  }
5610 #endif /* BIGDECIMAL_DEBUG */
5611  return;
5612 }
5613 
5614 /*
5615  * m <- ival
5616  */
5617 #if 0 /* unused */
5618 VP_EXPORT void
5619 VpItoV(Real *m, SIGNED_VALUE ival)
5620 {
5621  size_t mm, ind_m;
5622  size_t val, v1, v2, v;
5623  int isign;
5624  SIGNED_VALUE ne;
5625 
5626  if (ival == 0) {
5627  VpSetZero(m, 1);
5628  goto Exit;
5629  }
5630  isign = 1;
5631  val = ival;
5632  if (ival < 0) {
5633  isign = -1;
5634  val =(size_t)(-ival);
5635  }
5636  ne = 0;
5637  ind_m = 0;
5638  mm = m->MaxPrec;
5639  while (ind_m < mm) {
5640  m->frac[ind_m] = 0;
5641  ++ind_m;
5642  }
5643  ind_m = 0;
5644  while (val > 0) {
5645  if (val) {
5646  v1 = val;
5647  v2 = 1;
5648  while (v1 >= BASE) {
5649  v1 /= BASE;
5650  v2 *= BASE;
5651  }
5652  val = val - v2 * v1;
5653  v = v1;
5654  }
5655  else {
5656  v = 0;
5657  }
5658  m->frac[ind_m] = v;
5659  ++ind_m;
5660  ++ne;
5661  }
5662  m->Prec = ind_m - 1;
5663  m->exponent = ne;
5664  VpSetSign(m, isign);
5665  VpNmlz(m);
5666 
5667 Exit:
5668 #ifdef BIGDECIMAL_DEBUG
5669  if (gfDebug) {
5670  printf(" VpItoV i=%d\n", ival);
5671  VPrint(stdout, " m=%\n", m);
5672  }
5673 #endif /* BIGDECIMAL_DEBUG */
5674  return;
5675 }
5676 #endif
5677 
5678 /*
5679  * y = SQRT(x), y*y - x =>0
5680  */
5681 VP_EXPORT int
5683 {
5684  Real *f = NULL;
5685  Real *r = NULL;
5686  size_t y_prec;
5687  SIGNED_VALUE n, e;
5688  SIGNED_VALUE prec;
5689  ssize_t nr;
5690  double val;
5691 
5692  /* Zero, NaN or Infinity ? */
5693  if (!VpHasVal(x)) {
5694  if (VpIsZero(x) || VpGetSign(x) > 0) {
5695  VpAsgn(y,x,1);
5696  goto Exit;
5697  }
5698  VpSetNaN(y);
5699  return VpException(VP_EXCEPTION_OP, "(VpSqrt) SQRT(NaN or negative value)", 0);
5700  goto Exit;
5701  }
5702 
5703  /* Negative ? */
5704  if (VpGetSign(x) < 0) {
5705  VpSetNaN(y);
5706  return VpException(VP_EXCEPTION_OP, "(VpSqrt) SQRT(negative value)", 0);
5707  }
5708 
5709  /* One ? */
5710  if (VpIsOne(x)) {
5711  VpSetOne(y);
5712  goto Exit;
5713  }
5714 
5715  n = (SIGNED_VALUE)y->MaxPrec;
5716  if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec;
5717 
5718  /* allocate temporally variables */
5719  f = VpAlloc(y->MaxPrec * (BASE_FIG + 2), "#1");
5720  r = VpAlloc((n + n) * (BASE_FIG + 2), "#1");
5721 
5722  nr = 0;
5723  y_prec = y->MaxPrec;
5724 
5725  prec = x->exponent - (ssize_t)y_prec;
5726  if (x->exponent > 0)
5727  ++prec;
5728  else
5729  --prec;
5730 
5731  VpVtoD(&val, &e, x); /* val <- x */
5732  e /= (SIGNED_VALUE)BASE_FIG;
5733  n = e / 2;
5734  if (e - n * 2 != 0) {
5735  val /= BASE;
5736  n = (e + 1) / 2;
5737  }
5738  VpDtoV(y, sqrt(val)); /* y <- sqrt(val) */
5739  y->exponent += n;
5740  n = (SIGNED_VALUE)((DBLE_FIG + BASE_FIG - 1) / BASE_FIG);
5741  y->MaxPrec = Min((size_t)n , y_prec);
5742  f->MaxPrec = y->MaxPrec + 1;
5743  n = (SIGNED_VALUE)(y_prec * BASE_FIG);
5744  if (n < (SIGNED_VALUE)maxnr) n = (SIGNED_VALUE)maxnr;
5745  do {
5746  y->MaxPrec *= 2;
5747  if (y->MaxPrec > y_prec) y->MaxPrec = y_prec;
5748  f->MaxPrec = y->MaxPrec;
5749  VpDivd(f, r, x, y); /* f = x/y */
5750  VpAddSub(r, f, y, -1); /* r = f - y */
5751  VpMult(f, VpPt5, r); /* f = 0.5*r */
5752  if (VpIsZero(f)) goto converge;
5753  VpAddSub(r, f, y, 1); /* r = y + f */
5754  VpAsgn(y, r, 1); /* y = r */
5755  } while (++nr < n);
5756 
5757 #ifdef BIGDECIMAL_DEBUG
5758  if (gfDebug) {
5759  printf("ERROR(VpSqrt): did not converge within %ld iterations.\n", nr);
5760  }
5761 #endif /* BIGDECIMAL_DEBUG */
5762  y->MaxPrec = y_prec;
5763 
5764 converge:
5765  VpChangeSign(y, 1);
5766 #ifdef BIGDECIMAL_DEBUG
5767  if (gfDebug) {
5768  VpMult(r, y, y);
5769  VpAddSub(f, x, r, -1);
5770  printf("VpSqrt: iterations = %"PRIdSIZE"\n", nr);
5771  VPrint(stdout, " y =% \n", y);
5772  VPrint(stdout, " x =% \n", x);
5773  VPrint(stdout, " x-y*y = % \n", f);
5774  }
5775 #endif /* BIGDECIMAL_DEBUG */
5776  y->MaxPrec = y_prec;
5777 
5778 Exit:
5779  VpFree(f);
5780  VpFree(r);
5781  return 1;
5782 }
5783 
5784 /*
5785  *
5786  * nf: digit position for operation.
5787  *
5788  */
5789 VP_EXPORT int
5790 VpMidRound(Real *y, unsigned short f, ssize_t nf)
5791 /*
5792  * Round relatively from the decimal point.
5793  * f: rounding mode
5794  * nf: digit location to round from the decimal point.
5795  */
5796 {
5797  /* fracf: any positive digit under rounding position? */
5798  /* fracf_1further: any positive digits under one further than the rounding position? */
5799  /* exptoadd: number of digits needed to compensate negative nf */
5800  int fracf, fracf_1further;
5801  ssize_t n,i,ix,ioffset, exptoadd;
5802  BDIGIT v, shifter;
5803  BDIGIT div;
5804 
5805  nf += y->exponent * (ssize_t)BASE_FIG;
5806  exptoadd=0;
5807  if (nf < 0) {
5808  /* rounding position too left(large). */
5809  if (f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) {
5810  VpSetZero(y, VpGetSign(y)); /* truncate everything */
5811  return 0;
5812  }
5813  exptoadd = -nf;
5814  nf = 0;
5815  }
5816 
5817  ix = nf / (ssize_t)BASE_FIG;
5818  if ((size_t)ix >= y->Prec) return 0; /* rounding position too right(small). */
5819  v = y->frac[ix];
5820 
5821  ioffset = nf - ix*(ssize_t)BASE_FIG;
5822  n = (ssize_t)BASE_FIG - ioffset - 1;
5823  for (shifter = 1, i = 0; i < n; ++i) shifter *= 10;
5824 
5825  /* so the representation used (in y->frac) is an array of BDIGIT, where
5826  each BDIGIT contains a value between 0 and BASE-1, consisting of BASE_FIG
5827  decimal places.
5828 
5829  (that numbers of decimal places are typed as ssize_t is somewhat confusing)
5830 
5831  nf is now position (in decimal places) of the digit from the start of
5832  the array.
5833 
5834  ix is the position (in BDIGITS) of the BDIGIT containing the decimal digit,
5835  from the start of the array.
5836 
5837  v is the value of this BDIGIT
5838 
5839  ioffset is the number of extra decimal places along of this decimal digit
5840  within v.
5841 
5842  n is the number of decimal digits remaining within v after this decimal digit
5843  shifter is 10**n,
5844 
5845  v % shifter are the remaining digits within v
5846  v % (shifter * 10) are the digit together with the remaining digits within v
5847  v / shifter are the digit's predecessors together with the digit
5848  div = v / shifter / 10 is just the digit's precessors
5849  (v / shifter) - div*10 is just the digit, which is what v ends up being reassigned to.
5850  */
5851 
5852  fracf = (v % (shifter * 10) > 0);
5853  fracf_1further = ((v % shifter) > 0);
5854 
5855  v /= shifter;
5856  div = v / 10;
5857  v = v - div*10;
5858  /* now v is just the digit required.
5859  now fracf is whether the digit or any of the remaining digits within v are non-zero
5860  now fracf_1further is whether any of the remaining digits within v are non-zero
5861  */
5862 
5863  /* now check all the remaining BDIGITS for zero-ness a whole BDIGIT at a time.
5864  if we spot any non-zeroness, that means that we found a positive digit under
5865  rounding position, and we also found a positive digit under one further than
5866  the rounding position, so both searches (to see if any such non-zero digit exists)
5867  can stop */
5868 
5869  for (i = ix + 1; (size_t)i < y->Prec; i++) {
5870  if (y->frac[i] % BASE) {
5871  fracf = fracf_1further = 1;
5872  break;
5873  }
5874  }
5875 
5876  /* now fracf = does any positive digit exist under the rounding position?
5877  now fracf_1further = does any positive digit exist under one further than the
5878  rounding position?
5879  now v = the first digit under the rounding position */
5880 
5881  /* drop digits after pointed digit */
5882  memset(y->frac + ix + 1, 0, (y->Prec - (ix + 1)) * sizeof(BDIGIT));
5883 
5884  switch (f) {
5885  case VP_ROUND_DOWN: /* Truncate */
5886  break;
5887  case VP_ROUND_UP: /* Roundup */
5888  if (fracf) ++div;
5889  break;
5890  case VP_ROUND_HALF_UP:
5891  if (v>=5) ++div;
5892  break;
5893  case VP_ROUND_HALF_DOWN:
5894  if (v > 5 || (v == 5 && fracf_1further)) ++div;
5895  break;
5896  case VP_ROUND_CEIL:
5897  if (fracf && (VpGetSign(y) > 0)) ++div;
5898  break;
5899  case VP_ROUND_FLOOR:
5900  if (fracf && (VpGetSign(y) < 0)) ++div;
5901  break;
5902  case VP_ROUND_HALF_EVEN: /* Banker's rounding */
5903  if (v > 5) ++div;
5904  else if (v == 5) {
5905  if (fracf_1further) {
5906  ++div;
5907  }
5908  else {
5909  if (ioffset == 0) {
5910  /* v is the first decimal digit of its BDIGIT;
5911  need to grab the previous BDIGIT if present
5912  to check for evenness of the previous decimal
5913  digit (which is same as that of the BDIGIT since
5914  base 10 has a factor of 2) */
5915  if (ix && (y->frac[ix-1] % 2)) ++div;
5916  }
5917  else {
5918  if (div % 2) ++div;
5919  }
5920  }
5921  }
5922  break;
5923  }
5924  for (i = 0; i <= n; ++i) div *= 10;
5925  if (div >= BASE) {
5926  if (ix) {
5927  y->frac[ix] = 0;
5928  VpRdup(y, ix);
5929  }
5930  else {
5931  short s = VpGetSign(y);
5932  SIGNED_VALUE e = y->exponent;
5933  VpSetOne(y);
5934  VpSetSign(y, s);
5935  y->exponent = e + 1;
5936  }
5937  }
5938  else {
5939  y->frac[ix] = div;
5940  VpNmlz(y);
5941  }
5942  if (exptoadd > 0) {
5943  y->exponent += (SIGNED_VALUE)(exptoadd / BASE_FIG);
5944  exptoadd %= (ssize_t)BASE_FIG;
5945  for (i = 0; i < exptoadd; i++) {
5946  y->frac[0] *= 10;
5947  if (y->frac[0] >= BASE) {
5948  y->frac[0] /= BASE;
5949  y->exponent++;
5950  }
5951  }
5952  }
5953  return 1;
5954 }
5955 
5956 VP_EXPORT int
5957 VpLeftRound(Real *y, unsigned short f, ssize_t nf)
5958 /*
5959  * Round from the left hand side of the digits.
5960  */
5961 {
5962  BDIGIT v;
5963  if (!VpHasVal(y)) return 0; /* Unable to round */
5964  v = y->frac[0];
5965  nf -= VpExponent(y) * (ssize_t)BASE_FIG;
5966  while ((v /= 10) != 0) nf--;
5967  nf += (ssize_t)BASE_FIG-1;
5968  return VpMidRound(y, f, nf);
5969 }
5970 
5971 VP_EXPORT int
5972 VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf)
5973 {
5974  /* First,assign whole value in truncation mode */
5975  if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */
5976  return VpMidRound(y, f, nf);
5977 }
5978 
5979 static int
5980 VpLimitRound(Real *c, size_t ixDigit)
5981 {
5982  size_t ix = VpGetPrecLimit();
5983  if (!VpNmlz(c)) return -1;
5984  if (!ix) return 0;
5985  if (!ixDigit) ixDigit = c->Prec-1;
5986  if ((ix + BASE_FIG - 1) / BASE_FIG > ixDigit + 1) return 0;
5987  return VpLeftRound(c, VpGetRoundMode(), (ssize_t)ix);
5988 }
5989 
5990 /* If I understand correctly, this is only ever used to round off the final decimal
5991  digit of precision */
5992 static void
5993 VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v)
5994 {
5995  int f = 0;
5996 
5997  unsigned short const rounding_mode = VpGetRoundMode();
5998 
5999  if (VpLimitRound(c, ixDigit)) return;
6000  if (!v) return;
6001 
6002  v /= BASE1;
6003  switch (rounding_mode) {
6004  case VP_ROUND_DOWN:
6005  break;
6006  case VP_ROUND_UP:
6007  if (v) f = 1;
6008  break;
6009  case VP_ROUND_HALF_UP:
6010  if (v >= 5) f = 1;
6011  break;
6012  case VP_ROUND_HALF_DOWN:
6013  /* this is ok - because this is the last digit of precision,
6014  the case where v == 5 and some further digits are nonzero
6015  will never occur */
6016  if (v >= 6) f = 1;
6017  break;
6018  case VP_ROUND_CEIL:
6019  if (v && (VpGetSign(c) > 0)) f = 1;
6020  break;
6021  case VP_ROUND_FLOOR:
6022  if (v && (VpGetSign(c) < 0)) f = 1;
6023  break;
6024  case VP_ROUND_HALF_EVEN: /* Banker's rounding */
6025  /* as per VP_ROUND_HALF_DOWN, because this is the last digit of precision,
6026  there is no case to worry about where v == 5 and some further digits are nonzero */
6027  if (v > 5) f = 1;
6028  else if (v == 5 && vPrev % 2) f = 1;
6029  break;
6030  }
6031  if (f) {
6032  VpRdup(c, ixDigit);
6033  VpNmlz(c);
6034  }
6035 }
6036 
6037 /*
6038  * Rounds up m(plus one to final digit of m).
6039  */
6040 static int
6041 VpRdup(Real *m, size_t ind_m)
6042 {
6043  BDIGIT carry;
6044 
6045  if (!ind_m) ind_m = m->Prec;
6046 
6047  carry = 1;
6048  while (carry > 0 && ind_m--) {
6049  m->frac[ind_m] += carry;
6050  if (m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE;
6051  else carry = 0;
6052  }
6053  if (carry > 0) { /* Overflow,count exponent and set fraction part be 1 */
6054  if (!AddExponent(m, 1)) return 0;
6055  m->Prec = m->frac[0] = 1;
6056  }
6057  else {
6058  VpNmlz(m);
6059  }
6060  return 1;
6061 }
6062 
6063 /*
6064  * y = x - fix(x)
6065  */
6066 VP_EXPORT void
6068 {
6069  size_t my, ind_y, ind_x;
6070 
6071  if (!VpHasVal(x)) {
6072  VpAsgn(y, x, 1);
6073  goto Exit;
6074  }
6075 
6076  if (x->exponent > 0 && (size_t)x->exponent >= x->Prec) {
6077  VpSetZero(y, VpGetSign(x));
6078  goto Exit;
6079  }
6080  else if (x->exponent <= 0) {
6081  VpAsgn(y, x, 1);
6082  goto Exit;
6083  }
6084 
6085  /* satisfy: x->exponent > 0 */
6086 
6087  y->Prec = x->Prec - (size_t)x->exponent;
6088  y->Prec = Min(y->Prec, y->MaxPrec);
6089  y->exponent = 0;
6090  VpSetSign(y, VpGetSign(x));
6091  ind_y = 0;
6092  my = y->Prec;
6093  ind_x = x->exponent;
6094  while (ind_y < my) {
6095  y->frac[ind_y] = x->frac[ind_x];
6096  ++ind_y;
6097  ++ind_x;
6098  }
6099  VpNmlz(y);
6100 
6101 Exit:
6102 #ifdef BIGDECIMAL_DEBUG
6103  if (gfDebug) {
6104  VPrint(stdout, "VpFrac y=%\n", y);
6105  VPrint(stdout, " x=%\n", x);
6106  }
6107 #endif /* BIGDECIMAL_DEBUG */
6108  return;
6109 }
6110 
6111 /*
6112  * y = x ** n
6113  */
6114 VP_EXPORT int
6116 {
6117  size_t s, ss;
6118  ssize_t sign;
6119  Real *w1 = NULL;
6120  Real *w2 = NULL;
6121 
6122  if (VpIsZero(x)) {
6123  if (n == 0) {
6124  VpSetOne(y);
6125  goto Exit;
6126  }
6127  sign = VpGetSign(x);
6128  if (n < 0) {
6129  n = -n;
6130  if (sign < 0) sign = (n % 2) ? -1 : 1;
6131  VpSetInf(y, sign);
6132  }
6133  else {
6134  if (sign < 0) sign = (n % 2) ? -1 : 1;
6135  VpSetZero(y,sign);
6136  }
6137  goto Exit;
6138  }
6139  if (VpIsNaN(x)) {
6140  VpSetNaN(y);
6141  goto Exit;
6142  }
6143  if (VpIsInf(x)) {
6144  if (n == 0) {
6145  VpSetOne(y);
6146  goto Exit;
6147  }
6148  if (n > 0) {
6149  VpSetInf(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1);
6150  goto Exit;
6151  }
6152  VpSetZero(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1);
6153  goto Exit;
6154  }
6155 
6156  if (x->exponent == 1 && x->Prec == 1 && x->frac[0] == 1) {
6157  /* abs(x) = 1 */
6158  VpSetOne(y);
6159  if (VpGetSign(x) > 0) goto Exit;
6160  if ((n % 2) == 0) goto Exit;
6161  VpSetSign(y, -1);
6162  goto Exit;
6163  }
6164 
6165  if (n > 0) sign = 1;
6166  else if (n < 0) {
6167  sign = -1;
6168  n = -n;
6169  }
6170  else {
6171  VpSetOne(y);
6172  goto Exit;
6173  }
6174 
6175  /* Allocate working variables */
6176 
6177  w1 = VpAlloc((y->MaxPrec + 2) * BASE_FIG, "#0");
6178  w2 = VpAlloc((w1->MaxPrec * 2 + 1) * BASE_FIG, "#0");
6179  /* calculation start */
6180 
6181  VpAsgn(y, x, 1);
6182  --n;
6183  while (n > 0) {
6184  VpAsgn(w1, x, 1);
6185  s = 1;
6186  while (ss = s, (s += s) <= (size_t)n) {
6187  VpMult(w2, w1, w1);
6188  VpAsgn(w1, w2, 1);
6189  }
6190  n -= (SIGNED_VALUE)ss;
6191  VpMult(w2, y, w1);
6192  VpAsgn(y, w2, 1);
6193  }
6194  if (sign < 0) {
6195  VpDivd(w1, w2, VpConstOne, y);
6196  VpAsgn(y, w1, 1);
6197  }
6198 
6199 Exit:
6200 #ifdef BIGDECIMAL_DEBUG
6201  if (gfDebug) {
6202  VPrint(stdout, "VpPower y=%\n", y);
6203  VPrint(stdout, "VpPower x=%\n", x);
6204  printf(" n=%d\n", n);
6205  }
6206 #endif /* BIGDECIMAL_DEBUG */
6207  VpFree(w2);
6208  VpFree(w1);
6209  return 1;
6210 }
6211 
6212 #ifdef BIGDECIMAL_DEBUG
6213 int
6214 VpVarCheck(Real * v)
6215 /*
6216  * Checks the validity of the Real variable v.
6217  * [Input]
6218  * v ... Real *, variable to be checked.
6219  * [Returns]
6220  * 0 ... correct v.
6221  * other ... error
6222  */
6223 {
6224  size_t i;
6225 
6226  if (v->MaxPrec == 0) {
6227  printf("ERROR(VpVarCheck): Illegal Max. Precision(=%"PRIuSIZE")\n",
6228  v->MaxPrec);
6229  return 1;
6230  }
6231  if (v->Prec == 0 || v->Prec > v->MaxPrec) {
6232  printf("ERROR(VpVarCheck): Illegal Precision(=%"PRIuSIZE")\n", v->Prec);
6233  printf(" Max. Prec.=%"PRIuSIZE"\n", v->MaxPrec);
6234  return 2;
6235  }
6236  for (i = 0; i < v->Prec; ++i) {
6237  if (v->frac[i] >= BASE) {
6238  printf("ERROR(VpVarCheck): Illegal fraction\n");
6239  printf(" Frac[%"PRIuSIZE"]=%lu\n", i, v->frac[i]);
6240  printf(" Prec. =%"PRIuSIZE"\n", v->Prec);
6241  printf(" Exp. =%"PRIdVALUE"\n", v->exponent);
6242  printf(" BASE =%lu\n", BASE);
6243  return 3;
6244  }
6245  }
6246  return 0;
6247 }
6248 #endif /* BIGDECIMAL_DEBUG */
VP_EXPORT size_t VpDivd(Real *c, Real *r, Real *a, Real *b)
Definition: bigdecimal.c:4629
VP_EXPORT void VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
Definition: bigdecimal.c:5212
VP_EXPORT double VpGetDoublePosInf(void)
Definition: bigdecimal.c:3556
#define T_SYMBOL
Definition: ruby.h:494
#define ISDIGIT(c)
Definition: ruby.h:1775
static ID id_up
Definition: bigdecimal.c:58
#define Max(a, b)
Definition: bigdecimal.h:269
static double zero(void)
Definition: isinf.c:51
static ID id_half_even
Definition: bigdecimal.c:64
static VALUE BigDecimal_coerce(VALUE self, VALUE other)
Definition: bigdecimal.c:797
#define RMPD_EXCEPTION_MODE_DEFAULT
Definition: bigdecimal.h:135
static BDIGIT VpAddAbs(Real *a, Real *b, Real *c)
Definition: bigdecimal.c:4179
static size_t VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, BDIGIT *av, BDIGIT *bv)
Definition: bigdecimal.c:4390
SIGNED_VALUE exponent
Definition: bigdecimal.h:175
static ID id_BigDecimal_rounding_mode
Definition: bigdecimal.c:55
static VALUE BigDecimal_lt(VALUE self, VALUE r)
Definition: bigdecimal.c:1094
static VALUE BigDecimal_sign(VALUE self)
Definition: bigdecimal.c:2601
VP_EXPORT int VpException(unsigned short f, const char *str, int always)
Definition: bigdecimal.c:3589
void rb_bug(const char *fmt,...)
Definition: error.c:327
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1015
static VALUE BigDecimal_power(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:2191
static void VpFormatSt(char *psz, size_t fFmt)
Definition: bigdecimal.c:5088
static VALUE BigDecimal_load(VALUE self, VALUE str)
Definition: bigdecimal.c:383
#define Min(a, b)
Definition: bigdecimal.h:270
size_t strlen(const char *)
#define INT2NUM(x)
Definition: ruby.h:1288
#define VP_ROUND_HALF_UP
Definition: bigdecimal.h:141
static VALUE BigDecimal_div3(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:1513
#define T_FIXNUM
Definition: ruby.h:489
static VALUE BigDecimal_to_r(VALUE self)
Definition: bigdecimal.c:751
VALUE rb_Rational(VALUE, VALUE)
Definition: rational.c:1768
#define SAVE(p)
Definition: bigdecimal.c:75
static VALUE BigDecimal_abs(VALUE self)
Definition: bigdecimal.c:1594
static int is_zero(VALUE x)
Definition: bigdecimal.c:2094
static Real * GetVpValue(VALUE v, int must)
Definition: bigdecimal.c:283
#define BigMath_exp(x, n)
Definition: bigdecimal.c:2067
static ID id_truncate
Definition: bigdecimal.c:60
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1655
static VALUE BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:1727
#define VP_ROUND_DOWN
Definition: bigdecimal.h:140
#define DBL_DIG
Definition: numeric.c:67
VALUE obj
Definition: bigdecimal.h:168
VP_EXPORT int VpIsRoundMode(unsigned short n)
Definition: bigdecimal.c:3483
static double Zero(void)
Definition: bigdecimal.c:3522
#define VP_ROUND_FLOOR
Definition: bigdecimal.h:144
#define VpIsInf(a)
Definition: bigdecimal.h:303
#define VP_SIGN_POSITIVE_FINITE
Definition: bigdecimal.h:152
static unsigned short VpGetException(void)
Definition: bigdecimal.c:3397
#define VpIsDef(a)
Definition: bigdecimal.h:304
#define Qtrue
Definition: ruby.h:426
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
Definition: bignum.c:3199
#define VP_SIGN_NEGATIVE_ZERO
Definition: bigdecimal.h:151
#define TypedData_Wrap_Struct(klass, data_type, sval)
Definition: ruby.h:1027
static VALUE BigDecimal_eq(VALUE self, VALUE r)
Definition: bigdecimal.c:1081
static ID id_default
Definition: bigdecimal.c:62
const int id
Definition: nkf.c:209
static VALUE BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
Definition: bigdecimal.c:1278
static VALUE ToValue(Real *p)
Definition: bigdecimal.c:165
static VALUE BigMath_s_log(VALUE, VALUE, VALUE)
Definition: bigdecimal.c:2828
static ID id_half_down
Definition: bigdecimal.c:63
VALUE rb_eTypeError
Definition: error.c:548
#define T_RATIONAL
Definition: ruby.h:495
#define UNREACHABLE
Definition: ruby.h:42
#define VpMaxPrec(a)
Definition: bigdecimal.h:272
static VALUE BigDecimal_dump(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:361
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:896
static VALUE BigDecimal_limit(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:2566
#define VpSetNaN(a)
Definition: bigdecimal.h:298
size_t Prec
Definition: bigdecimal.h:172
static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:1669
static int VpRdup(Real *m, size_t ind_m)
Definition: bigdecimal.c:6041
RUBY_EXTERN VALUE rb_eMathDomainError
Definition: ruby.h:1625
#define SYM2ID(x)
Definition: ruby.h:356
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1302
static VALUE BigMath_s_exp(VALUE, VALUE, VALUE)
Definition: bigdecimal.c:2697
VP_EXPORT unsigned short VpGetRoundMode(void)
Definition: bigdecimal.c:3467
VP_EXPORT unsigned short VpSetRoundMode(unsigned short n)
Definition: bigdecimal.c:3501
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:775
static VALUE BigDecimal_mod(VALUE self, VALUE r)
Definition: bigdecimal.c:1366
VP_EXPORT void VpDtoV(Real *m, double d)
Definition: bigdecimal.c:5550
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:807
#define is_positive(x)
Definition: bigdecimal.c:2091
#define PRIxVALUE
Definition: ruby.h:135
static void cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v)
Definition: bigdecimal.c:182
#define Check_Type(v, t)
Definition: ruby.h:532
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
VP_EXPORT void VpFrac(Real *y, Real *x)
Definition: bigdecimal.c:6067
#define VP_SIGN_POSITIVE_ZERO
Definition: bigdecimal.h:150
static VALUE BigDecimal_sqrt(VALUE self, VALUE nFig)
Definition: bigdecimal.c:1616
#define RB_GC_GUARD(v)
Definition: ruby.h:523
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static void VpSetException(unsigned short f)
Definition: bigdecimal.c:3413
#define DATA_PTR(dta)
Definition: ruby.h:992
#define VP_ROUND_HALF_DOWN
Definition: bigdecimal.h:142
#define VP_SIGN_POSITIVE_INFINITE
Definition: bigdecimal.h:154
#define VP_EXCEPTION_OVERFLOW
Definition: bigdecimal.h:128
#define VpIsPosInf(a)
Definition: bigdecimal.h:301
#define RRATIONAL_NEGATIVE_P(x)
Definition: bigdecimal.c:98
st_data_t st_index_t
Definition: st.h:48
static VALUE BigDecimal_prec(VALUE self)
Definition: bigdecimal.c:311
static VALUE BigDecimal_comp(VALUE self, VALUE r)
Definition: bigdecimal.c:1065
VP_EXPORT Real * VpCreateRbObject(size_t mx, const char *str)
Definition: bigdecimal.c:579
VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m)
Definition: bigdecimal.c:5486
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1684
static int is_one(VALUE x)
Definition: bigdecimal.c:2117
static VALUE BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
Definition: bigdecimal.c:1379
static VALUE BigDecimal_fix(VALUE self)
Definition: bigdecimal.c:1635
#define FIXNUM_P(f)
Definition: ruby.h:347
#define SSIZET2NUM(v)
Definition: ruby.h:263
static Real * VpConstOne
Definition: bigdecimal.c:3320
static VALUE BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:1836
VALUE rb_str_tmp_new(long)
Definition: string.c:919
static void BigDecimal_delete(void *pv)
Definition: bigdecimal.c:138
RUBY_EXTERN VALUE rb_eZeroDivError
Definition: ruby.h:1609
#define DoSomeOne(x, y, f)
Definition: bigdecimal.c:104
VP_EXPORT int VpComp(Real *a, Real *b)
Definition: bigdecimal.c:4882
static VALUE BigDecimal_mult2(VALUE self, VALUE b, VALUE n)
Definition: bigdecimal.c:1571
static size_t GetAddSubPrec(Real *a, Real *b)
Definition: bigdecimal.c:538
static const unsigned char dv[]
Definition: nkf.c:586
static ID id_down
Definition: bigdecimal.c:59
static Real * VpCopy(Real *pv, Real const *const x)
Definition: bigdecimal.c:590
#define VpIsPosZero(a)
Definition: bigdecimal.h:289
#define VpPrec(a)
Definition: bigdecimal.h:273
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
#define rb_ary_new2
Definition: intern.h:90
VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf)
Definition: bigdecimal.c:5790
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)
Definition: bigdecimal.c:5326
VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf)
Definition: bigdecimal.c:5972
RUBY_EXTERN void * memmove(void *, const void *, size_t)
Definition: memmove.c:7
#define getchar()
Definition: win32.h:144
#define VpBaseVal()
Definition: bigdecimal.h:210
#define VP_EXCEPTION_INFINITY
Definition: bigdecimal.h:125
VALUE rb_thread_local_aref(VALUE, ID)
Definition: thread.c:2761
#define SZ_INF
Definition: bigdecimal.h:113
VP_EXPORT Real * VpNewRbClass(size_t mx, const char *str, VALUE klass)
Definition: bigdecimal.c:571
#define DBL_MAX_10_EXP
Definition: numeric.c:64
static ID id_half_up
Definition: bigdecimal.c:61
void rb_exc_raise(VALUE mesg)
Definition: eval.c:567
static VALUE BigDecimal_mode(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:484
#define strtod(s, e)
Definition: util.h:74
#define VP_SIGN_NEGATIVE_FINITE
Definition: bigdecimal.h:153
static ID id_ceil
Definition: bigdecimal.c:67
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1664
#define MUL_OVERFLOW_SIGNED_VALUE_P(a, b)
Definition: bigdecimal.c:49
static size_t BigDecimal_memsize(const void *ptr)
Definition: bigdecimal.c:144
#define RRATIONAL(obj)
Definition: ruby.h:1130
static VALUE BigDecimal_divmod(VALUE self, VALUE r)
Definition: bigdecimal.c:1458
#define VpIsNaN(a)
Definition: bigdecimal.h:297
static VALUE BigDecimal_inspect(VALUE self)
Definition: bigdecimal.c:2041
static VALUE BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
Definition: bigdecimal.c:1201
#define div(x, y)
Definition: date_strftime.c:27
static VALUE BigDecimalCmp(VALUE self, VALUE r, char op)
Definition: bigdecimal.c:952
static VALUE BigDecimal_neg(VALUE self)
Definition: bigdecimal.c:1148
static VALUE BigDecimal_save_rounding_mode(VALUE self)
Definition: bigdecimal.c:2651
VALUE rb_class_name(VALUE)
Definition: variable.c:391
static VALUE BigDecimal_nonzero(VALUE self)
Definition: bigdecimal.c:1055
static int VpLimitRound(Real *c, size_t ixDigit)
Definition: bigdecimal.c:5980
VALUE rb_dbl2big(double d)
Definition: bignum.c:5211
#define RMPD_COMPONENT_FIGURES
Definition: bigdecimal.h:101
NORETURN(static void cannot_be_coerced_into_BigDecimal(VALUE, VALUE))
static VALUE BigDecimal_exponent(VALUE self)
Definition: bigdecimal.c:2024
#define val
#define VP_EXCEPTION_UNDERFLOW
Definition: bigdecimal.h:127
#define ne(x, y)
Definition: time.c:66
#define rb_float_new(d)
Definition: internal.h:595
static int VpIsDefOP(Real *c, Real *a, Real *b, int sw)
Definition: bigdecimal.c:3616
#define SZ_NINF
Definition: bigdecimal.h:115
#define PRIdVALUE
Definition: ruby.h:132
#define VpExponent(a)
Definition: bigdecimal.h:310
static VALUE BigDecimal_remainder(VALUE self, VALUE r)
Definition: bigdecimal.c:1429
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:510
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:2159
static VALUE BigDecimal_to_f(VALUE self)
Definition: bigdecimal.c:704
#define VP_EXPORT
Definition: bigdecimal.h:121
#define rmpd_set_thread_local_exception_mode(mode)
Definition: bigdecimal.c:3389
#define snprintf
Definition: subst.h:6
VALUE rb_thread_current(void)
Definition: thread.c:2401
#define HALF_BASE
Definition: bigdecimal.c:81
#define NIL_P(v)
Definition: ruby.h:438
VP_EXPORT double VpGetDoubleNaN(void)
Definition: bigdecimal.c:3548
VP_EXPORT size_t VpGetPrecLimit(void)
Definition: bigdecimal.c:3432
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:630
#define VpIsOne(a)
Definition: bigdecimal.h:309
static VALUE BigDecimal_div(VALUE self, VALUE r)
Definition: bigdecimal.c:1254
VP_EXPORT void * VpMemAlloc(size_t mb)
Definition: bigdecimal.c:3343
#define BDIGIT_DBL_SIGNED
Definition: bigdecimal.h:49
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2225
#define VpAllocReal(prec)
Definition: bigdecimal.c:586
static VALUE BigDecimal_IsNaN(VALUE self)
Definition: bigdecimal.c:607
VP_EXPORT size_t VpMult(Real *c, Real *a, Real *b)
Definition: bigdecimal.c:4500
static double one(void)
Definition: isinf.c:52
#define ENTER(n)
Definition: bigdecimal.c:73
#define T_FLOAT
Definition: ruby.h:481
static int VpNmlz(Real *a)
Definition: bigdecimal.c:4844
#define TYPE(x)
Definition: ruby.h:505
int argc
Definition: ruby.c:131
volatile const double gOne_ABCED9B4_CE73__00400511F31D
Definition: bigdecimal.c:3520
static int is_kind_of_BigDecimal(VALUE const v)
Definition: bigdecimal.c:159
#define Qfalse
Definition: ruby.h:425
static VALUE BigDecimal_add2(VALUE self, VALUE b, VALUE n)
Definition: bigdecimal.c:1523
VP_EXPORT void VpToFString(Real *a, char *psz, size_t fFmt, int fPlus)
Definition: bigdecimal.c:5260
#define T_BIGNUM
Definition: ruby.h:487
static VALUE BigDecimal_initialize_copy(VALUE self, VALUE other)
Definition: bigdecimal.c:2481
if((ID)(DISPID) nameid!=nameid)
Definition: win32ole.c:770
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1352
RUBY_EXTERN int isinf(double)
Definition: isinf.c:56
VP_EXPORT Real * VpOne(void)
Definition: bigdecimal.c:3787
#define rb_str_new2
Definition: intern.h:840
VP_EXPORT void VpSzMantissa(Real *a, char *psz)
Definition: bigdecimal.c:5130
#define T_COMPLEX
Definition: ruby.h:496
#define VpDblFig()
Definition: bigdecimal.h:209
static VALUE int_chr(int argc, VALUE *argv, VALUE num)
Definition: numeric.c:2548
VALUE rb_big2str(VALUE x, int base)
Definition: bignum.c:5012
static VALUE BigDecimal_version(VALUE self)
Definition: bigdecimal.c:110
static VALUE BigDecimal_double_fig(VALUE self)
Definition: bigdecimal.c:296
static VALUE BigDecimal_floor(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:1788
short flag
Definition: bigdecimal.h:186
#define RBIGNUM_ZERO_P(x)
Definition: bigdecimal.c:89
VP_EXPORT void VpFree(Real *pv)
Definition: bigdecimal.c:3367
void Init_bigdecimal(void)
Definition: bigdecimal.c:3087
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2025
static VALUE BigDecimal_add(VALUE self, VALUE r)
Definition: bigdecimal.c:853
#define VpSetInf(a, s)
Definition: bigdecimal.h:307
#define VpSetSign(a, s)
Definition: bigdecimal.h:283
#define VP_EXCEPTION_ZERODIVIDE
Definition: bigdecimal.h:129
static ID id_BigDecimal_exception_mode
Definition: bigdecimal.c:54
static Real * GetVpValueWithPrec(VALUE v, long prec, int must)
Definition: bigdecimal.c:200
static void VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v)
Definition: bigdecimal.c:5993
volatile const double gZero_ABCED9B1_CE73__00400511F31D
Definition: bigdecimal.c:3519
#define RSTRING_LEN(str)
Definition: ruby.h:841
VALUE rb_yield(VALUE)
Definition: vm_eval.c:942
#define VpSetPosInf(a)
Definition: bigdecimal.h:305
int errno
#define T_DATA
Definition: ruby.h:492
static const rb_data_type_t BigDecimal_data_type
Definition: bigdecimal.c:150
#define vabs
Definition: bigdecimal.h:82
#define VpBaseFig()
Definition: bigdecimal.h:208
#define VP_SIGN_NEGATIVE_INFINITE
Definition: bigdecimal.h:155
void rb_fatal(const char *fmt,...)
Definition: error.c:1911
#define rb_Rational1(x)
Definition: intern.h:173
static VALUE BigDecimal_uplus(VALUE self)
Definition: bigdecimal.c:830
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
VP_EXPORT Real * VpAlloc(size_t mx, const char *szVal)
Definition: bigdecimal.c:3844
#define rmpd_set_thread_local_rounding_mode(mode)
Definition: bigdecimal.c:3459
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
static VALUE BigDecimal_ge(VALUE self, VALUE r)
Definition: bigdecimal.c:1133
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:616
#define PRIsVALUE
Definition: ruby.h:137
static VALUE BigDecimal_div2(VALUE, VALUE, VALUE)
Definition: bigdecimal.c:1474
unsigned long ID
Definition: ruby.h:89
static VALUE BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:2542
#define Qnil
Definition: ruby.h:427
static VALUE BigDecimal_split(VALUE self)
Definition: bigdecimal.c:1987
#define VP_ROUND_UP
Definition: bigdecimal.h:139
#define VP_EXCEPTION_MEMORY
Definition: bigdecimal.h:133
static int is_integer(VALUE x)
Definition: bigdecimal.c:2071
#define MemCmp(x, y, z)
Definition: bigdecimal.c:3326
unsigned long VALUE
Definition: ruby.h:88
#define VP_SIGN_NaN
Definition: bigdecimal.h:149
static ID id_BigDecimal_precision_limit
Definition: bigdecimal.c:56
#define StrCmp(x, y)
Definition: bigdecimal.c:3327
VP_EXPORT size_t VpInit(BDIGIT BaseVal)
Definition: bigdecimal.c:3756
static VALUE rmpd_power_by_big_decimal(Real const *x, Real const *exp, ssize_t const n)
Definition: bigdecimal.c:2163
#define FIX2INT(x)
Definition: ruby.h:632
VALUE rb_num_coerce_relop(VALUE, VALUE, ID)
Definition: numeric.c:295
#define maxnr
Definition: bigdecimal.c:3322
#define isnan(x)
Definition: win32.h:376
static void shift(struct cparse_params *v, long act, VALUE tok, VALUE val)
Definition: cparse.c:662
RUBY_EXTERN VALUE rb_cNumeric
Definition: ruby.h:1575
short sign
Definition: bigdecimal.h:176
void rb_jump_tag(int tag)
Definition: eval.c:706
static VALUE BigDecimal_to_i(VALUE self)
Definition: bigdecimal.c:657
VALUE rb_str_dup(VALUE)
Definition: string.c:1062
#define FIXABLE(f)
Definition: ruby.h:350
static VALUE BigDecimal_s_allocate(VALUE klass)
Definition: bigdecimal.c:2431
VP_EXPORT double VpGetDoubleNegInf(void)
Definition: bigdecimal.c:3564
#define LONG2NUM(x)
Definition: ruby.h:1309
static VALUE BigDecimal_zero(VALUE self)
Definition: bigdecimal.c:1047
#define StringValueCStr(v)
Definition: ruby.h:541
static VALUE BigDecimal_IsFinite(VALUE self)
Definition: bigdecimal.c:628
#define VpIsNegInf(a)
Definition: bigdecimal.h:302
VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw)
Definition: bigdecimal.c:4001
#define RSTRING_PTR(str)
Definition: ruby.h:845
VALUE rb_cBigDecimal
Definition: bigdecimal.c:51
static size_t rmpd_double_figures(void)
Definition: bigdecimal.h:206
#define rb_exc_new3
Definition: intern.h:248
#define VP_EXCEPTION_NaN
Definition: bigdecimal.h:126
BDIGIT frac[FLEXIBLE_ARRAY_SIZE]
Definition: bigdecimal.h:187
#define RMPD_PRECISION_LIMIT_DEFAULT
Definition: bigdecimal.c:3428
static VALUE BigDecimal_gt(VALUE self, VALUE r)
Definition: bigdecimal.c:1120
#define rmpd_set_thread_local_precision_limit(limit)
Definition: bigdecimal.c:3422
static VALUE BigDecimal_mult(VALUE self, VALUE r)
Definition: bigdecimal.c:1174
static int is_negative(VALUE x)
Definition: bigdecimal.c:2077
#define RFLOAT_VALUE(v)
Definition: ruby.h:814
#define f
#define INT2FIX(i)
Definition: ruby.h:231
#define VpChangeSign(a, s)
Definition: bigdecimal.h:281
void * rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:520
#define NUM2SSIZET(x)
Definition: ruby.h:681
RUBY_EXTERN double round(double)
Definition: numeric.c:92
#define xmalloc
Definition: defines.h:108
static void BigDecimal_check_num(Real *p)
Definition: bigdecimal.c:637
static const unsigned char cv[]
Definition: nkf.c:564
static Real * BigDecimal_new(int argc, VALUE *argv)
Definition: bigdecimal.c:2493
#define NUM2SIZET(x)
Definition: ruby.h:680
VP_EXPORT int VpToSpecialString(Real *a, char *psz, int fPlus)
Definition: bigdecimal.c:5177
#define RMPD_ROUNDING_MODE_DEFAULT
Definition: bigdecimal.h:147
#define VpIsNegZero(a)
Definition: bigdecimal.h:290
#define VpGetSign(a)
Definition: bigdecimal.h:279
VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf)
Definition: bigdecimal.c:5957
#define RARRAY_PTR(a)
Definition: ruby.h:907
VP_EXPORT size_t VpAddSub(Real *c, Real *a, Real *b, int operation)
Definition: bigdecimal.c:4045
#define VpIsZero(a)
Definition: bigdecimal.h:291
#define DBL_MIN_10_EXP
Definition: numeric.c:61
static double One(void)
Definition: bigdecimal.c:3528
static VALUE BigDecimal_power_op(VALUE self, VALUE exp)
Definition: bigdecimal.c:2425
static int rb_special_const_p(VALUE obj)
Definition: ruby.h:1687
#define LONG2FIX(i)
Definition: ruby.h:232
#define VpSetOne(a)
Definition: bigdecimal.h:286
#define SZ_NaN
Definition: bigdecimal.h:112
#define BDIGIT_DBL
Definition: bigdecimal.h:48
#define RTEST(v)
Definition: ruby.h:437
static int is_even(VALUE x)
Definition: bigdecimal.c:2142
void rb_thread_check_ints(void)
Definition: thread.c:1139
#define T_STRING
Definition: ruby.h:482
#define DBLE_FIG
Definition: bigdecimal.c:85
static VALUE BigDecimal_sub2(VALUE self, VALUE b, VALUE n)
Definition: bigdecimal.c:1553
#define PRIuSIZE
Definition: ruby.h:179
static ID id_banker
Definition: bigdecimal.c:65
static ID id_to_r
Definition: bigdecimal.c:69
VP_EXPORT int VpPower(Real *y, Real *x, SIGNED_VALUE n)
Definition: bigdecimal.c:6115
static unsigned int hash(const char *str, unsigned int len)
Definition: lex.c:56
#define SIGNED_VALUE_MAX
Definition: bigdecimal.c:47
#define SafeStringValue(v)
Definition: ruby.h:545
#define BASE_FIG
Definition: bigdecimal.c:78
static SIGNED_VALUE GetPositiveInt(VALUE v)
Definition: bigdecimal.c:559
static VALUE BigDecimal_initialize(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:2457
#define BASE1
Definition: bigdecimal.c:82
#define PRIdSIZE
Definition: ruby.h:176
static Real * VpPt5
Definition: bigdecimal.c:3321
#define assert(condition)
Definition: ossl.h:45
#define VpSetZero(a, s)
Definition: bigdecimal.h:294
#define VpSetNegInf(a)
Definition: bigdecimal.h:306
#define xrealloc
Definition: defines.h:111
#define VP_ROUND_HALF_EVEN
Definition: bigdecimal.h:145
VP_EXPORT size_t VpSetPrecLimit(size_t n)
Definition: bigdecimal.c:3448
RUBY_EXTERN VALUE rb_eFloatDomainError
Definition: ruby.h:1613
#define RRATIONAL_ZERO_P(x)
Definition: bigdecimal.c:93
#define BigMath_log(x, n)
Definition: bigdecimal.c:2068
#define BASE
Definition: bigdecimal.c:79
static BDIGIT VpSubAbs(Real *a, Real *b, Real *c)
Definition: bigdecimal.c:4274
#define SZ_PINF
Definition: bigdecimal.h:114
VALUE rb_inspect(VALUE)
Definition: object.c:470
#define FIX2UINT(x)
Definition: ruby.h:633
VP_EXPORT size_t VpNumOfChars(Real *vp, const char *pszFmt)
Definition: bigdecimal.c:3712
#define VpHasVal(a)
Definition: bigdecimal.h:308
#define rb_intern_const(str)
Definition: ruby.h:1442
#define RBIGNUM_NEGATIVE_P(b)
Definition: ruby.h:1098
void void xfree(void *)
#define VP_EXCEPTION_OP
Definition: bigdecimal.h:132
static ID id_eq
Definition: bigdecimal.c:70
static VALUE BigDecimal_hash(VALUE self)
Definition: bigdecimal.c:332
VALUE rb_define_module(const char *name)
Definition: class.c:746
static unsigned short check_rounding_mode(VALUE const v)
Definition: bigdecimal.c:410
static VALUE BigDecimal_save_limit(VALUE self)
Definition: bigdecimal.c:2676
#define rb_intern(str)
static VALUE BigDecimal_le(VALUE self, VALUE r)
Definition: bigdecimal.c:1107
static VALUE BigDecimal_save_exception_mode(VALUE self)
Definition: bigdecimal.c:2626
static int AddExponent(Real *a, SIGNED_VALUE n)
Definition: bigdecimal.c:3794
#define VP_ROUND_MODE
Definition: bigdecimal.h:138
#define mod(x, y)
Definition: date_strftime.c:28
VP_EXPORT double VpGetDoubleNegZero(void)
Definition: bigdecimal.c:3572
VALUE rb_mBigMath
Definition: bigdecimal.c:52
#define NULL
Definition: _sdbm.c:103
#define FIX2LONG(x)
Definition: ruby.h:345
#define Qundef
Definition: ruby.h:428
#define VpReallocReal(ptr, prec)
Definition: bigdecimal.c:587
static ID id_ceiling
Definition: bigdecimal.c:66
#define VP_EXCEPTION_ALL
Definition: bigdecimal.h:124
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
void rb_warn(const char *fmt,...)
Definition: error.c:223
VP_EXPORT void * VpMemRealloc(void *ptr, size_t mb)
Definition: bigdecimal.c:3357
#define bp()
Definition: vm_debug.h:25
VALUE rb_eArgError
Definition: error.c:549
static VALUE BigDecimal_IsInfinite(VALUE self)
Definition: bigdecimal.c:618
VP_EXPORT ssize_t VpExponent10(Real *a)
Definition: bigdecimal.c:5113
#define BDIGIT
Definition: bigdecimal.h:47
#define VP_ROUND_CEIL
Definition: bigdecimal.h:143
static VALUE BigDecimal_frac(VALUE self)
Definition: bigdecimal.c:1757
size_t MaxPrec
Definition: bigdecimal.h:169
static VALUE BigDecimal_sub(VALUE self, VALUE r)
Definition: bigdecimal.c:911
char ** argv
Definition: ruby.c:132
#define ISSPACE(c)
Definition: ruby.h:1770
static ID id_floor
Definition: bigdecimal.c:68
VALUE rb_num_coerce_cmp(VALUE, VALUE, ID)
Definition: numeric.c:287
static VALUE BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
Definition: bigdecimal.c:1896
VALUE rb_str_new(const char *, long)
Definition: string.c:534
VALUE rb_obj_class(VALUE)
Definition: object.c:226
#define SIGNED_VALUE
Definition: ruby.h:90
#define GUARD_OBJ(p, y)
Definition: bigdecimal.c:76
VP_EXPORT int VpSqrt(Real *y, Real *x)
Definition: bigdecimal.c:5682