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