PageRenderTime 70ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/ext/bigdecimal/bigdecimal.c

https://github.com/nazy/ruby
C | 5053 lines | 3569 code | 423 blank | 1061 comment | 737 complexity | a241cd5abe75ccc357df5e107464434b MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0, 0BSD, Unlicense

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. *
  3. * Ruby BigDecimal(Variable decimal precision) extension library.
  4. *
  5. * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
  6. *
  7. * You may distribute under the terms of either the GNU General Public
  8. * License or the Artistic License, as specified in the README file
  9. * of this BigDecimal distribution.
  10. *
  11. * NOTE: Change log in this source removed to reduce source code size.
  12. * See rev. 1.25 if needed.
  13. *
  14. */
  15. /* #define BIGDECIMAL_DEBUG 1 */
  16. #include "bigdecimal.h"
  17. #include <ctype.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <errno.h>
  22. #include <math.h>
  23. #include "math.h"
  24. #ifdef HAVE_IEEEFP_H
  25. #include <ieeefp.h>
  26. #endif
  27. /* #define ENABLE_NUMERIC_STRING */
  28. VALUE rb_cBigDecimal;
  29. static ID id_BigDecimal_exception_mode;
  30. static ID id_BigDecimal_rounding_mode;
  31. static ID id_BigDecimal_precision_limit;
  32. static ID id_up;
  33. static ID id_down;
  34. static ID id_truncate;
  35. static ID id_half_up;
  36. static ID id_default;
  37. static ID id_half_down;
  38. static ID id_half_even;
  39. static ID id_banker;
  40. static ID id_ceiling;
  41. static ID id_ceil;
  42. static ID id_floor;
  43. /* MACRO's to guard objects from GC by keeping them in stack */
  44. #define ENTER(n) volatile VALUE vStack[n];int iStack=0
  45. #define PUSH(x) vStack[iStack++] = (unsigned long)(x);
  46. #define SAVE(p) PUSH(p->obj);
  47. #define GUARD_OBJ(p,y) {p=y;SAVE(p);}
  48. #define BASE_FIG RMPD_COMPONENT_FIGURES
  49. #define BASE RMPD_BASE
  50. #define HALF_BASE (BASE/2)
  51. #define BASE1 (BASE/10)
  52. #ifndef DBLE_FIG
  53. #define DBLE_FIG (DBL_DIG+1) /* figure of double */
  54. #endif
  55. /*
  56. * ================== Ruby Interface part ==========================
  57. */
  58. #define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f)
  59. /*
  60. * Returns the BigDecimal version number.
  61. *
  62. * Ruby 1.8.0 returns 1.0.0.
  63. * Ruby 1.8.1 thru 1.8.3 return 1.0.1.
  64. */
  65. static VALUE
  66. BigDecimal_version(VALUE self)
  67. {
  68. /*
  69. * 1.0.0: Ruby 1.8.0
  70. * 1.0.1: Ruby 1.8.1
  71. */
  72. return rb_str_new2("1.0.1");
  73. }
  74. /*
  75. * VP routines used in BigDecimal part
  76. */
  77. static unsigned short VpGetException(void);
  78. static void VpSetException(unsigned short f);
  79. static void VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v);
  80. static int VpLimitRound(Real *c, size_t ixDigit);
  81. /*
  82. * **** BigDecimal part ****
  83. */
  84. static void
  85. BigDecimal_delete(void *pv)
  86. {
  87. VpFree(pv);
  88. }
  89. static size_t
  90. BigDecimal_memsize(const void *ptr)
  91. {
  92. const Real *pv = ptr;
  93. return pv ? (sizeof(*pv) + pv->MaxPrec * sizeof(BDIGIT)) : 0;
  94. }
  95. static const rb_data_type_t BigDecimal_data_type = {
  96. "BigDecimal",
  97. {0, BigDecimal_delete, BigDecimal_memsize,},
  98. };
  99. static VALUE
  100. ToValue(Real *p)
  101. {
  102. if(VpIsNaN(p)) {
  103. VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",0);
  104. } else if(VpIsPosInf(p)) {
  105. VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",0);
  106. } else if(VpIsNegInf(p)) {
  107. VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",0);
  108. }
  109. return p->obj;
  110. }
  111. static Real *
  112. GetVpValue(VALUE v, int must)
  113. {
  114. Real *pv;
  115. VALUE bg;
  116. char szD[128];
  117. VALUE orig = Qundef;
  118. int util_loaded = 0;
  119. again:
  120. switch(TYPE(v))
  121. {
  122. case T_RATIONAL:
  123. if(orig == Qundef ? (orig = v, 1) : orig != v) {
  124. if(!util_loaded) {
  125. rb_require("bigdecimal/util");
  126. util_loaded = 1;
  127. }
  128. v = rb_funcall2(v, rb_intern("to_d"), 0, 0);
  129. goto again;
  130. }
  131. v = orig;
  132. goto SomeOneMayDoIt;
  133. case T_DATA:
  134. if(rb_typeddata_is_kind_of(v, &BigDecimal_data_type)) {
  135. pv = DATA_PTR(v);
  136. return pv;
  137. } else {
  138. goto SomeOneMayDoIt;
  139. }
  140. break;
  141. case T_FIXNUM:
  142. sprintf(szD, "%ld", FIX2LONG(v));
  143. return VpCreateRbObject(VpBaseFig() * 2 + 1, szD);
  144. #ifdef ENABLE_NUMERIC_STRING
  145. case T_STRING:
  146. SafeStringValue(v);
  147. return VpCreateRbObject(strlen(RSTRING_PTR(v)) + VpBaseFig() + 1,
  148. RSTRING_PTR(v));
  149. #endif /* ENABLE_NUMERIC_STRING */
  150. case T_BIGNUM:
  151. bg = rb_big2str(v, 10);
  152. return VpCreateRbObject(strlen(RSTRING_PTR(bg)) + VpBaseFig() + 1,
  153. RSTRING_PTR(bg));
  154. default:
  155. goto SomeOneMayDoIt;
  156. }
  157. SomeOneMayDoIt:
  158. if(must) {
  159. rb_raise(rb_eTypeError, "%s can't be coerced into BigDecimal",
  160. rb_special_const_p(v)?
  161. RSTRING_PTR(rb_inspect(v)):
  162. rb_obj_classname(v)
  163. );
  164. }
  165. return NULL; /* NULL means to coerce */
  166. }
  167. /* call-seq:
  168. * BigDecimal.double_fig
  169. *
  170. * The BigDecimal.double_fig class method returns the number of digits a
  171. * Float number is allowed to have. The result depends upon the CPU and OS
  172. * in use.
  173. */
  174. static VALUE
  175. BigDecimal_double_fig(VALUE self)
  176. {
  177. return INT2FIX(VpDblFig());
  178. }
  179. /* call-seq:
  180. * precs
  181. *
  182. * Returns an Array of two Integer values.
  183. *
  184. * The first value is the current number of significant digits in the
  185. * BigDecimal. The second value is the maximum number of significant digits
  186. * for the BigDecimal.
  187. */
  188. static VALUE
  189. BigDecimal_prec(VALUE self)
  190. {
  191. ENTER(1);
  192. Real *p;
  193. VALUE obj;
  194. GUARD_OBJ(p,GetVpValue(self,1));
  195. obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()),
  196. INT2NUM(p->MaxPrec*VpBaseFig()));
  197. return obj;
  198. }
  199. static VALUE
  200. BigDecimal_hash(VALUE self)
  201. {
  202. ENTER(1);
  203. Real *p;
  204. st_index_t hash;
  205. GUARD_OBJ(p,GetVpValue(self,1));
  206. hash = (st_index_t)p->sign;
  207. /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */
  208. if(hash == 2 || hash == (st_index_t)-2) {
  209. hash ^= rb_memhash(p->frac, sizeof(BDIGIT)*p->Prec);
  210. hash += p->exponent;
  211. }
  212. return INT2FIX(hash);
  213. }
  214. static VALUE
  215. BigDecimal_dump(int argc, VALUE *argv, VALUE self)
  216. {
  217. ENTER(5);
  218. Real *vp;
  219. char *psz;
  220. VALUE dummy;
  221. volatile VALUE dump;
  222. rb_scan_args(argc, argv, "01", &dummy);
  223. GUARD_OBJ(vp,GetVpValue(self,1));
  224. dump = rb_str_new(0,VpNumOfChars(vp,"E")+50);
  225. psz = RSTRING_PTR(dump);
  226. sprintf(psz, "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig());
  227. VpToString(vp, psz+strlen(psz), 0, 0);
  228. rb_str_resize(dump, strlen(psz));
  229. return dump;
  230. }
  231. /*
  232. * Internal method used to provide marshalling support. See the Marshal module.
  233. */
  234. static VALUE
  235. BigDecimal_load(VALUE self, VALUE str)
  236. {
  237. ENTER(2);
  238. Real *pv;
  239. unsigned char *pch;
  240. unsigned char ch;
  241. unsigned long m=0;
  242. SafeStringValue(str);
  243. pch = (unsigned char *)RSTRING_PTR(str);
  244. /* First get max prec */
  245. while((*pch)!=(unsigned char)'\0' && (ch=*pch++)!=(unsigned char)':') {
  246. if(!ISDIGIT(ch)) {
  247. rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string");
  248. }
  249. m = m*10 + (unsigned long)(ch-'0');
  250. }
  251. if(m>VpBaseFig()) m -= VpBaseFig();
  252. GUARD_OBJ(pv,VpNewRbClass(m,(char *)pch,self));
  253. m /= VpBaseFig();
  254. if(m && pv->MaxPrec>m) pv->MaxPrec = m+1;
  255. return ToValue(pv);
  256. }
  257. static unsigned short
  258. check_rounding_mode(VALUE const v)
  259. {
  260. unsigned short sw;
  261. ID id;
  262. switch (TYPE(v)) {
  263. case T_SYMBOL:
  264. id = SYM2ID(v);
  265. if (id == id_up)
  266. return VP_ROUND_UP;
  267. if (id == id_down || id == id_truncate)
  268. return VP_ROUND_DOWN;
  269. if (id == id_half_up || id == id_default)
  270. return VP_ROUND_HALF_UP;
  271. if (id == id_half_down)
  272. return VP_ROUND_HALF_DOWN;
  273. if (id == id_half_even || id == id_banker)
  274. return VP_ROUND_HALF_EVEN;
  275. if (id == id_ceiling || id == id_ceil)
  276. return VP_ROUND_CEIL;
  277. if (id == id_floor)
  278. return VP_ROUND_FLOOR;
  279. rb_raise(rb_eArgError, "invalid rounding mode");
  280. default:
  281. break;
  282. }
  283. Check_Type(v, T_FIXNUM);
  284. sw = (unsigned short)FIX2UINT(v);
  285. if (!VpIsRoundMode(sw)) {
  286. rb_raise(rb_eArgError, "invalid rounding mode");
  287. }
  288. return sw;
  289. }
  290. /* call-seq:
  291. * BigDecimal.mode(mode, value)
  292. *
  293. * Controls handling of arithmetic exceptions and rounding. If no value
  294. * is supplied, the current value is returned.
  295. *
  296. * Six values of the mode parameter control the handling of arithmetic
  297. * exceptions:
  298. *
  299. * BigDecimal::EXCEPTION_NaN
  300. * BigDecimal::EXCEPTION_INFINITY
  301. * BigDecimal::EXCEPTION_UNDERFLOW
  302. * BigDecimal::EXCEPTION_OVERFLOW
  303. * BigDecimal::EXCEPTION_ZERODIVIDE
  304. * BigDecimal::EXCEPTION_ALL
  305. *
  306. * For each mode parameter above, if the value set is false, computation
  307. * continues after an arithmetic exception of the appropriate type.
  308. * When computation continues, results are as follows:
  309. *
  310. * EXCEPTION_NaN:: NaN
  311. * EXCEPTION_INFINITY:: +infinity or -infinity
  312. * EXCEPTION_UNDERFLOW:: 0
  313. * EXCEPTION_OVERFLOW:: +infinity or -infinity
  314. * EXCEPTION_ZERODIVIDE:: +infinity or -infinity
  315. *
  316. * One value of the mode parameter controls the rounding of numeric values:
  317. * BigDecimal::ROUND_MODE. The values it can take are:
  318. *
  319. * ROUND_UP, :up:: round away from zero
  320. * ROUND_DOWN, :down, :truncate:: round towards zero (truncate)
  321. * ROUND_HALF_UP, :half_up, :default:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round away from zero. (default)
  322. * ROUND_HALF_DOWN, :half_down:: round towards the nearest neighbor, unless both neighbors are equidistant, in which case round towards zero.
  323. * 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)
  324. * ROUND_CEILING, :ceiling, :ceil:: round towards positive infinity (ceil)
  325. * ROUND_FLOOR, :floor:: round towards negative infinity (floor)
  326. *
  327. */
  328. static VALUE
  329. BigDecimal_mode(int argc, VALUE *argv, VALUE self)
  330. {
  331. VALUE which;
  332. VALUE val;
  333. unsigned long f,fo;
  334. if(rb_scan_args(argc,argv,"11",&which,&val)==1) val = Qnil;
  335. Check_Type(which, T_FIXNUM);
  336. f = (unsigned long)FIX2INT(which);
  337. if(f&VP_EXCEPTION_ALL) {
  338. /* Exception mode setting */
  339. fo = VpGetException();
  340. if(val==Qnil) return INT2FIX(fo);
  341. if(val!=Qfalse && val!=Qtrue) {
  342. rb_raise(rb_eArgError, "second argument must be true or false");
  343. return Qnil; /* Not reached */
  344. }
  345. if(f&VP_EXCEPTION_INFINITY) {
  346. VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):
  347. (fo&(~VP_EXCEPTION_INFINITY))));
  348. }
  349. fo = VpGetException();
  350. if(f&VP_EXCEPTION_NaN) {
  351. VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):
  352. (fo&(~VP_EXCEPTION_NaN))));
  353. }
  354. fo = VpGetException();
  355. if(f&VP_EXCEPTION_UNDERFLOW) {
  356. VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_UNDERFLOW):
  357. (fo&(~VP_EXCEPTION_UNDERFLOW))));
  358. }
  359. fo = VpGetException();
  360. if(f&VP_EXCEPTION_ZERODIVIDE) {
  361. VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_ZERODIVIDE):
  362. (fo&(~VP_EXCEPTION_ZERODIVIDE))));
  363. }
  364. fo = VpGetException();
  365. return INT2FIX(fo);
  366. }
  367. if (VP_ROUND_MODE == f) {
  368. /* Rounding mode setting */
  369. unsigned short sw;
  370. fo = VpGetRoundMode();
  371. if (NIL_P(val)) return INT2FIX(fo);
  372. sw = check_rounding_mode(val);
  373. fo = VpSetRoundMode(sw);
  374. return INT2FIX(fo);
  375. }
  376. rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
  377. return Qnil;
  378. }
  379. static size_t
  380. GetAddSubPrec(Real *a, Real *b)
  381. {
  382. size_t mxs;
  383. size_t mx = a->Prec;
  384. SIGNED_VALUE d;
  385. if(!VpIsDef(a) || !VpIsDef(b)) return (size_t)-1L;
  386. if(mx < b->Prec) mx = b->Prec;
  387. if(a->exponent!=b->exponent) {
  388. mxs = mx;
  389. d = a->exponent - b->exponent;
  390. if (d < 0) d = -d;
  391. mx = mx + (size_t)d;
  392. if (mx<mxs) {
  393. return VpException(VP_EXCEPTION_INFINITY,"Exponent overflow",0);
  394. }
  395. }
  396. return mx;
  397. }
  398. static SIGNED_VALUE
  399. GetPositiveInt(VALUE v)
  400. {
  401. SIGNED_VALUE n;
  402. Check_Type(v, T_FIXNUM);
  403. n = FIX2INT(v);
  404. if (n < 0) {
  405. rb_raise(rb_eArgError, "argument must be positive");
  406. }
  407. return n;
  408. }
  409. VP_EXPORT Real *
  410. VpNewRbClass(size_t mx, char *str, VALUE klass)
  411. {
  412. Real *pv = VpAlloc(mx,str);
  413. pv->obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, pv);
  414. return pv;
  415. }
  416. VP_EXPORT Real *
  417. VpCreateRbObject(size_t mx, const char *str)
  418. {
  419. Real *pv = VpAlloc(mx,str);
  420. pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
  421. return pv;
  422. }
  423. /* Returns True if the value is Not a Number */
  424. static VALUE
  425. BigDecimal_IsNaN(VALUE self)
  426. {
  427. Real *p = GetVpValue(self,1);
  428. if(VpIsNaN(p)) return Qtrue;
  429. return Qfalse;
  430. }
  431. /* Returns nil, -1, or +1 depending on whether the value is finite,
  432. * -infinity, or +infinity.
  433. */
  434. static VALUE
  435. BigDecimal_IsInfinite(VALUE self)
  436. {
  437. Real *p = GetVpValue(self,1);
  438. if(VpIsPosInf(p)) return INT2FIX(1);
  439. if(VpIsNegInf(p)) return INT2FIX(-1);
  440. return Qnil;
  441. }
  442. /* Returns True if the value is finite (not NaN or infinite) */
  443. static VALUE
  444. BigDecimal_IsFinite(VALUE self)
  445. {
  446. Real *p = GetVpValue(self,1);
  447. if(VpIsNaN(p)) return Qfalse;
  448. if(VpIsInf(p)) return Qfalse;
  449. return Qtrue;
  450. }
  451. static void
  452. BigDecimal_check_num(Real *p)
  453. {
  454. if(VpIsNaN(p)) {
  455. VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",1);
  456. } else if(VpIsPosInf(p)) {
  457. VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",1);
  458. } else if(VpIsNegInf(p)) {
  459. VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",1);
  460. }
  461. }
  462. static VALUE BigDecimal_split(VALUE self);
  463. /* Returns the value as an integer (Fixnum or Bignum).
  464. *
  465. * If the BigNumber is infinity or NaN, raises FloatDomainError.
  466. */
  467. static VALUE
  468. BigDecimal_to_i(VALUE self)
  469. {
  470. ENTER(5);
  471. ssize_t e, nf;
  472. Real *p;
  473. GUARD_OBJ(p,GetVpValue(self,1));
  474. BigDecimal_check_num(p);
  475. e = VpExponent10(p);
  476. if(e<=0) return INT2FIX(0);
  477. nf = VpBaseFig();
  478. if(e<=nf) {
  479. return LONG2NUM((long)(VpGetSign(p)*(BDIGIT_DBL_SIGNED)p->frac[0]));
  480. }
  481. else {
  482. VALUE a = BigDecimal_split(self);
  483. VALUE digits = RARRAY_PTR(a)[1];
  484. VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0);
  485. ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits);
  486. if (VpGetSign(p) < 0) {
  487. numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
  488. }
  489. if (dpower < 0) {
  490. return rb_funcall(numerator, rb_intern("div"), 1,
  491. rb_funcall(INT2FIX(10), rb_intern("**"), 1,
  492. INT2FIX(-dpower)));
  493. }
  494. return rb_funcall(numerator, '*', 1,
  495. rb_funcall(INT2FIX(10), rb_intern("**"), 1,
  496. INT2FIX(dpower)));
  497. }
  498. }
  499. /* Returns a new Float object having approximately the same value as the
  500. * BigDecimal number. Normal accuracy limits and built-in errors of binary
  501. * Float arithmetic apply.
  502. */
  503. static VALUE
  504. BigDecimal_to_f(VALUE self)
  505. {
  506. ENTER(1);
  507. Real *p;
  508. double d;
  509. SIGNED_VALUE e;
  510. char *buf;
  511. volatile VALUE str;
  512. GUARD_OBJ(p, GetVpValue(self, 1));
  513. if (VpVtoD(&d, &e, p) != 1)
  514. return rb_float_new(d);
  515. if (e > (SIGNED_VALUE)(DBL_MAX_10_EXP+BASE_FIG))
  516. goto overflow;
  517. if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-BASE_FIG))
  518. goto underflow;
  519. str = rb_str_new(0, VpNumOfChars(p,"E"));
  520. buf = RSTRING_PTR(str);
  521. VpToString(p, buf, 0, 0);
  522. errno = 0;
  523. d = strtod(buf, 0);
  524. if (errno == ERANGE)
  525. goto overflow;
  526. return rb_float_new(d);
  527. overflow:
  528. VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0);
  529. if (d > 0.0)
  530. return rb_float_new(VpGetDoublePosInf());
  531. else
  532. return rb_float_new(VpGetDoubleNegInf());
  533. underflow:
  534. VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0);
  535. if (d > 0.0)
  536. return rb_float_new(0.0);
  537. else
  538. return rb_float_new(-0.0);
  539. }
  540. /* Converts a BigDecimal to a Rational.
  541. */
  542. static VALUE
  543. BigDecimal_to_r(VALUE self)
  544. {
  545. Real *p;
  546. ssize_t sign, power, denomi_power;
  547. VALUE a, digits, numerator;
  548. p = GetVpValue(self,1);
  549. BigDecimal_check_num(p);
  550. sign = VpGetSign(p);
  551. power = VpExponent10(p);
  552. a = BigDecimal_split(self);
  553. digits = RARRAY_PTR(a)[1];
  554. denomi_power = power - RSTRING_LEN(digits);
  555. numerator = rb_funcall(digits, rb_intern("to_i"), 0);
  556. if (sign < 0) {
  557. numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
  558. }
  559. if (denomi_power < 0) {
  560. return rb_Rational(numerator,
  561. rb_funcall(INT2FIX(10), rb_intern("**"), 1,
  562. INT2FIX(-denomi_power)));
  563. }
  564. else {
  565. return rb_Rational1(rb_funcall(numerator, '*', 1,
  566. rb_funcall(INT2FIX(10), rb_intern("**"), 1,
  567. INT2FIX(denomi_power))));
  568. }
  569. }
  570. /* The coerce method provides support for Ruby type coercion. It is not
  571. * enabled by default.
  572. *
  573. * This means that binary operations like + * / or - can often be performed
  574. * on a BigDecimal and an object of another type, if the other object can
  575. * be coerced into a BigDecimal value.
  576. *
  577. * e.g.
  578. * a = BigDecimal.new("1.0")
  579. * b = a / 2.0 -> 0.5
  580. *
  581. * Note that coercing a String to a BigDecimal is not supported by default;
  582. * it requires a special compile-time option when building Ruby.
  583. */
  584. static VALUE
  585. BigDecimal_coerce(VALUE self, VALUE other)
  586. {
  587. ENTER(2);
  588. VALUE obj;
  589. Real *b;
  590. if (TYPE(other) == T_FLOAT) {
  591. obj = rb_assoc_new(other, BigDecimal_to_f(self));
  592. } else {
  593. GUARD_OBJ(b,GetVpValue(other,1));
  594. obj = rb_assoc_new(b->obj, self);
  595. }
  596. return obj;
  597. }
  598. static VALUE
  599. BigDecimal_uplus(VALUE self)
  600. {
  601. return self;
  602. }
  603. /* call-seq:
  604. * add(value, digits)
  605. *
  606. * Add the specified value.
  607. *
  608. * e.g.
  609. * c = a.add(b,n)
  610. * c = a + b
  611. *
  612. * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.
  613. */
  614. static VALUE
  615. BigDecimal_add(VALUE self, VALUE r)
  616. {
  617. ENTER(5);
  618. Real *c, *a, *b;
  619. size_t mx;
  620. GUARD_OBJ(a,GetVpValue(self,1));
  621. b = GetVpValue(r,0);
  622. if(!b) return DoSomeOne(self,r,'+');
  623. SAVE(b);
  624. if(VpIsNaN(b)) return b->obj;
  625. if(VpIsNaN(a)) return a->obj;
  626. mx = GetAddSubPrec(a,b);
  627. if (mx == (size_t)-1L) {
  628. GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
  629. VpAddSub(c, a, b, 1);
  630. } else {
  631. GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
  632. if(!mx) {
  633. VpSetInf(c,VpGetSign(a));
  634. } else {
  635. VpAddSub(c, a, b, 1);
  636. }
  637. }
  638. return ToValue(c);
  639. }
  640. /* call-seq:
  641. * sub(value, digits)
  642. *
  643. * Subtract the specified value.
  644. *
  645. * e.g.
  646. * c = a.sub(b,n)
  647. * c = a - b
  648. *
  649. * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.
  650. */
  651. static VALUE
  652. BigDecimal_sub(VALUE self, VALUE r)
  653. {
  654. ENTER(5);
  655. Real *c, *a, *b;
  656. size_t mx;
  657. GUARD_OBJ(a,GetVpValue(self,1));
  658. b = GetVpValue(r,0);
  659. if(!b) return DoSomeOne(self,r,'-');
  660. SAVE(b);
  661. if(VpIsNaN(b)) return b->obj;
  662. if(VpIsNaN(a)) return a->obj;
  663. mx = GetAddSubPrec(a,b);
  664. if (mx == (size_t)-1L) {
  665. GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0"));
  666. VpAddSub(c, a, b, -1);
  667. } else {
  668. GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
  669. if(!mx) {
  670. VpSetInf(c,VpGetSign(a));
  671. } else {
  672. VpAddSub(c, a, b, -1);
  673. }
  674. }
  675. return ToValue(c);
  676. }
  677. static VALUE
  678. BigDecimalCmp(VALUE self, VALUE r,char op)
  679. {
  680. ENTER(5);
  681. SIGNED_VALUE e;
  682. Real *a, *b;
  683. GUARD_OBJ(a,GetVpValue(self,1));
  684. b = GetVpValue(r,0);
  685. if(!b) {
  686. ID f = 0;
  687. switch(op)
  688. {
  689. case '*': return rb_num_coerce_cmp(self,r,rb_intern("<=>"));
  690. case '=': return RTEST(rb_num_coerce_cmp(self,r,rb_intern("=="))) ? Qtrue : Qfalse;
  691. case 'G': f = rb_intern(">="); break;
  692. case 'L': f = rb_intern("<="); break;
  693. case '>': case '<': f = (ID)op; break;
  694. }
  695. return rb_num_coerce_relop(self,r,f);
  696. }
  697. SAVE(b);
  698. e = VpComp(a, b);
  699. if(e==999) return (op == '*') ? Qnil : Qfalse;
  700. switch(op)
  701. {
  702. case '*': return INT2FIX(e); /* any op */
  703. case '=': if(e==0) return Qtrue ; return Qfalse;
  704. case 'G': if(e>=0) return Qtrue ; return Qfalse;
  705. case '>': if(e> 0) return Qtrue ; return Qfalse;
  706. case 'L': if(e<=0) return Qtrue ; return Qfalse;
  707. case '<': if(e< 0) return Qtrue ; return Qfalse;
  708. }
  709. rb_bug("Undefined operation in BigDecimalCmp()");
  710. }
  711. /* Returns True if the value is zero. */
  712. static VALUE
  713. BigDecimal_zero(VALUE self)
  714. {
  715. Real *a = GetVpValue(self,1);
  716. return VpIsZero(a) ? Qtrue : Qfalse;
  717. }
  718. /* Returns self if the value is non-zero, nil otherwise. */
  719. static VALUE
  720. BigDecimal_nonzero(VALUE self)
  721. {
  722. Real *a = GetVpValue(self,1);
  723. return VpIsZero(a) ? Qnil : self;
  724. }
  725. /* The comparison operator.
  726. * a <=> b is 0 if a == b, 1 if a > b, -1 if a < b.
  727. */
  728. static VALUE
  729. BigDecimal_comp(VALUE self, VALUE r)
  730. {
  731. return BigDecimalCmp(self, r, '*');
  732. }
  733. /*
  734. * Tests for value equality; returns true if the values are equal.
  735. *
  736. * The == and === operators and the eql? method have the same implementation
  737. * for BigDecimal.
  738. *
  739. * Values may be coerced to perform the comparison:
  740. *
  741. * BigDecimal.new('1.0') == 1.0 -> true
  742. */
  743. static VALUE
  744. BigDecimal_eq(VALUE self, VALUE r)
  745. {
  746. return BigDecimalCmp(self, r, '=');
  747. }
  748. /* call-seq:
  749. * a < b
  750. *
  751. * Returns true if a is less than b. Values may be coerced to perform the
  752. * comparison (see ==, coerce).
  753. */
  754. static VALUE
  755. BigDecimal_lt(VALUE self, VALUE r)
  756. {
  757. return BigDecimalCmp(self, r, '<');
  758. }
  759. /* call-seq:
  760. * a <= b
  761. *
  762. * Returns true if a is less than or equal to b. Values may be coerced to
  763. * perform the comparison (see ==, coerce).
  764. */
  765. static VALUE
  766. BigDecimal_le(VALUE self, VALUE r)
  767. {
  768. return BigDecimalCmp(self, r, 'L');
  769. }
  770. /* call-seq:
  771. * a > b
  772. *
  773. * Returns true if a is greater than b. Values may be coerced to
  774. * perform the comparison (see ==, coerce).
  775. */
  776. static VALUE
  777. BigDecimal_gt(VALUE self, VALUE r)
  778. {
  779. return BigDecimalCmp(self, r, '>');
  780. }
  781. /* call-seq:
  782. * a >= b
  783. *
  784. * Returns true if a is greater than or equal to b. Values may be coerced to
  785. * perform the comparison (see ==, coerce)
  786. */
  787. static VALUE
  788. BigDecimal_ge(VALUE self, VALUE r)
  789. {
  790. return BigDecimalCmp(self, r, 'G');
  791. }
  792. static VALUE
  793. BigDecimal_neg(VALUE self)
  794. {
  795. ENTER(5);
  796. Real *c, *a;
  797. GUARD_OBJ(a,GetVpValue(self,1));
  798. GUARD_OBJ(c,VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0"));
  799. VpAsgn(c, a, -1);
  800. return ToValue(c);
  801. }
  802. /* call-seq:
  803. * mult(value, digits)
  804. *
  805. * Multiply by the specified value.
  806. *
  807. * e.g.
  808. * c = a.mult(b,n)
  809. * c = a * b
  810. *
  811. * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.
  812. */
  813. static VALUE
  814. BigDecimal_mult(VALUE self, VALUE r)
  815. {
  816. ENTER(5);
  817. Real *c, *a, *b;
  818. size_t mx;
  819. GUARD_OBJ(a,GetVpValue(self,1));
  820. b = GetVpValue(r,0);
  821. if(!b) return DoSomeOne(self,r,'*');
  822. SAVE(b);
  823. mx = a->Prec + b->Prec;
  824. GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0"));
  825. VpMult(c, a, b);
  826. return ToValue(c);
  827. }
  828. static VALUE
  829. BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
  830. /* For c = self.div(r): with round operation */
  831. {
  832. ENTER(5);
  833. Real *a, *b;
  834. size_t mx;
  835. GUARD_OBJ(a,GetVpValue(self,1));
  836. b = GetVpValue(r,0);
  837. if(!b) return DoSomeOne(self,r,'/');
  838. SAVE(b);
  839. *div = b;
  840. mx = a->Prec + vabs(a->exponent);
  841. if(mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent);
  842. mx =(mx + 1) * VpBaseFig();
  843. GUARD_OBJ((*c),VpCreateRbObject(mx, "#0"));
  844. GUARD_OBJ((*res),VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
  845. VpDivd(*c, *res, a, b);
  846. return (VALUE)0;
  847. }
  848. /* call-seq:
  849. * div(value, digits)
  850. * quo(value)
  851. *
  852. * Divide by the specified value.
  853. *
  854. * e.g.
  855. * c = a.div(b,n)
  856. *
  857. * digits:: If specified and less than the number of significant digits of the result, the result is rounded to that number of digits, according to BigDecimal.mode.
  858. *
  859. * If digits is 0, the result is the same as the / operator. If not, the
  860. * result is an integer BigDecimal, by analogy with Float#div.
  861. *
  862. * The alias quo is provided since div(value, 0) is the same as computing
  863. * the quotient; see divmod.
  864. */
  865. static VALUE
  866. BigDecimal_div(VALUE self, VALUE r)
  867. /* For c = self/r: with round operation */
  868. {
  869. ENTER(5);
  870. Real *c=NULL, *res=NULL, *div = NULL;
  871. r = BigDecimal_divide(&c, &res, &div, self, r);
  872. if(r!=(VALUE)0) return r; /* coerced by other */
  873. SAVE(c);SAVE(res);SAVE(div);
  874. /* a/b = c + r/b */
  875. /* c xxxxx
  876. r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
  877. */
  878. /* Round */
  879. if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
  880. VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal()*(BDIGIT_DBL)res->frac[0]/div->frac[0]));
  881. }
  882. return ToValue(c);
  883. }
  884. /*
  885. * %: mod = a%b = a - (a.to_f/b).floor * b
  886. * div = (a.to_f/b).floor
  887. */
  888. static VALUE
  889. BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
  890. {
  891. ENTER(8);
  892. Real *c=NULL, *d=NULL, *res=NULL;
  893. Real *a, *b;
  894. size_t mx;
  895. GUARD_OBJ(a,GetVpValue(self,1));
  896. b = GetVpValue(r,0);
  897. if(!b) return Qfalse;
  898. SAVE(b);
  899. if(VpIsNaN(a) || VpIsNaN(b)) goto NaN;
  900. if(VpIsInf(a) && VpIsInf(b)) goto NaN;
  901. if(VpIsZero(b)) {
  902. rb_raise(rb_eZeroDivError, "divided by 0");
  903. }
  904. if(VpIsInf(a)) {
  905. GUARD_OBJ(d,VpCreateRbObject(1, "0"));
  906. VpSetInf(d, (SIGNED_VALUE)(VpGetSign(a) == VpGetSign(b) ? 1 : -1));
  907. GUARD_OBJ(c,VpCreateRbObject(1, "NaN"));
  908. *div = d;
  909. *mod = c;
  910. return Qtrue;
  911. }
  912. if(VpIsInf(b)) {
  913. GUARD_OBJ(d,VpCreateRbObject(1, "0"));
  914. *div = d;
  915. *mod = a;
  916. return Qtrue;
  917. }
  918. if(VpIsZero(a)) {
  919. GUARD_OBJ(c,VpCreateRbObject(1, "0"));
  920. GUARD_OBJ(d,VpCreateRbObject(1, "0"));
  921. *div = d;
  922. *mod = c;
  923. return Qtrue;
  924. }
  925. mx = a->Prec + vabs(a->exponent);
  926. if(mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent);
  927. mx =(mx + 1) * VpBaseFig();
  928. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  929. GUARD_OBJ(res,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
  930. VpDivd(c, res, a, b);
  931. mx = c->Prec *(VpBaseFig() + 1);
  932. GUARD_OBJ(d,VpCreateRbObject(mx, "0"));
  933. VpActiveRound(d,c,VP_ROUND_DOWN,0);
  934. VpMult(res,d,b);
  935. VpAddSub(c,a,res,-1);
  936. if(!VpIsZero(c) && (VpGetSign(a)*VpGetSign(b)<0)) {
  937. VpAddSub(res,d,VpOne(),-1);
  938. GUARD_OBJ(d,VpCreateRbObject(GetAddSubPrec(c, b)*(VpBaseFig() + 1), "0"));
  939. VpAddSub(d ,c,b, 1);
  940. *div = res;
  941. *mod = d;
  942. } else {
  943. *div = d;
  944. *mod = c;
  945. }
  946. return Qtrue;
  947. NaN:
  948. GUARD_OBJ(c,VpCreateRbObject(1, "NaN"));
  949. GUARD_OBJ(d,VpCreateRbObject(1, "NaN"));
  950. *div = d;
  951. *mod = c;
  952. return Qtrue;
  953. }
  954. /* call-seq:
  955. * a % b
  956. * a.modulo(b)
  957. *
  958. * Returns the modulus from dividing by b. See divmod.
  959. */
  960. static VALUE
  961. BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */
  962. {
  963. ENTER(3);
  964. Real *div=NULL, *mod=NULL;
  965. if(BigDecimal_DoDivmod(self,r,&div,&mod)) {
  966. SAVE(div); SAVE(mod);
  967. return ToValue(mod);
  968. }
  969. return DoSomeOne(self,r,'%');
  970. }
  971. static VALUE
  972. BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
  973. {
  974. ENTER(10);
  975. size_t mx;
  976. Real *a=NULL, *b=NULL, *c=NULL, *res=NULL, *d=NULL, *rr=NULL, *ff=NULL;
  977. Real *f=NULL;
  978. GUARD_OBJ(a,GetVpValue(self,1));
  979. b = GetVpValue(r,0);
  980. if(!b) return DoSomeOne(self,r,rb_intern("remainder"));
  981. SAVE(b);
  982. mx =(a->MaxPrec + b->MaxPrec) *VpBaseFig();
  983. GUARD_OBJ(c ,VpCreateRbObject(mx, "0"));
  984. GUARD_OBJ(res,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
  985. GUARD_OBJ(rr ,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
  986. GUARD_OBJ(ff ,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0"));
  987. VpDivd(c, res, a, b);
  988. mx = c->Prec *(VpBaseFig() + 1);
  989. GUARD_OBJ(d,VpCreateRbObject(mx, "0"));
  990. GUARD_OBJ(f,VpCreateRbObject(mx, "0"));
  991. VpActiveRound(d,c,VP_ROUND_DOWN,0); /* 0: round off */
  992. VpFrac(f, c);
  993. VpMult(rr,f,b);
  994. VpAddSub(ff,res,rr,1);
  995. *dv = d;
  996. *rv = ff;
  997. return (VALUE)0;
  998. }
  999. /* Returns the remainder from dividing by the value.
  1000. *
  1001. * x.remainder(y) means x-y*(x/y).truncate
  1002. */
  1003. static VALUE
  1004. BigDecimal_remainder(VALUE self, VALUE r) /* remainder */
  1005. {
  1006. VALUE f;
  1007. Real *d,*rv=0;
  1008. f = BigDecimal_divremain(self,r,&d,&rv);
  1009. if(f!=(VALUE)0) return f;
  1010. return ToValue(rv);
  1011. }
  1012. /* Divides by the specified value, and returns the quotient and modulus
  1013. * as BigDecimal numbers. The quotient is rounded towards negative infinity.
  1014. *
  1015. * For example:
  1016. *
  1017. * require 'bigdecimal'
  1018. *
  1019. * a = BigDecimal.new("42")
  1020. * b = BigDecimal.new("9")
  1021. *
  1022. * q,m = a.divmod(b)
  1023. *
  1024. * c = q * b + m
  1025. *
  1026. * a == c -> true
  1027. *
  1028. * The quotient q is (a/b).floor, and the modulus is the amount that must be
  1029. * added to q * b to get a.
  1030. */
  1031. static VALUE
  1032. BigDecimal_divmod(VALUE self, VALUE r)
  1033. {
  1034. ENTER(5);
  1035. Real *div=NULL, *mod=NULL;
  1036. if(BigDecimal_DoDivmod(self,r,&div,&mod)) {
  1037. SAVE(div); SAVE(mod);
  1038. return rb_assoc_new(ToValue(div), ToValue(mod));
  1039. }
  1040. return DoSomeOne(self,r,rb_intern("divmod"));
  1041. }
  1042. static VALUE
  1043. BigDecimal_div2(int argc, VALUE *argv, VALUE self)
  1044. {
  1045. ENTER(5);
  1046. VALUE b,n;
  1047. int na = rb_scan_args(argc,argv,"11",&b,&n);
  1048. if(na==1) { /* div in Float sense */
  1049. Real *div=NULL;
  1050. Real *mod;
  1051. if(BigDecimal_DoDivmod(self,b,&div,&mod)) {
  1052. return BigDecimal_to_i(ToValue(div));
  1053. }
  1054. return DoSomeOne(self,b,rb_intern("div"));
  1055. } else { /* div in BigDecimal sense */
  1056. SIGNED_VALUE ix = GetPositiveInt(n);
  1057. if (ix == 0) return BigDecimal_div(self, b);
  1058. else {
  1059. Real *res=NULL;
  1060. Real *av=NULL, *bv=NULL, *cv=NULL;
  1061. size_t mx = (ix+VpBaseFig()*2);
  1062. size_t pl = VpSetPrecLimit(0);
  1063. GUARD_OBJ(cv,VpCreateRbObject(mx,"0"));
  1064. GUARD_OBJ(av,GetVpValue(self,1));
  1065. GUARD_OBJ(bv,GetVpValue(b,1));
  1066. mx = av->Prec + bv->Prec + 2;
  1067. if(mx <= cv->MaxPrec) mx = cv->MaxPrec+1;
  1068. GUARD_OBJ(res,VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0"));
  1069. VpDivd(cv,res,av,bv);
  1070. VpSetPrecLimit(pl);
  1071. VpLeftRound(cv,(int)VpGetRoundMode(),ix);
  1072. return ToValue(cv);
  1073. }
  1074. }
  1075. }
  1076. static VALUE
  1077. BigDecimal_add2(VALUE self, VALUE b, VALUE n)
  1078. {
  1079. ENTER(2);
  1080. Real *cv;
  1081. SIGNED_VALUE mx = GetPositiveInt(n);
  1082. if (mx == 0) return BigDecimal_add(self, b);
  1083. else {
  1084. size_t pl = VpSetPrecLimit(0);
  1085. VALUE c = BigDecimal_add(self,b);
  1086. VpSetPrecLimit(pl);
  1087. GUARD_OBJ(cv,GetVpValue(c,1));
  1088. VpLeftRound(cv,(int)VpGetRoundMode(),mx);
  1089. return ToValue(cv);
  1090. }
  1091. }
  1092. static VALUE
  1093. BigDecimal_sub2(VALUE self, VALUE b, VALUE n)
  1094. {
  1095. ENTER(2);
  1096. Real *cv;
  1097. SIGNED_VALUE mx = GetPositiveInt(n);
  1098. if (mx == 0) return BigDecimal_sub(self, b);
  1099. else {
  1100. size_t pl = VpSetPrecLimit(0);
  1101. VALUE c = BigDecimal_sub(self,b);
  1102. VpSetPrecLimit(pl);
  1103. GUARD_OBJ(cv,GetVpValue(c,1));
  1104. VpLeftRound(cv,(int)VpGetRoundMode(),mx);
  1105. return ToValue(cv);
  1106. }
  1107. }
  1108. static VALUE
  1109. BigDecimal_mult2(VALUE self, VALUE b, VALUE n)
  1110. {
  1111. ENTER(2);
  1112. Real *cv;
  1113. SIGNED_VALUE mx = GetPositiveInt(n);
  1114. if (mx == 0) return BigDecimal_mult(self, b);
  1115. else {
  1116. size_t pl = VpSetPrecLimit(0);
  1117. VALUE c = BigDecimal_mult(self,b);
  1118. VpSetPrecLimit(pl);
  1119. GUARD_OBJ(cv,GetVpValue(c,1));
  1120. VpLeftRound(cv,(int)VpGetRoundMode(),mx);
  1121. return ToValue(cv);
  1122. }
  1123. }
  1124. /* Returns the absolute value.
  1125. *
  1126. * BigDecimal('5').abs -> 5
  1127. *
  1128. * BigDecimal('-3').abs -> 3
  1129. */
  1130. static VALUE
  1131. BigDecimal_abs(VALUE self)
  1132. {
  1133. ENTER(5);
  1134. Real *c, *a;
  1135. size_t mx;
  1136. GUARD_OBJ(a,GetVpValue(self,1));
  1137. mx = a->Prec *(VpBaseFig() + 1);
  1138. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1139. VpAsgn(c, a, 1);
  1140. VpChangeSign(c, 1);
  1141. return ToValue(c);
  1142. }
  1143. /* call-seq:
  1144. * sqrt(n)
  1145. *
  1146. * Returns the square root of the value.
  1147. *
  1148. * If n is specified, returns at least that many significant digits.
  1149. */
  1150. static VALUE
  1151. BigDecimal_sqrt(VALUE self, VALUE nFig)
  1152. {
  1153. ENTER(5);
  1154. Real *c, *a;
  1155. size_t mx, n;
  1156. GUARD_OBJ(a,GetVpValue(self,1));
  1157. mx = a->Prec *(VpBaseFig() + 1);
  1158. n = GetPositiveInt(nFig) + VpDblFig() + 1;
  1159. if(mx <= n) mx = n;
  1160. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1161. VpSqrt(c, a);
  1162. return ToValue(c);
  1163. }
  1164. /* Return the integer part of the number.
  1165. */
  1166. static VALUE
  1167. BigDecimal_fix(VALUE self)
  1168. {
  1169. ENTER(5);
  1170. Real *c, *a;
  1171. size_t mx;
  1172. GUARD_OBJ(a,GetVpValue(self,1));
  1173. mx = a->Prec *(VpBaseFig() + 1);
  1174. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1175. VpActiveRound(c,a,VP_ROUND_DOWN,0); /* 0: round off */
  1176. return ToValue(c);
  1177. }
  1178. /* call-seq:
  1179. * round(n, mode)
  1180. *
  1181. * Round to the nearest 1 (by default), returning the result as a BigDecimal.
  1182. *
  1183. * BigDecimal('3.14159').round -> 3
  1184. *
  1185. * BigDecimal('8.7').round -> 9
  1186. *
  1187. * If n is specified and positive, the fractional part of the result has no
  1188. * more than that many digits.
  1189. *
  1190. * If n is specified and negative, at least that many digits to the left of the
  1191. * decimal point will be 0 in the result.
  1192. *
  1193. * BigDecimal('3.14159').round(3) -> 3.142
  1194. *
  1195. * BigDecimal('13345.234').round(-2) -> 13300.0
  1196. *
  1197. * The value of the optional mode argument can be used to determine how
  1198. * rounding is performed; see BigDecimal.mode.
  1199. */
  1200. static VALUE
  1201. BigDecimal_round(int argc, VALUE *argv, VALUE self)
  1202. {
  1203. ENTER(5);
  1204. Real *c, *a;
  1205. int iLoc = 0;
  1206. VALUE vLoc;
  1207. VALUE vRound;
  1208. size_t mx, pl;
  1209. unsigned short sw = VpGetRoundMode();
  1210. switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) {
  1211. case 0:
  1212. iLoc = 0;
  1213. break;
  1214. case 1:
  1215. Check_Type(vLoc, T_FIXNUM);
  1216. iLoc = FIX2INT(vLoc);
  1217. break;
  1218. case 2:
  1219. Check_Type(vLoc, T_FIXNUM);
  1220. iLoc = FIX2INT(vLoc);
  1221. sw = check_rounding_mode(vRound);
  1222. break;
  1223. }
  1224. pl = VpSetPrecLimit(0);
  1225. GUARD_OBJ(a,GetVpValue(self,1));
  1226. mx = a->Prec *(VpBaseFig() + 1);
  1227. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1228. VpSetPrecLimit(pl);
  1229. VpActiveRound(c,a,sw,iLoc);
  1230. if (argc == 0) {
  1231. return BigDecimal_to_i(ToValue(c));
  1232. }
  1233. return ToValue(c);
  1234. }
  1235. /* call-seq:
  1236. * truncate(n)
  1237. *
  1238. * Truncate to the nearest 1, returning the result as a BigDecimal.
  1239. *
  1240. * BigDecimal('3.14159').truncate -> 3
  1241. *
  1242. * BigDecimal('8.7').truncate -> 8
  1243. *
  1244. * If n is specified and positive, the fractional part of the result has no
  1245. * more than that many digits.
  1246. *
  1247. * If n is specified and negative, at least that many digits to the left of the
  1248. * decimal point will be 0 in the result.
  1249. *
  1250. * BigDecimal('3.14159').truncate(3) -> 3.141
  1251. *
  1252. * BigDecimal('13345.234').truncate(-2) -> 13300.0
  1253. */
  1254. static VALUE
  1255. BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
  1256. {
  1257. ENTER(5);
  1258. Real *c, *a;
  1259. int iLoc;
  1260. VALUE vLoc;
  1261. size_t mx, pl = VpSetPrecLimit(0);
  1262. if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
  1263. iLoc = 0;
  1264. } else {
  1265. Check_Type(vLoc, T_FIXNUM);
  1266. iLoc = FIX2INT(vLoc);
  1267. }
  1268. GUARD_OBJ(a,GetVpValue(self,1));
  1269. mx = a->Prec *(VpBaseFig() + 1);
  1270. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1271. VpSetPrecLimit(pl);
  1272. VpActiveRound(c,a,VP_ROUND_DOWN,iLoc); /* 0: truncate */
  1273. if (argc == 0) {
  1274. return BigDecimal_to_i(ToValue(c));
  1275. }
  1276. return ToValue(c);
  1277. }
  1278. /* Return the fractional part of the number.
  1279. */
  1280. static VALUE
  1281. BigDecimal_frac(VALUE self)
  1282. {
  1283. ENTER(5);
  1284. Real *c, *a;
  1285. size_t mx;
  1286. GUARD_OBJ(a,GetVpValue(self,1));
  1287. mx = a->Prec *(VpBaseFig() + 1);
  1288. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1289. VpFrac(c, a);
  1290. return ToValue(c);
  1291. }
  1292. /* call-seq:
  1293. * floor(n)
  1294. *
  1295. * Return the largest integer less than or equal to the value, as a BigDecimal.
  1296. *
  1297. * BigDecimal('3.14159').floor -> 3
  1298. *
  1299. * BigDecimal('-9.1').floor -> -10
  1300. *
  1301. * If n is specified and positive, the fractional part of the result has no
  1302. * more than that many digits.
  1303. *
  1304. * If n is specified and negative, at least that
  1305. * many digits to the left of the decimal point will be 0 in the result.
  1306. *
  1307. * BigDecimal('3.14159').floor(3) -> 3.141
  1308. *
  1309. * BigDecimal('13345.234').floor(-2) -> 13300.0
  1310. */
  1311. static VALUE
  1312. BigDecimal_floor(int argc, VALUE *argv, VALUE self)
  1313. {
  1314. ENTER(5);
  1315. Real *c, *a;
  1316. int iLoc;
  1317. VALUE vLoc;
  1318. size_t mx, pl = VpSetPrecLimit(0);
  1319. if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
  1320. iLoc = 0;
  1321. } else {
  1322. Check_Type(vLoc, T_FIXNUM);
  1323. iLoc = FIX2INT(vLoc);
  1324. }
  1325. GUARD_OBJ(a,GetVpValue(self,1));
  1326. mx = a->Prec *(VpBaseFig() + 1);
  1327. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1328. VpSetPrecLimit(pl);
  1329. VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);
  1330. #ifdef BIGDECIMAL_DEBUG
  1331. VPrint(stderr, "floor: c=%\n", c);
  1332. #endif
  1333. if (argc == 0) {
  1334. return BigDecimal_to_i(ToValue(c));
  1335. }
  1336. return ToValue(c);
  1337. }
  1338. /* call-seq:
  1339. * ceil(n)
  1340. *
  1341. * Return the smallest integer greater than or equal to the value, as a BigDecimal.
  1342. *
  1343. * BigDecimal('3.14159').ceil -> 4
  1344. *
  1345. * BigDecimal('-9.1').ceil -> -9
  1346. *
  1347. * If n is specified and positive, the fractional part of the result has no
  1348. * more than that many digits.
  1349. *
  1350. * If n is specified and negative, at least that
  1351. * many digits to the left of the decimal point will be 0 in the result.
  1352. *
  1353. * BigDecimal('3.14159').ceil(3) -> 3.142
  1354. *
  1355. * BigDecimal('13345.234').ceil(-2) -> 13400.0
  1356. */
  1357. static VALUE
  1358. BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
  1359. {
  1360. ENTER(5);
  1361. Real *c, *a;
  1362. int iLoc;
  1363. VALUE vLoc;
  1364. size_t mx, pl = VpSetPrecLimit(0);
  1365. if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
  1366. iLoc = 0;
  1367. } else {
  1368. Check_Type(vLoc, T_FIXNUM);
  1369. iLoc = FIX2INT(vLoc);
  1370. }
  1371. GUARD_OBJ(a,GetVpValue(self,1));
  1372. mx = a->Prec *(VpBaseFig() + 1);
  1373. GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
  1374. VpSetPrecLimit(pl);
  1375. VpActiveRound(c,a,VP_ROUND_CEIL,iLoc);
  1376. if (argc == 0) {
  1377. return BigDecimal_to_i(ToValue(c));
  1378. }
  1379. return ToValue(c);
  1380. }
  1381. /* call-seq:
  1382. * to_s(s)
  1383. *
  1384. * Converts the value to a string.
  1385. *
  1386. * The default format looks like 0.xxxxEnn.
  1387. *
  1388. * The optional parameter s consists of either an integer; or an optional '+'
  1389. * or ' ', followed by an optional number, followed by an optional 'E' or 'F'.
  1390. *
  1391. * If there is a '+' at the start of s, positive values are returned with
  1392. * a leading '+'.
  1393. *
  1394. * A space at the start of s returns positive values with a leading space.
  1395. *
  1396. * If s contains a number, a space is inserted after each group of that many
  1397. * fractional digits.
  1398. *
  1399. * If s ends with an 'E', engineering notation (0.xxxxEnn) is used.
  1400. *
  1401. * If s ends with an 'F', conventional floating point notation is used.
  1402. *
  1403. * Examples:
  1404. *
  1405. * BigDecimal.new('-123.45678901234567890').to_s('5F') -> '-123.45678 90123 45678 9'
  1406. *
  1407. * BigDecimal.new('123.45678901234567890').to_s('+8F') -> '+123.45678901 23456789'
  1408. *
  1409. * BigDecimal.new('123.45678901234567890').to_s(' F') -> ' 123.4567890123456789'
  1410. */
  1411. static VALUE
  1412. BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
  1413. {
  1414. ENTER(5);
  1415. int fmt=0; /* 0:E format */
  1416. int fPlus=0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */
  1417. Real *vp;
  1418. volatile VALUE str;
  1419. char *psz;
  1420. char ch;
  1421. size_t nc, mc = 0;
  1422. VALUE f;
  1423. GUARD_OBJ(vp,GetVpValue(self,1));
  1424. if(rb_scan_args(argc,argv,"01",&f)==1) {
  1425. if(TYPE(f)==T_STRING) {
  1426. SafeStringValue(f);
  1427. psz = RSTRING_PTR(f);
  1428. if(*psz==' ') {
  1429. fPlus = 1; psz++;
  1430. } else if(*psz=='+') {
  1431. fPlus = 2; psz++;
  1432. }
  1433. while((ch=*psz++)!=0) {
  1434. if(ISSPACE(ch)) continue;
  1435. if(!ISDIGIT(ch)) {
  1436. if(ch=='F' || ch=='f') fmt = 1; /* F format */
  1437. break;
  1438. }
  1439. mc = mc * 10 + ch - '0';
  1440. }
  1441. }
  1442. else {
  1443. mc = (size_t)GetPositiveInt(f);
  1444. }
  1445. }
  1446. if(fmt) {
  1447. nc = VpNumOfChars(vp,"F");
  1448. } else {
  1449. nc = VpNumOfChars(vp,"E");
  1450. }
  1451. if(mc>0) nc += (nc + mc - 1) / mc + 1;
  1452. str = rb_str_new(0, nc);
  1453. psz = RSTRING_PTR(str);
  1454. if(fmt) {
  1455. VpToFString(vp, psz, mc, fPlus);
  1456. } else {
  1457. VpToString (vp, psz, mc, fPlus);
  1458. }
  1459. rb_str_resize(str, strlen(psz));
  1460. return str;
  1461. }
  1462. /* Splits a BigDecimal number into four parts, returned as an array of values.
  1463. *
  1464. * The first value represents the sign of the BigDecimal, and is -1 or 1, or 0
  1465. * if the BigDecimal is Not a Number.
  1466. *
  1467. * The second value is a string representing the significant digits of the
  1468. * BigDecimal, with no leading zeros.
  1469. *
  1470. * The third value is the base used for arithmetic (currently always 10) as an
  1471. * Integer.
  1472. *
  1473. * The fourth value is an Integer exponent.
  1474. *
  1475. * If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the
  1476. * string of significant digits with no leading zeros, and n is the exponent.
  1477. *
  1478. * From these values, you can translate a BigDecimal to a float as follows:
  1479. *
  1480. * sign, significant_digits, base, exponent = a.split
  1481. * f = sign * "0.#{significant_digits}".to_f * (base ** exponent)
  1482. *
  1483. * (Note that the to_f method is provided as a more convenient way to translate
  1484. * a BigDecimal to a Float.)
  1485. */
  1486. static VALUE
  1487. BigDecimal_split(VALUE self)
  1488. {
  1489. ENTER(5);
  1490. Real *vp;
  1491. VALUE obj,str;
  1492. ssize_t e, s;
  1493. char *psz1;
  1494. GUARD_OBJ(vp,GetVpValue(self,1));
  1495. str = rb_str_new(0, VpNumOfChars(vp,"E"));
  1496. psz1 = RSTRING_PTR(str);
  1497. VpSzMantissa(vp,psz1);
  1498. s = 1;
  1499. if(psz1[0]=='-') {
  1500. size_t len = strlen(psz1+1);
  1501. memmove(psz1, psz1+1, len);
  1502. psz1[len] = '\0';
  1503. s = -1;
  1504. }
  1505. if(psz1[0]=='N') s=0; /* NaN */
  1506. e = VpExponent10(vp);
  1507. obj = rb_ary_new2(4);
  1508. rb_ary_push(obj, INT2FIX(s));
  1509. rb_ary_push(obj, str);
  1510. rb_str_resize(str, strlen(psz1));
  1511. rb_ary_push(obj, INT2FIX(10));
  1512. rb_ary_push(obj, INT2NUM(e));
  1513. return obj;
  1514. }
  1515. /* Returns the exponent of the BigDecimal number, as an Integer.
  1516. *
  1517. * If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string
  1518. * of digits with no leading zeros, then n is the exponent.
  1519. */
  1520. static VALUE
  1521. BigDecimal_exponent(VALUE self)
  1522. {
  1523. ssize_t e = VpExponent10(GetVpValue(self, 1));
  1524. return INT2NUM(e);
  1525. }
  1526. /* Returns debugging information about the value as a string of comma-separated
  1527. * values in angle brackets with a leading #:
  1528. *
  1529. * BigDecimal.new("1234.5678").inspect ->
  1530. * "#<BigDecimal:b7ea1130,'0.12345678E4',8(12)>"
  1531. *
  1532. * The first part is the address, the second is the value as a string, and
  1533. * the final part ss(mm) is the current number of significant digits and the
  1534. * maximum number of significant digits, respectively.
  1535. */
  1536. static VALUE
  1537. BigDecimal_inspect(VALUE self)
  1538. {
  1539. ENTER(5);
  1540. Real *vp;
  1541. volatile VALUE obj;
  1542. size_t nc;
  1543. char *psz, *tmp;
  1544. GUARD_OBJ(vp,GetVpValue(self,1));
  1545. nc = VpNumOfChars(vp,"E");
  1546. nc +=(nc + 9) / 10;
  1547. obj = rb_str_new(0, nc+256);
  1548. psz = RSTRING_PTR(obj);
  1549. sprintf(psz,"#<BigDecimal:%"PRIxVALUE",'",self);
  1550. tmp = psz + strlen(psz);
  1551. VpToString(vp, tmp, 10, 0);
  1552. tmp += strlen(tmp);
  1553. sprintf(tmp, "',%"PRIuSIZE"(%"PRIuSIZE")>", VpPrec(vp)*VpBaseFig(), VpMaxPrec(vp)*VpBaseFig());
  1554. rb_str_resize(obj, strlen(psz));
  1555. return obj;
  1556. }
  1557. /* call-seq:
  1558. * power(n)
  1559. *
  1560. * Returns the value raised to the power of n. Note that n must be an Integer.
  1561. *
  1562. * Also available as the operator **
  1563. */
  1564. static VALUE
  1565. BigDecimal_power(VALUE self, VALUE p)
  1566. {
  1567. ENTER(5);
  1568. Real *x, *y;
  1569. ssize_t mp, ma;
  1570. SIGNED_VALUE n;
  1571. Check_Type(p, T_FIXNUM);
  1572. n = FIX2INT(p);
  1573. ma = n;
  1574. if (ma < 0) ma = -ma;
  1575. if (ma == 0) ma = 1;
  1576. GUARD_OBJ(x, GetVpValue(self, 1));
  1577. if (VpIsDef(x)) {
  1578. mp = x->Prec * (VpBaseFig() + 1);
  1579. GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0"));
  1580. }
  1581. else {
  1582. GUARD_OBJ(y, VpCreateRbObject(1, "0"));
  1583. }
  1584. VpPower(y, x, n);
  1585. return ToValue(y);
  1586. }
  1587. static VALUE
  1588. BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
  1589. {
  1590. ENTER(5);
  1591. Real *pv;
  1592. size_t mf;
  1593. VALUE nFig;
  1594. VALUE iniValue;
  1595. if(rb_scan_args(argc,argv,"11",&iniValue,&nFig)==1) {
  1596. mf = 0;
  1597. } else {
  1598. mf = GetPositiveInt(nFig);
  1599. }
  1600. SafeStringValue(iniValue);
  1601. GUARD_OBJ(pv,VpCreateRbObject(mf, RSTRING_PTR(iniValue)));
  1602. return ToValue(pv);
  1603. }
  1604. /* call-seq:
  1605. * new(initial, digits)
  1606. *
  1607. * Create a new BigDecimal object.
  1608. *
  1609. * initial:: The initial value, as a String. Spaces are ignored, unrecognized characters terminate the value.
  1610. *
  1611. * digits:: The number of significant digits, as a Fixnum. If omitted or 0, the number of significant digits is determined from the initial value.
  1612. *
  1613. * The actual number of significant digits used in computation is usually
  1614. * larger than the specified number.
  1615. */
  1616. static VALUE
  1617. BigDecimal_new(int argc, VALUE *argv, VALUE self)
  1618. {
  1619. ENTER(5);
  1620. Real *pv;
  1621. size_t mf;
  1622. VALUE nFig;
  1623. VALUE iniValue;
  1624. if(rb_scan_args(argc,argv,"11",&iniValue,&nFig)==1) {
  1625. mf = 0;
  1626. } else {
  1627. mf = GetPositiveInt(nFig);
  1628. }
  1629. SafeStringValue(iniValue);
  1630. GUARD_OBJ(pv,VpNewRbClass(mf, RSTRING_PTR(iniValue),self));
  1631. return ToValue(pv);
  1632. }
  1633. /* call-seq:
  1634. * BigDecimal.limit(digits)
  1635. *
  1636. * Limit the number of significant digits in newly created BigDecimal
  1637. * numbers to the specified value. Rounding is performed as necessary,
  1638. * as specified by BigDecimal.mode.
  1639. *
  1640. * A limit of 0, the default, means no upper limit.
  1641. *
  1642. * The limit specified by this method takes less priority over any limit
  1643. * specified to instance methods such as ceil, floor, truncate, or round.
  1644. */
  1645. static VALUE
  1646. BigDecimal_limit(int argc, VALUE *argv, VALUE self)
  1647. {
  1648. VALUE nFig;
  1649. VALUE nCur = INT2NUM(VpGetPrecLimit());
  1650. if(rb_scan_args(argc,argv,"01",&nFig)==1) {
  1651. int nf;
  1652. if(nFig==Qnil) return nCur;
  1653. Check_Type(nFig, T_FIXNUM);
  1654. nf = FIX2INT(nFig);
  1655. if(nf<0) {
  1656. rb_raise(rb_eArgError, "argument must be positive");
  1657. }
  1658. VpSetPrecLimit(nf);
  1659. }
  1660. return nCur;
  1661. }
  1662. /* Returns the sign of the value.
  1663. *
  1664. * Returns a positive value if > 0, a negative value if < 0, and a
  1665. * zero if == 0.
  1666. *
  1667. * The specific value returned indicates the type and sign of the BigDecimal,
  1668. * as follows:
  1669. *
  1670. * BigDecimal::SIGN_NaN:: value is Not a Number
  1671. * BigDecimal::SIGN_POSITIVE_ZERO:: value is +0
  1672. * BigDecimal::SIGN_NEGATIVE_ZERO:: value is -0
  1673. * BigDecimal::SIGN_POSITIVE_INFINITE:: value is +infinity
  1674. * BigDecimal::SIGN_NEGATIVE_INFINITE:: value is -infinity
  1675. * BigDecimal::SIGN_POSITIVE_FINITE:: value is positive
  1676. * BigDecimal::SIGN_NEGATIVE_FINITE:: value is negative
  1677. */
  1678. static VALUE
  1679. BigDecimal_sign(VALUE self)
  1680. { /* sign */
  1681. int s = GetVpValue(self,1)->sign;
  1682. return INT2FIX(s);
  1683. }
  1684. /* call-seq:
  1685. * BigDecimal.save_exception_mode { ... }
  1686. */
  1687. static VALUE
  1688. BigDecimal_save_exception_mode(VALUE self)
  1689. {
  1690. unsigned short const exception_mode = VpGetException();
  1691. int state;
  1692. VALUE ret = rb_protect(rb_yield, Qnil, &state);
  1693. VpSetException(exception_mode);
  1694. if (state) rb_jump_tag(state);
  1695. return ret;
  1696. }
  1697. /* call-seq:
  1698. * BigDecimal.save_rounding_mode { ... }
  1699. */
  1700. static VALUE
  1701. BigDecimal_save_rounding_mode(VALUE self)
  1702. {
  1703. unsigned short const round_mode = VpGetRoundMode();
  1704. int state;
  1705. VALUE ret = rb_protect(rb_yield, Qnil, &state);
  1706. VpSetRoundMode(round_mode);
  1707. if (state) rb_jump_tag(state);
  1708. return Qnil;
  1709. }
  1710. /* call-seq:
  1711. * BigDecimal.save_limit { ... }
  1712. */
  1713. static VALUE
  1714. BigDecimal_save_limit(VALUE self)
  1715. {
  1716. size_t const limit = VpGetPrecLimit();
  1717. int state;
  1718. VALUE ret = rb_protect(rb_yield, Qnil, &state);
  1719. VpSetPrecLimit(limit);
  1720. if (state) rb_jump_tag(state);
  1721. return Qnil;
  1722. }
  1723. /* Document-class: BigDecimal
  1724. * BigDecimal provides arbitrary-precision floating point decimal arithmetic.
  1725. *
  1726. * Copyright (C) 2002 by Shigeo Kobayashi <shigeo@tinyforest.gr.jp>.
  1727. * You may distribute under the terms of either the GNU General Public
  1728. * License or the Artistic License, as specified in the README file
  1729. * of the BigDecimal distribution.
  1730. *
  1731. * Documented by mathew <meta@pobox.com>.
  1732. *
  1733. * = Introduction
  1734. *
  1735. * Ruby provides built-in support for arbitrary precision integer arithmetic.
  1736. * For example:
  1737. *
  1738. * 42**13 -> 1265437718438866624512
  1739. *
  1740. * BigDecimal provides similar support for very large or very accurate floating
  1741. * point numbers.
  1742. *
  1743. * Decimal arithmetic is also useful for general calculation, because it
  1744. * provides the correct answers people expect--whereas normal binary floating
  1745. * point arithmetic often introduces subtle errors because of the conversion
  1746. * between base 10 and base 2. For example, try:
  1747. *
  1748. * sum = 0
  1749. * for i in (1..10000)
  1750. * sum = sum + 0.0001
  1751. * end
  1752. * print sum
  1753. *
  1754. * and contrast with the output from:
  1755. *
  1756. * require 'bigdecimal'
  1757. *
  1758. * sum = BigDecimal.new("0")
  1759. * for i in (1..10000)
  1760. * sum = sum + BigDecimal.new("0.0001")
  1761. * end
  1762. * print sum
  1763. *
  1764. * Similarly:
  1765. *
  1766. * (BigDecimal.new("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") -> true
  1767. *
  1768. * (1.2 - 1.0) == 0.2 -> false
  1769. *
  1770. * = Special features of accurate decimal arithmetic
  1771. *
  1772. * Because BigDecimal is more accurate than normal binary floating point
  1773. * arithmetic, it requires some special values.
  1774. *
  1775. * == Infinity
  1776. *
  1777. * BigDecimal sometimes needs to return infinity, for example if you divide
  1778. * a value by zero.
  1779. *
  1780. * BigDecimal.new("1.0") / BigDecimal.new("0.0") -> infinity
  1781. *
  1782. * BigDecimal.new("-1.0") / BigDecimal.new("0.0") -> -infinity
  1783. *
  1784. * You can represent infinite numbers to BigDecimal using the strings
  1785. * 'Infinity', '+Infinity' and '-Infinity' (case-sensitive)
  1786. *
  1787. * == Not a Number
  1788. *
  1789. * When a computation results in an undefined value, the special value NaN
  1790. * (for 'not a number') is returned.
  1791. *
  1792. * Example:
  1793. *
  1794. * BigDecimal.new("0.0") / …

Large files files are truncated, but you can click here to view the full file