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