summaryrefslogtreecommitdiff
path: root/ext/bigdecimal
diff options
context:
space:
mode:
authorshigek <shigek@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-27 04:38:57 +0000
committershigek <shigek@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-06-27 04:38:57 +0000
commitd3ce235babf3a5fa9a7904c45ec193e8962fe845 (patch)
tree6d2a550cb79cddaee7a52a6aae149d1b3f0d3c16 /ext/bigdecimal
parent7e91b4b546634afa0203f7bd6d0e5092f8f7ee61 (diff)
downloadbundler-d3ce235babf3a5fa9a7904c45ec193e8962fe845.tar.gz
1.From Tadashi Saito's advice
to_parts changed to split,assign removed, ** added,bugs in infinite? & nozero? fixed. 2.Rounding functionalities added mode now accepts rounding mode. round accepts second argument for Bankers' rounding. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4008 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/bigdecimal')
-rw-r--r--ext/bigdecimal/bigdecimal.c321
-rw-r--r--ext/bigdecimal/bigdecimal.h19
-rw-r--r--ext/bigdecimal/bigdecimal_en.html507
-rw-r--r--ext/bigdecimal/bigdecimal_ja.html507
4 files changed, 740 insertions, 614 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index 62343830ac..f1bd1e2320 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -34,14 +34,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef NT
-#include <malloc.h>
-#ifdef _MSC_VER
-#include <float.h>
-#define isnan(x) _isnan(x)
-#define isinf(x) (!(_finite(x)))
-#endif /* _MSC_VER */
-#endif /* defined NT */
#include "ruby.h"
#include "math.h"
#include "version.h"
@@ -52,7 +44,7 @@ VALUE rb_cBigDecimal;
#include "bigdecimal.h"
-/* MACRO's to guard objects from GC by keeping it in stack */
+/* MACRO's to guard objects from GC by keeping them in stack */
#define ENTER(n) volatile VALUE vStack[n];int iStack=0
#define PUSH(x) vStack[iStack++] = (unsigned long)(x);
#define SAVE(p) PUSH(p->obj);
@@ -71,7 +63,9 @@ static int VpSubAbs(Real *a,Real *b,Real *c);
static U_LONG VpSetPTR(Real *a,Real *b,Real *c,U_LONG *a_pos,U_LONG *b_pos,U_LONG *c_pos,U_LONG *av,U_LONG *bv);
static int VpNmlz(Real *a);
static void VpFormatSt(char *psz,S_INT fFmt);
-static int VpRdup(Real *m);
+static int VpRdup(Real *m,U_LONG ind_m);
+static int VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v);
+
static U_LONG SkipWhiteChar(char *szVal);
/*
@@ -297,25 +291,32 @@ BigDecimal_load(VALUE self, VALUE str)
static VALUE
BigDecimal_mode(VALUE self, VALUE which, VALUE val)
{
- unsigned short fo = VpGetException();
- unsigned short f;
-
- if(TYPE(which)!=T_FIXNUM) return INT2FIX(fo);
- if(val!=Qfalse && val!=Qtrue) return INT2FIX(fo);
+ unsigned long f,fo;
+
+ if(TYPE(which)!=T_FIXNUM) return Qnil;
+ f = (unsigned long)FIX2INT(which);
- f = (unsigned short)FIX2INT(which);
- if(f&VP_EXCEPTION_INFINITY) {
+ if(f&VP_EXCEPTION_ALL) {
+ /* Exception mode setting */
fo = VpGetException();
- VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):
- (fo&(~VP_EXCEPTION_INFINITY))));
+ if(val!=Qfalse && val!=Qtrue) return Qnil;
+ if(f&VP_EXCEPTION_INFINITY) {
+ VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):
+ (fo&(~VP_EXCEPTION_INFINITY))));
+ }
+ if(f&VP_EXCEPTION_NaN) {
+ VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):
+ (fo&(~VP_EXCEPTION_NaN))));
+ }
+ return INT2FIX(fo);
}
- if(f&VP_EXCEPTION_NaN) {
- fo = VpGetException();
- VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):
- (fo&(~VP_EXCEPTION_NaN))));
+ if(VP_COMP_MODE==f) {
+ /* Computaion mode setting */
+ if(TYPE(val)!=T_FIXNUM) return Qnil;
+ fo = VpSetCompMode((unsigned long)FIX2INT(val));
+ return INT2FIX(fo);
}
- fo = VpGetException();
- return INT2FIX(fo);
+ return Qnil;
}
static U_LONG
@@ -380,8 +381,9 @@ static VALUE
BigDecimal_IsInfinite(VALUE self)
{
Real *p = GetVpValue(self,1);
- if(VpIsInf(p)) return Qtrue;
- return Qfalse;
+ if(VpIsPosInf(p)) return INT2FIX(1);
+ if(VpIsNegInf(p)) return INT2FIX(-1);
+ return Qnil;
}
static VALUE
@@ -547,7 +549,7 @@ static VALUE
BigDecimal_nonzero(VALUE self)
{
Real *a = GetVpValue(self,1);
- return VpIsZero(a) ? Qfalse : self;
+ return VpIsZero(a) ? Qnil : self;
}
static VALUE
@@ -650,6 +652,7 @@ BigDecimal_mult(VALUE self, VALUE r)
static VALUE
BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
+/* For c,res = self.div(r): no round operation */
{
ENTER(5);
Real *a, *b;
@@ -669,16 +672,19 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r)
static VALUE
BigDecimal_div(VALUE self, VALUE r)
+/* For c = self/r: with round operation */
{
ENTER(5);
Real *c=NULL, *res=NULL, *div = NULL;
r = BigDecimal_divide(&c, &res, &div, self, r);
SAVE(c);SAVE(res);SAVE(div);
if(r!=(VALUE)0) return r; /* coerced by other */
- if(res->frac[0]*2>=div->frac[0]) {
- /* Round up */
- VpRdup(c);
- }
+ /* a/b = c + r/b */
+ /* c xxxxx
+ r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
+ */
+ /* Round up ? */
+ VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]);
return ToValue(c);
}
@@ -707,7 +713,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
VpDivd(c, res, a, b);
mx = c->Prec *(VpBaseFig() + 1);
GUARD_OBJ(d,VpCreateRbObject(mx, "0"));
- VpRound(d,c,1,3,0);
+ VpActiveRound(d,c,VP_COMP_MODE_FLOOR,0);
VpMult(res,d,b);
VpAddSub(c,a,res,-1);
*div = d;
@@ -754,7 +760,7 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv)
GUARD_OBJ(d,VpCreateRbObject(mx, "0"));
GUARD_OBJ(f,VpCreateRbObject(mx, "0"));
- VpRound(d,c,1,1,0); /* 1: round off */
+ VpActiveRound(d,c,VP_COMP_MODE_TRUNCATE,0); /* 0: round off */
VpFrac(f, c);
VpMult(rr,f,b);
@@ -814,20 +820,6 @@ BigDecimal_divmod2(VALUE self, VALUE b, VALUE n)
}
static VALUE
-BigDecimal_assign2(VALUE self, VALUE n, VALUE f)
-{
- ENTER(5);
- Real *cv;
- Real *av;
- U_LONG mx = (U_LONG)GetPositiveInt(n);
- Check_Type(f, T_FIXNUM);
- GUARD_OBJ(cv,VpCreateRbObject(mx,"0"));
- GUARD_OBJ(av,GetVpValue(self,1));
- VpAsgn(cv,av,FIX2INT(f));
- return ToValue(cv);
-}
-
-static VALUE
BigDecimal_add2(VALUE self, VALUE b, VALUE n)
{
ENTER(5);
@@ -928,7 +920,7 @@ BigDecimal_fix(VALUE self)
GUARD_OBJ(a,GetVpValue(self,1));
mx = a->Prec *(VpBaseFig() + 1);
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
- VpRound(c,a,1,1,0); /* 1: round off */
+ VpActiveRound(c,a,VP_COMP_MODE_TRUNCATE,0); /* 0: round off */
return ToValue(c);
}
@@ -941,19 +933,29 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
int sw;
U_LONG mx;
VALUE vLoc;
-
- if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
+ VALUE vBanker;
+ int na = rb_scan_args(argc,argv,"02",&vLoc,&vBanker);
+ sw = VP_COMP_MODE_ROUNDUP; /* round up */
+ switch(na) {
+ case 0:
iLoc = 0;
- } else {
+ break;
+ case 1:
+ Check_Type(vLoc, T_FIXNUM);
+ iLoc = FIX2INT(vLoc);
+ break;
+ case 2:
Check_Type(vLoc, T_FIXNUM);
iLoc = FIX2INT(vLoc);
+ Check_Type(vBanker, T_FIXNUM);
+ if(FIX2INT(vBanker)) sw = VP_COMP_MODE_EVEN; /* Banker's rounding */
+ break;
}
- sw = 2;
GUARD_OBJ(a,GetVpValue(self,1));
mx = a->Prec *(VpBaseFig() + 1);
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
- VpRound(c,a,sw,1,iLoc);
+ VpActiveRound(c,a,sw,iLoc);
return ToValue(c);
}
@@ -973,12 +975,11 @@ BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
Check_Type(vLoc, T_FIXNUM);
iLoc = FIX2INT(vLoc);
}
- sw = 1; /* truncate */
GUARD_OBJ(a,GetVpValue(self,1));
mx = a->Prec *(VpBaseFig() + 1);
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
- VpRound(c,a,sw,1,iLoc);
+ VpActiveRound(c,a,VP_COMP_MODE_TRUNCATE,iLoc); /* 0: truncate */
return ToValue(c);
}
@@ -1015,7 +1016,7 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
GUARD_OBJ(a,GetVpValue(self,1));
mx = a->Prec *(VpBaseFig() + 1);
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
- VpRound(c,a,1,3,iLoc);
+ VpActiveRound(c,a,VP_COMP_MODE_FLOOR,iLoc);
return ToValue(c);
}
@@ -1038,7 +1039,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
GUARD_OBJ(a,GetVpValue(self,1));
mx = a->Prec *(VpBaseFig() + 1);
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
- VpRound(c,a,1,2,iLoc);
+ VpActiveRound(c,a,VP_COMP_MODE_CEIL,iLoc);
return ToValue(c);
}
@@ -1064,7 +1065,7 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
}
static VALUE
-BigDecimal_to_parts(VALUE self)
+BigDecimal_split(VALUE self)
{
ENTER(5);
Real *vp;
@@ -1366,8 +1367,10 @@ Init_bigdecimal(void)
rb_define_singleton_method(rb_cBigDecimal, "induced_from",BigDecimal_induced_from, 1);
rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1);
- /* Constants */
+ /* Constants definition */
rb_define_const(rb_cBigDecimal, "BASE", INT2FIX((S_INT)VpBaseVal()));
+
+ /* Exceptions */
rb_define_const(rb_cBigDecimal, "EXCEPTION_ALL",INT2FIX(VP_EXCEPTION_ALL));
rb_define_const(rb_cBigDecimal, "EXCEPTION_NaN",INT2FIX(VP_EXCEPTION_NaN));
rb_define_const(rb_cBigDecimal, "EXCEPTION_INFINITY",INT2FIX(VP_EXCEPTION_INFINITY));
@@ -1375,6 +1378,14 @@ Init_bigdecimal(void)
rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW",INT2FIX(VP_EXCEPTION_OVERFLOW));
rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE",INT2FIX(VP_EXCEPTION_ZERODIVIDE));
+ /* Computation mode */
+ rb_define_const(rb_cBigDecimal, "COMP_MODE",INT2FIX(VP_COMP_MODE));
+ rb_define_const(rb_cBigDecimal, "COMP_MODE_TRUNCATE",INT2FIX(VP_COMP_MODE_TRUNCATE));
+ rb_define_const(rb_cBigDecimal, "COMP_MODE_ROUNDUP",INT2FIX(VP_COMP_MODE_ROUNDUP));
+ rb_define_const(rb_cBigDecimal, "COMP_MODE_CEIL",INT2FIX(VP_COMP_MODE_CEIL));
+ rb_define_const(rb_cBigDecimal, "COMP_MODE_FLOOR",INT2FIX(VP_COMP_MODE_FLOOR));
+ rb_define_const(rb_cBigDecimal, "COMP_MODE_EVEN",INT2FIX(VP_COMP_MODE_EVEN));
+
/* Constants for sign value */
rb_define_const(rb_cBigDecimal, "SIGN_NaN",INT2FIX(VP_SIGN_NaN));
rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_ZERO",INT2FIX(VP_SIGN_POSITIVE_ZERO));
@@ -1386,7 +1397,6 @@ Init_bigdecimal(void)
/* instance methods */
rb_define_method(rb_cBigDecimal, "prec", BigDecimal_prec, 0);
- rb_define_method(rb_cBigDecimal, "assign", BigDecimal_assign2, 2);
rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2);
rb_define_method(rb_cBigDecimal, "mult", BigDecimal_mult2, 2);
@@ -1394,7 +1404,7 @@ Init_bigdecimal(void)
rb_define_method(rb_cBigDecimal, "hash", BigDecimal_hash, 0);
rb_define_method(rb_cBigDecimal, "to_s", BigDecimal_to_s, -1);
rb_define_method(rb_cBigDecimal, "to_i", BigDecimal_to_i, 0);
- rb_define_method(rb_cBigDecimal, "to_parts", BigDecimal_to_parts, 0);
+ rb_define_method(rb_cBigDecimal, "split", BigDecimal_split, 0);
rb_define_method(rb_cBigDecimal, "+", BigDecimal_add, 1);
rb_define_method(rb_cBigDecimal, "-", BigDecimal_sub, 1);
rb_define_method(rb_cBigDecimal, "+@", BigDecimal_uplus, 0);
@@ -1415,6 +1425,7 @@ Init_bigdecimal(void)
rb_define_method(rb_cBigDecimal, "floor", BigDecimal_floor, -1);
rb_define_method(rb_cBigDecimal, "ceil", BigDecimal_ceil, -1);
rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, 1);
+ rb_define_method(rb_cBigDecimal, "**", BigDecimal_power, 1);
rb_define_method(rb_cBigDecimal, "exp", BigDecimal_exp, 1);
rb_define_method(rb_cBigDecimal, "sincos", BigDecimal_sincos, 1);
rb_define_method(rb_cBigDecimal, "<=>", BigDecimal_comp, 1);
@@ -1462,6 +1473,8 @@ static int gfCheckVal = 1; /* Value checking flag in VpNmlz() */
#endif /* _DEBUG */
static U_LONG gnPrecLimit = 0; /* Global upper limit of the precision newly allocated */
+static short gfCompMode = VP_COMP_MODE_ROUNDUP; /* Mode for general computation */
+
static U_LONG BASE_FIG = 4; /* =log10(BASE) */
static U_LONG BASE = 10000L; /* Base value(value must be 10**BASE_FIG) */
/* The value of BASE**2 + BASE must be represented */
@@ -1544,6 +1557,22 @@ VpSetPrecLimit(U_LONG n)
return s;
}
+VP_EXPORT unsigned long
+VpGetCompMode(void)
+{
+ return gfCompMode;
+}
+
+VP_EXPORT unsigned long
+VpSetCompMode(unsigned long n)
+{
+ unsigned long s = gfCompMode;
+ if(n!=VP_COMP_MODE_TRUNCATE && n!= VP_COMP_MODE_ROUNDUP && n!=VP_COMP_MODE_CEIL &&
+ n!=VP_COMP_MODE_FLOOR && n!= VP_COMP_MODE_EVEN) return s;
+ gfCompMode = n;
+ return s;
+}
+
/*
* 0.0 & 1.0 generator
* These gZero_..... and gOne_..... can be any name
@@ -1552,8 +1581,8 @@ VpSetPrecLimit(U_LONG n)
* (to let the compiler know they may be changed in outside
* (... but not actually..)).
*/
-double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
-double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
+volatile double gZero_ABCED9B1_CE73__00400511F31D = 0.0;
+volatile double gOne_ABCED9B4_CE73__00400511F31D = 1.0;
static double
Zero(void)
{
@@ -1969,10 +1998,10 @@ VpAlloc(U_LONG mx, char *szVal)
++i;
++ni;
}
- nf = 0;
+ nf = 0;
ipf = 0;
ipe = 0;
- ne = 0;
+ ne = 0;
if(v) {
/* other than digit nor \0 */
if(szVal[i] == '.') { /* xxx. */
@@ -2023,11 +2052,10 @@ VpAlloc(U_LONG mx, char *szVal)
* [Input]
* a ... RHSV
* isw ... switch for assignment.
- * c = a when isw = 1 or 2
- * c = -a when isw = -1 or -1
- * when |isw|==1
- * if c->MaxPrec < a->Prec,then round up
- * will not be performed.
+ * c = a when isw > 0
+ * c = -a when isw < 0
+ * if c->MaxPrec < a->Prec,then round operation
+ * will be performed.
* [Output]
* c ... LHSV
*/
@@ -2051,22 +2079,19 @@ VpAsgn(Real *c, Real *a, int isw)
n =(a->Prec < c->MaxPrec) ?(a->Prec) :(c->MaxPrec);
c->Prec = n;
for(j=0;j < n; ++j) c->frac[j] = a->frac[j];
- if(isw < 0) isw = -isw;
- if(isw == 2) {
- if(a->MaxPrec>n) {
- if((c->Prec < a->Prec) &&
- (a->frac[n] >= HALF_BASE)) VpRdup(c); /* round up/off */
- }
+ /* Needs round ? */
+ if(c->Prec < a->Prec) {
+ VpInternalRound(c,n,(n>0)?a->frac[n-1]:0,a->frac[n]);
}
} else {
/* The value of 'a' is zero. */
VpSetZero(c,isw*VpGetSign(a));
return 1;
}
- VpNmlz(c);
return c->Prec*BASE_FIG;
}
+
/*
* c = a + b when operation = 1 or 2
* = a - b when operation = -1 or -2.
@@ -2113,7 +2138,7 @@ VpAddSub(Real *c, Real *a, Real *b, int operation)
}
if(operation < 0) sw = -1;
- else sw = 1;
+ else sw = 1;
/* compare absolute value. As a result,|a_ptr|>=|b_ptr| */
if(a->exponent > b->exponent) {
@@ -2202,7 +2227,6 @@ static int
VpAddAbs(Real *a, Real *b, Real *c)
{
U_LONG word_shift;
- U_LONG round;
U_LONG carry;
U_LONG ap;
U_LONG bp;
@@ -2210,7 +2234,7 @@ VpAddAbs(Real *a, Real *b, Real *c)
U_LONG a_pos;
U_LONG b_pos;
U_LONG c_pos;
- U_LONG av, bv;
+ U_LONG av, bv, mrv;
#ifdef _DEBUG
if(gfDebug) {
@@ -2226,7 +2250,7 @@ VpAddAbs(Real *a, Real *b, Real *c)
if(word_shift==-1L) return 0; /* Overflow */
if(b_pos == -1L) goto Assign_a;
- round =((av + bv) >= HALF_BASE) ? 1 : 0;
+ mrv = av + bv; /* Most right val. Used for round. */
/* Just assign the last few digits of b to c because a has no */
/* corresponding digits to be added. */
@@ -2281,8 +2305,7 @@ VpAddAbs(Real *a, Real *b, Real *c)
}
if(c_pos) c->frac[c_pos - 1] += carry;
- if(round) VpRdup(c); /* Roundup and normalize. */
- else VpNmlz(c); /* normalize the result */
+ if(!VpInternalRound(c,0,(c->Prec>0)?a->frac[c->Prec-1]:0,mrv)) VpNmlz(c);
goto Exit;
Assign_a:
@@ -2305,7 +2328,7 @@ static int
VpSubAbs(Real *a, Real *b, Real *c)
{
U_LONG word_shift;
- U_LONG round;
+ U_LONG mrv;
U_LONG borrow;
U_LONG ap;
U_LONG bp;
@@ -2330,10 +2353,10 @@ VpSubAbs(Real *a, Real *b, Real *c)
if(b_pos == -1L) goto Assign_a;
if(av >= bv) {
- round =((av -= bv) >= HALF_BASE) ? 1 : 0;
+ mrv = av - bv;
borrow = 0;
} else {
- round = 0;
+ mrv = 0;
borrow = 1;
}
@@ -2395,8 +2418,8 @@ VpSubAbs(Real *a, Real *b, Real *c)
}
}
if(c_pos) c->frac[c_pos - 1] -= borrow;
- if(round) VpRdup(c); /* Round up and normalize */
- else VpNmlz(c); /* normalize the result */
+
+ if(!VpInternalRound(c,0,(c->Prec>0)?a->frac[c->Prec-1]:0,mrv)) VpNmlz(c);
goto Exit;
Assign_a:
@@ -2454,7 +2477,7 @@ VpSetPTR(Real *a, Real *b, Real *c, U_LONG *a_pos, U_LONG *b_pos, U_LONG *c_pos,
/*
* a = xxxxxxAxxx
* c = xxxxxx
- * a_pos = |
+ * a_pos = |
*/
*a_pos = left_word;
*av = a->frac[*a_pos]; /* av is 'A' shown in above. */
@@ -2544,11 +2567,11 @@ VpMult(Real *c, Real *a, Real *b)
return 1; /* 0: 1 significant digit */
}
- if((a->Prec == 1) &&(a->frac[0] == 1) &&(a->exponent == 1)) {
+ if(VpIsOne(a)) {
VpAsgn(c, b, VpGetSign(a));
goto Exit;
}
- if((b->Prec == 1) &&(b->frac[0] == 1) &&(b->exponent == 1)) {
+ if(VpIsOne(b)) {
VpAsgn(c, a, VpGetSign(b));
goto Exit;
}
@@ -2624,7 +2647,7 @@ VpMult(Real *c, Real *a, Real *b)
VpNmlz(c); /* normalize the result */
if(w != NULL) { /* free work variable */
- VpAsgn(w, c, 2);
+ VpAsgn(w, c, 1);
VpFree(c);
c = w;
}
@@ -2675,8 +2698,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
VpSetZero(r,VpGetSign(a)*VpGetSign(b));
goto Exit;
}
-
- if((b->Prec == 1) &&(b->frac[0] == 1) &&(b->exponent == 1)) {
+ if(VpIsOne(b)) {
/* divide by one */
VpAsgn(c, a, VpGetSign(b));
VpSetZero(r,VpGetSign(a));
@@ -2980,6 +3002,7 @@ Exit:
return (int)val;
}
+#ifdef _DEBUG
/*
* cntl_chr ... ASCIIZ Character, print control characters
* Available control codes:
@@ -3082,6 +3105,7 @@ VPrint(FILE *fp, char *cntl_chr, Real *a)
}
return (int)nc;
}
+#endif /* _DEBUG */
static void
VpFormatSt(char *psz,S_INT fFmt)
@@ -3468,8 +3492,9 @@ VpDtoV(Real *m, double d)
}
m->Prec = ind_m + 1;
m->exponent = ne;
- if(val*((double)((S_INT)BASE)) >=(double)((S_INT)HALF_BASE)) VpRdup(m);
- VpNmlz(m);
+
+ if(!VpInternalRound(m,0,(m->Prec>0)?m->frac[m->Prec-1]:0,
+ (U_LONG)(val*((double)((S_INT)BASE))))) VpNmlz(m);
Exit:
#ifdef _DEBUG
@@ -3551,8 +3576,8 @@ VpSqrt(Real *y, Real *x)
Real *f = NULL;
Real *r = NULL;
S_LONG y_prec, f_prec;
- S_LONG n;
- S_LONG e;
+ S_LONG n;
+ S_LONG e;
S_LONG prec;
S_LONG nr;
double val;
@@ -3650,11 +3675,12 @@ Exit:
/*
*
- * f = 1: round, 2:ceil, 3: floor
+ * f = 0: Round off/Truncate, 1: round up, 2:ceil, 3: floor, 4: Banker's rounding
+ * nf: digit position for operation.
*
*/
VP_EXPORT void
-VpRound(Real *y, Real *x, int sw, int f, int nf)
+VpActiveRound(Real *y, Real *x, int f, int nf)
{
int n,i,j,ix,ioffset;
U_LONG v;
@@ -3665,35 +3691,41 @@ VpRound(Real *y, Real *x, int sw, int f, int nf)
goto Exit;
}
- /* First,assign whole value */
- VpAsgn(y, x, sw);
+ /* First,assign whole value in truncation mode */
+ VpAsgn(y, x, 1); /* 1 round off,2 round up */
nf += y->exponent*((int)BASE_FIG);
/* ix: x->fraq[ix] contains round position */
ix = (nf + ((int)BASE_FIG))/((int)BASE_FIG)-1;
if(ix<0 || ((U_LONG)ix)>=y->Prec) goto Exit; /* Unable to round */
ioffset = nf - ix*((int)BASE_FIG);
for(j=ix+1;j<(int)y->Prec;++j) y->frac[j] = 0;
- VpNmlz(y);
+ /* VpNmlz(y); */
v = y->frac[ix];
/* drop digits after pointed digit */
n = BASE_FIG - ioffset - 1;
for(i=0;i<n;++i) v /= 10;
div = v/10;
v = v - div*10;
- switch(f){
- case 1: /* Round */
- if(sw==2 && v>=5) {
- ++div;
- }
+ switch(f) {
+ case VP_COMP_MODE_TRUNCATE: /* Truncate/Round off */
+ break;
+ case VP_COMP_MODE_ROUNDUP: /* Round up */
+ if(v>=5) ++div;
break;
- case 2: /* ceil */
- if(v) {
- if(VpGetSign(x)>0) ++div;
- }
+ case VP_COMP_MODE_CEIL: /* ceil */
+ if(v && (VpGetSign(x)>0)) ++div;
+ break;
+ case VP_COMP_MODE_FLOOR: /* floor */
+ if(v && (VpGetSign(x)<0)) ++div;
break;
- case 3: /* floor */
- if(v) {
- if(VpGetSign(x)<0) ++div;
+ case VP_COMP_MODE_EVEN: /* Banker's rounding */
+ if(v>5) ++div;
+ else if(v==5) {
+ if(i==(BASE_FIG-1)) {
+ if(ix && (y->frac[ix-1]%2)) ++div;
+ } else {
+ if(div%2) ++div;
+ }
}
break;
}
@@ -3702,7 +3734,7 @@ VpRound(Real *y, Real *x, int sw, int f, int nf)
y->frac[ix] = 0;
if(ix) {
VpNmlz(y);
- VpRdup(y);
+ VpRdup(y,0);
} else {
VpSetOne(y);
VpSetSign(y,VpGetSign(x));
@@ -3715,24 +3747,51 @@ VpRound(Real *y, Real *x, int sw, int f, int nf)
Exit:
#ifdef _DEBUG
if(gfDebug) {
- VPrint(stdout, "VpRound y=%\n", y);
+ VPrint(stdout, "VpActiveRound y=%\n", y);
VPrint(stdout, " x=%\n", x);
}
#endif /*_DEBUG */
return;
}
+static int
+VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v)
+{
+ int f = 0;
+ v /= BASE1;
+ switch(gfCompMode) {
+ case VP_COMP_MODE_TRUNCATE:
+ break;
+ case VP_COMP_MODE_ROUNDUP:
+ if(v >= 5) f = 1;
+ break;
+ case VP_COMP_MODE_CEIL: /* ceil */
+ if(v && (VpGetSign(c)>0)) f = 1;
+ break;
+ case VP_COMP_MODE_FLOOR: /* floor */
+ if(v && (VpGetSign(c)<0)) f = 1;
+ break;
+ case VP_COMP_MODE_EVEN: /* Banker's rounding */
+ if(v>5) f = 1;
+ else if(v==5 && vPrev%2) f = 1;
+ break;
+ }
+ if(f) VpRdup(c,ixDigit); /* round up */
+ return f;
+}
+
/*
* Rounds up m(plus one to final digit of m).
*/
static int
-VpRdup(Real *m)
+VpRdup(Real *m,U_LONG ind_m)
{
- U_LONG ind_m, carry;
- ind_m = m->Prec;
+ U_LONG carry;
+
+ if(!ind_m) ind_m = m->Prec;
+
carry = 1;
- while(carry > 0 && ind_m) {
- --ind_m;
+ while(carry > 0 && (ind_m--)) {
m->frac[ind_m] += carry;
if(m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE;
else carry = 0;
@@ -3907,8 +3966,8 @@ VpPi(Real *y)
VpAddSub(r, y, f, 1); /* r = y + f */
VpAsgn(y, r, 1); /* y = r */
- VpRdup(n); /* n = n + 1 */
- VpRdup(n); /* n = n + 1 */
+ VpRdup(n,0); /* n = n + 1 */
+ VpRdup(n,0); /* n = n + 1 */
if(VpIsZero(f)) break;
} while((f->exponent > 0 || ((U_LONG)(-(f->exponent)) < y->MaxPrec)) &&
i1<nc
@@ -3926,8 +3985,8 @@ VpPi(Real *y)
VpAddSub(r, y, f, 1); /* r = y + f */
VpAsgn(y, r, 1); /* y = r */
- VpRdup(n); /* n = n + 1 */
- VpRdup(n); /* n = n + 1 */
+ VpRdup(n,0); /* n = n + 1 */
+ VpRdup(n,0); /* n = n + 1 */
if(VpIsZero(f)) break;
} while((f->exponent > 0 || ((U_LONG)(-(f->exponent)) < y->MaxPrec)) &&
i2<nc
@@ -3972,11 +4031,11 @@ VpExp1(Real *y)
add = VpAlloc(p, "#1"); /* add = 1 */
VpSetOne(y); /* y = 1 */
- VpRdup(y); /* y = y + 1 */
+ VpRdup(y,0); /* y = y + 1 */
i = 0;
do {
++i;
- VpRdup(n); /* n = n + 1 */
+ VpRdup(n,0); /* n = n + 1 */
VpDivd(f, r, add, n); /* f = add/n(=1/n!) */
VpAsgn(add, f, 1); /* add = 1/n! */
VpAddSub(r, y, f, 1);
@@ -4041,7 +4100,7 @@ VpExp(Real *y, Real *x)
i = 0;
do {
++i;
- VpRdup(n); /* n = n + 1 */
+ VpRdup(n,0); /* n = n + 1 */
VpDivd(div, r, x, n); /* div = x/n */
VpMult(c, z, div); /* c = x/(n-1)! * x/n */
VpAsgn(z, c, 1); /* z = x*n/n! */
@@ -4117,7 +4176,7 @@ VpSinCos(Real *psin,Real *pcos,Real *x)
i = 0;
do {
++i;
- VpRdup(n); /* n = n + 1 */
+ VpRdup(n,0); /* n = n + 1 */
VpDivd(div, r, x, n); /* div = x/n */
VpMult(c, z, div); /* c = x/(n-1)! * x/n */
VpAsgn(z, c, 1); /* z = x*n/n! */
diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h
index 8708d04b6f..3debb52826 100644
--- a/ext/bigdecimal/bigdecimal.h
+++ b/ext/bigdecimal/bigdecimal.h
@@ -32,7 +32,7 @@ extern "C" {
#define S_INT int
/* Exception codes */
-#define VP_EXCEPTION_ALL ((unsigned short)0xFFFF)
+#define VP_EXCEPTION_ALL ((unsigned short)0x00FF)
#define VP_EXCEPTION_INFINITY ((unsigned short)0x0001)
#define VP_EXCEPTION_NaN ((unsigned short)0x0002)
#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004)
@@ -43,6 +43,14 @@ extern "C" {
#define VP_EXCEPTION_OP ((unsigned short)0x0020)
#define VP_EXCEPTION_MEMORY ((unsigned short)0x0040)
+/* Computation mode */
+#define VP_COMP_MODE ((unsigned short)0x0100)
+#define VP_COMP_MODE_TRUNCATE 0
+#define VP_COMP_MODE_ROUNDUP 1
+#define VP_COMP_MODE_CEIL 2
+#define VP_COMP_MODE_FLOOR 3
+#define VP_COMP_MODE_EVEN 4
+
#define VP_SIGN_NaN 0 /* NaN */
#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */
@@ -103,6 +111,10 @@ VP_EXPORT double VpGetDoubleNegZero(void);
VP_EXPORT U_LONG VpGetPrecLimit(void);
VP_EXPORT U_LONG VpSetPrecLimit(U_LONG n);
+/* Computation mode */
+VP_EXPORT unsigned long VpGetCompMode(void);
+VP_EXPORT unsigned long VpSetCompMode(unsigned long n);
+
VP_EXPORT int VpException(unsigned short f,char *str,int always);
VP_EXPORT int VpIsNegDoubleZero(double v);
VP_EXPORT U_LONG VpNumOfChars(Real *vp);
@@ -123,14 +135,13 @@ VP_EXPORT void VpVtoD(double *d,S_LONG *e,Real *m);
VP_EXPORT void VpDtoV(Real *m,double d);
VP_EXPORT void VpItoV(Real *m,S_INT ival);
VP_EXPORT int VpSqrt(Real *y,Real *x);
-VP_EXPORT void VpRound(Real *y,Real *x,int sw,int f,int il);
+VP_EXPORT void VpActiveRound(Real *y,Real *x,int f,int il);
VP_EXPORT void VpFrac(Real *y,Real *x);
VP_EXPORT int VpPower(Real *y,Real *x,S_INT n);
VP_EXPORT void VpPi(Real *y);
VP_EXPORT void VpExp1(Real *y);
VP_EXPORT void VpExp(Real *y,Real *x);
VP_EXPORT void VpSinCos(Real *psin,Real *pcos,Real *x);
-VP_EXPORT int VPrint(FILE *fp,char *cntl_chr,Real *a);
/*
* ------------------
@@ -177,9 +188,11 @@ VP_EXPORT int VPrint(FILE *fp,char *cntl_chr,Real *a);
#define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE)
#define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE)
#define VpSetInf(a,s) ( ((s)>0)?VpSetPosInf(a):VpSetNegInf(a) )
+#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1))
#ifdef _DEBUG
int VpVarCheck(Real * v);
+VP_EXPORT int VPrint(FILE *fp,char *cntl_chr,Real *a);
#endif /* _DEBUG */
#if defined(__cplusplus)
diff --git a/ext/bigdecimal/bigdecimal_en.html b/ext/bigdecimal/bigdecimal_en.html
index b8e9768f8f..04dd83a429 100644
--- a/ext/bigdecimal/bigdecimal_en.html
+++ b/ext/bigdecimal/bigdecimal_en.html
@@ -2,90 +2,27 @@
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html">
<style type="text/css"><!--
-body {
- color: #3f0f0f;
- background: #fefeff;
- margin-left: 2em; margin-right: 2em;
-}
-h1 {
- color: #ffffff;
- background-color: #3939AD;
- border-color: #FF00FF;
- width: 100%;
- border-style: solid;
- border-top-width: 0.1em;
- border-bottom-width: 0.1em;
- border-right: none;
- border-left: none;
- padding: 0.1em;
- font-weight: bold;
- font-size: 160%;
- text-align: center;
-}
-h2 {
- color: #00007f;
- background-color: #e7e7ff;
- border-color: #000094;
- width: 100%;
- border-style: solid;
- border-left: none;
- border-right: none;
- border-top-width: 0.1em;
- border-bottom-width: 0.1em;
- padding: 0.1em;
- font-weight: bold;
- font-size: 110%;
-}
-h3 {
- color: #00007f;
- padding: 0.2em;
- font-size: 110%;
-}
-h4, h5 {
- color: #000000;
- padding: 0.2em;
- font-size: 100%;
-}
-table {
- margin-top: 0.2em; margin-bottom: 0.2em;
- margin-left: 2em; margin-right: 2em;
-}
-caption {
- color: #7f0000;
- font-weight: bold;
-}
-th {
- background: #e7e7ff;
- padding-left: 0.2em; padding-right: 0.2em;
-}
-td {
- background: #f3f7ff;
- padding-left: 0.2em; padding-right: 0.2em;
-}
-code {
- color: #0000df;
-}
-dt {
- margin-top: 0.2em;
-}
-li {
- margin-top: 0.2em;
+body { color: #3f0f0f; background: #fefeff; margin-left: 2em; margin-right: 2em;}
+h1 { color: #ffffff; background-color: #3939AD; border-color: #FF00FF; width: 100%; border-style: solid;
+ border-top-width: 0.1em; border-bottom-width: 0.1em; border-right: none; border-left: none;
+ padding: 0.1em; font-weight: bold; font-size: 160%; text-align: center;}
+h2 { color: #00007f; background-color: #e7e7ff; border-color: #000094; width: 100%; border-style: solid; border-le ft: none; border-right: none; border-top-width: 0.1em; border-bottom-width: 0.1em; padding: 0.1em;
+ font-weight: bold; font-size: 110%;
}
+h3 { color: #00007f; padding: 0.2em; font-size: 110%;}
+h4, h5 { color: #000000; padding: 0.2em; font-size: 100%;}
+table { margin-top: 0.2em; margin-bottom: 0.2em; margin-left: 2em; margin-right: 2em;}
+caption { color: #7f0000; font-weight: bold;}
+th { background: #e7e7ff; padding-left: 0.2em; padding-right: 0.2em;}
+td { background: #f3f7ff; padding-left: 0.2em; padding-right: 0.2em;}
+code { color: #0000df;}
+dt { margin-top: 0.2em;}
+li { margin-top: 0.2em;}
pre
-{
- BACKGROUND-COLOR: #d0d0d0;
- BORDER-BOTTOM: medium none;
- BORDER-LEFT: medium none;
- BORDER-RIGHT: medium none;
- BORDER-TOP: medium none;
- LINE-HEIGHT: 100%;
- MARGIN: 12px 12px 12px 12px;
- PADDING-BOTTOM: 12px;
- PADDING-LEFT: 12px;
- PADDING-RIGHT: 12px;
- PADDING-TOP: 12px;
- WHITE-SPACE: pre;
- WIDTH: 100%
+{ BACKGROUND-COLOR: #d0d0d0; BORDER-BOTTOM: medium none; BORDER-LEFT: medium none;
+ BORDER-RIGHT: medium none; BORDER-TOP: medium none; LINE-HEIGHT: 100%; MARGIN: 12px 12px 12px 12px;
+ PADDING-BOTTOM: 12px; PADDING-LEFT: 12px; PADDING-RIGHT: 12px; PADDING-TOP: 12px;
+ WHITE-SPACE: pre; WIDTH: 100%
}
--></style>
@@ -99,7 +36,6 @@ Using BigDecimal class, you can obtain any number of significant digits in compu
For the details about Ruby see:<BR>
<UL>
<LI><A HREF="http://www.ruby-lang.org/en/">http://www.ruby-lang.org/en/</A>:Official Ruby page(English).</LI>
-<LI><A HREF="http://ruby.freak.ne.jp/">http://ruby.freak.ne.jp/</A>:Ruby informations(Japanese).</LI>
<LI><A HREF="http://kahori.com/ruby/ring/">http://kahori.com/ruby/ring/</A>:Mutually linked pages relating to Ruby(Japanese).
</LI>
</UL>
@@ -126,7 +62,7 @@ NOTE:<BR>
<A NAME="#INTRO">
<H2>Introduction</H2>
Ruby already has builtin (variable length integer number) class Bignum. Using Bignum class,you can obtain
- any integer value in magnitude. But, variable length floating number class is not yet built in.
+ any integer value in magnitude. But, variable length decimal number class is not yet built in.
This is why I made variable length floating class BigDecimal.
Feel free to send any comments or bug reports to me.
<A HREF="mailto:shigeo@tinyforest.gr.jp">shigeo@tinyforest.gr.jp</A>
@@ -155,16 +91,80 @@ not exactly but slightly excess memories will be allocated to newly created obje
In 32 bits integer system,every 4 digits(in decimal) are computed simultaneously.
This means the number of significant digits in BigDecimal is always a multiple of 4.
+<H4><U>Class methods</U></H4>
<UL>
-<LI><B>new</B></LI><BR>
+<LI><B>new</B></LI><BLOCKQUOTE>
"new" method creates a new BigDecimal object.<BR>
a=BigDecimal::new(s[,n])<BR>
where:<BR>
s: Initial value string.<BR>
n: Maximum number of significant digits of a. n must be a Fixnum object.
If n is omitted or is equal to 0,then the maximum number of significant digits of a is determined from the length of s.
+</BLOCKQUOTE>
+
+<LI><B>mode</B></LI><BLOCKQUOTE>
+mode method controls BigDecimal computation.Following usage are defined.<BR>
+<P><B>[EXCEPTION control]</B><P>
+Actions when computation results NaN or Infinity can be defined as follows.
+<P>
+<BLOCKQUOTE>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)<BR>
+</BLOCKQUOTE>
+EXCEPTION_NaN controls the execution when computation results to NaN.<BR>
+EXCEPTION_INFINITY controls the execution when computation results to Infinity(±Infinity).<BR>
+EXCEPTION_UNDERFLOW controls the execution when computation underflows.<BR>
+EXCEPTION_OVERFLOW controls the execution when computation overflows.<BR>
+EXCEPTION_ZERODIVIDE controls the execution when zero-division occures.<BR>
+EXCEPTION_ALL controls the execution for any exception defined occures.<BR>
+If the flag is true,then the relating exception is thrown.<BR>
+No exception is thrown when the flag is false(default) and computation
+continues with the result:<BR>
+<BLOCKQUOTE>
+EXCEPTION_NaN results to NaN<BR>
+EXCEPTION_INFINITY results to +Infinity or -Infinity<BR>
+EXCEPTION_UNDERFLOW results to 0.<BR>
+EXCEPTION_OVERFLOW results to +Infinity or -Infinity<BR>
+EXCEPTION_ZERODIVIDE results to +Infinity or -Infinity<BR>
+</BLOCKQUOTE>
+EXCEPTION_INFINITY,EXCEPTION_OVERFLOW, and EXCEPTION_ZERODIVIDE are
+ currently the same.<BR>
+The return value of mode method is the previous value set.<BR>
+nil is returned if any argument is wrong.<BR>
+Suppose the return value of the mode method is f,then
+ f &amp; BigDecimal::EXCEPTION_NaN !=0 means EXCEPTION_NaN is set to on.
+<P>
+<B>[ROUND error control]</B><P>
+Rounding operation can be controlled as:
+<BLOCKQUOTE>
+f = BigDecimal::mode(BigDecimal::COMP_MODE,flag)
+</BLOCKQUOTE>
+where flag must be one of:
+<TABLE>
+<TR><TD>COMP_MODE_TRUNCATE</TD><TD>truncate</TD></TR>
+<TR><TD>COMP_MODE_ROUNDUP</TD><TD>roundup,default</TD></TR>
+<TR><TD>COMP_MODE_CEIL</TD><TD>ceil</TD></TR>
+<TR><TD>COMP_MODE_FLOOR</TD><TD>floor</TD></TR>
+<TR><TD>COMP_MODE_EVEN</TD><TD>Banker's rounding</TD></TR>
+</TABLE>
+nil is returned if any argument is illegal.<BR>
+The digit location for rounding operation can not be specified by mode method,
+use truncate/roundup/ceil/floor mthods for each instance instead.
+
+</BLOCKQUOTE>
-<LI><B>double_fig</B></LI><BR>
+<LI><B>limit[(n)]</B></LI><BLOCKQUOTE>
+Limits the maximum digits that the newly created BigDecimal objects can hold
+never exceed n. Returns maximum value before set.
+Zero,the default value,means no upper limit.<BR>
+mf = BigDecimal::limit(n)<BR>
+</BLOCKQUOTE>
+
+<LI><B>double_fig</B></LI><BLOCKQUOTE>
double_fig is a class method which returns the number of digits
the Float class can have.
<CODE><PRE>
@@ -180,71 +180,71 @@ double_fig is:
v /= 10;
}
</PRE></CODE>
+</BLOCKQUOTE>
-<LI><B>prec</B></LI><BR>
-r,m = a.prec<BR>
-where r is the number of significant digits of a,
-m is the maximum number of significant digits a can hold.<br>
-<CODE><PRE>
- require "bigdecimal"
- a = BigDecimal.new("0.12345")
- p a.prec # ==> [8, 12]
- b = BigDecimal.new("0.1234500000000")
- p b.prec # ==> [8, 20]
- c = BigDecimal.new("0.12345",20)
- p c.prec # ==> [8, 24]
-</PRE></CODE>
-r and m are always the multiple of log10(BigDecimal::BASE).
+<LI><B>BASE</B></LI><BLOCKQUOTE>
+Base value used in the BigDecimal calculation.
+On 32 bits integer system,the value of BASE is 10000.<BR>
+b = BigDecimal::BASE<BR>
+</BLOCKQUOTE>
+
+<LI><B>E</B></LI><BLOCKQUOTE>
+e = BigDecimal::E(n)<BR>
+where e(=2.718281828....) is the base value of natural logarithm.<BR>
+n specifies the length of significant digits of e.
+
+</BLOCKQUOTE>
+<LI><B>PI</B></LI><BLOCKQUOTE>
+e = BigDecimal::PI(n)<BR>
+returns at least n digits of the ratio of the circumference of a circle to its diameter
+(pi=3.14159265358979....) using J.Machin's formula.<BR>
+</BLOCKQUOTE>
+</UL>
-<LI><B>+</B></LI><BR>
+<H4><U>Instance methods</U></H4>
+<UL>
+<LI><B>+</B></LI><BLOCKQUOTE>
addition(c = a + b)<BR>
For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
-<LI><B>-</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>-</B></LI><BLOCKQUOTE>
subtraction (c = a - b) or negation (c = -a)<BR>
For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
-<LI><B>*</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>*</B></LI><BLOCKQUOTE>
multiplication(c = a * b)<BR>
For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
-<LI><B>/</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>/</B></LI><BLOCKQUOTE>
division(c = a / b)<BR>
For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
+</BLOCKQUOTE>
-<LI><B>assign</B></LI><BR>
-c = a.assign(n,f)<BR>
-assigns the value of a to c.<BR>
-n is the number of significant digits of resulting c.<BR>
-If f > 0,then a is assigned to c.<BR>
-If f < 0,then -a is assigned to c.<BR>
-The absolute value of f (|f|) must be 1 or 2.
-If |f|=2,then proper round operation over c is performed,when the maximum
-number of significant digits of c is less than current
-number of significant digits of a.
-If |f|=1 then extra digits are discarded when the maximum
-number of significant digits of c is less than current
-number of significant digits of a.
-
-<LI><B>add</B></LI><BR>
+<LI><B>add</B></LI><BLOCKQUOTE>
c = a.add(b,n)<BR>
c = a.add(b,n) performs c = a + b.
If n is less than the actual significant digits of a + b,
then c is rounded properly.
-<LI><B>sub</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>sub</B></LI><BLOCKQUOTE>
c = a.sub(b,n)<BR>
c = a.sub(b,n) performs c = a - b.
If n is less than the actual significant digits of a - b,
then c is rounded properly.
-<LI><B>mult</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>mult</B></LI><BLOCKQUOTE>
c = a.mult(b,n)<BR>
c = a.mult(b,n) performs c = a * b.
If n is less than the actual significant digits of a * b,
then c is rounded properly.
-<LI><B>div</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>div</B></LI><BLOCKQUOTE>
c,r = a.div(b,n)<BR>
c,r = a.div(b,n) performs c = a / b, r is the residue of a / b.
If necessary,the divide operation continues to n digits which c
@@ -253,169 +253,154 @@ Unlike the divmod method,c is not always an integer.
c is never rounded,and the equation a = c*b + r is always
valid unless c is NaN or Infinity.
-<LI><B>%</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>%</B></LI><BLOCKQUOTE>
r = a%b <BR>
is the same as:<BR>
r = a-((a/b).floor)*b<BR>
-<LI><B>fix</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>fix</B></LI><BLOCKQUOTE>
c = a.fix<BR>
returns integer part of a.<BR>
-<LI><B>frac</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>frac</B></LI><BLOCKQUOTE>
c = a.frac<BR>
returns fraction part of a.<BR>
-<LI><B>floor[(n)]</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>floor[(n)]</B></LI><BLOCKQUOTE>
c = a.floor<BR>
-returns the maximum integer value (in BigDecimal) which is less than or equal to a.<BR>
-As shown in the following example,an optional integer argument (n) specifying the position
-of 'floor'ed digit can be given.
-If n> 0,then the (n+1)th digit counted from the decimal point in fraction part is 'floor'ed.
-If n<0,then the n-th digit counted from the decimal point in integer part is 'floor'ed.<BR>
+returns the maximum integer value (in BigDecimal) which is less than or equal to a.
+<PRE><CODE>
+ c = BigDecimal("1.23456").floor # ==> 1
+ c = BigDecimal("-1.23456").floor # ==> -2
+</CODE></PRE>
-c = BigDecimal::new("1.23456")<BR>
-d = c.floor(4) # d = 1.2345<BR>
-c = BigDecimal::new("15.23456")<BR>
-d = c.floor(-1) # d = 10.0<BR>
+As shown in the following example,an optional integer argument (n) specifying the position
+of the target digit can be given.<BR>
+If n> 0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
+If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
+<PRE><CODE>
+ c = BigDecimal::new("1.23456").floor(4) # ==> 1.2345
+ c = BigDecimal::new("15.23456").floor(-1) # ==> 10.0
+</CODE></PRE>
-<LI><B>ceil[(n)]</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>ceil[(n)]</B></LI><BLOCKQUOTE>
c = a.ceil<BR>
-returns the minimum integer value (in BigDecimal) which is greater than or equal to a.<BR>
-As shown in the following example,an optional integer argument (n) specifying the position
-of 'ceil'ed digit can be given.
-If n>0,then the (n+1)th digit counted from the decimal point in fraction part is 'ceil'ed.
-If n<0,then the n-th digit counted from the decimal point in integer part is 'ceil'ed.<BR>
+returns the minimum integer value (in BigDecimal) which is greater than or equal to a.
+<PRE><CODE>
+ c = BigDecimal("1.23456").ceil # ==> 2
+ c = BigDecimal("-1.23456").ceil # ==> -1
+</CODE></PRE>
-c = BigDecimal::new("1.23456")<BR>
-d = c.ceil(4) # d = 1.2346<BR>
-c = BigDecimal::new("15.23456")<BR>
-d = c.ceil(-1) # d = 20.0<BR>
+As shown in the following example,an optional integer argument (n) specifying the position
+of the target digit can be given.<BR>
+If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
+If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
+<PRE><CODE>
+ c = BigDecimal::new("1.23456").ceil(4) # ==> 1.2346
+ c = BigDecimal::new("15.23456").ceil(-1) # ==> 20.0
+</CODE></PRE>
-<LI><B>round[(n)]</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>round[(n[,b])]</B></LI><BLOCKQUOTE>
c = a.round<BR>
-round off a to the nearest 1.<BR>
+round a to the nearest 1.<BR>
+<PRE><CODE>
+ c = BigDecimal("1.23456").round # ==> 1
+ c = BigDecimal("-1.23456").round # ==> -1
+</CODE></PRE>
+
As shown in the following example,an optional integer argument (n) specifying the position
-of rounded digit can be given.
-If n>0,then the (n+1)th digit counted from the decimal point in fraction part is rounded.
-If n<0,then the n-th digit counted from the decimal point in integer part is rounded.<BR>
+of the target digit can be given.<BR>
+If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
+If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
+<PRE><CODE>
+c = BigDecimal::new("1.23456").round(4) # ==> 1.2346
+c = BigDecimal::new("15.23456").round(-1) # ==> 20.0
+</CODE></PRE>
-c = BigDecimal::new("1.23456")<BR>
-d = c.round(4) # d = 1.235 <BR>
-c = BigDecimal::new("15.23456")<BR>
-d = c.round(-1) # d = 20.0<BR>
+If the second optional argument b is given with the non-zero value(default is zero) then
+so called Banker's rounding is performed.<BR>
+Suppose the digit p is to be rounded,then:<BR>
+ If p<5 then p is truncated<BR>
+ If p>5 then p is rounded up<BR>
+ If p is 5 then round up operation is taken only when the left hand side digit of p is odd.
+<PRE><CODE>
+c = BigDecimal::new("1.23456").round(3,1) # ==> 1.234
+c = BigDecimal::new("1.23356").round(3,1) # ==> 1.234
+</CODE></PRE>
-<LI><B>truncate[(n)]</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>truncate[(n)]</B></LI><BLOCKQUOTE>
c = a.truncate<BR>
truncate a to the nearest 1.<BR>
As shown in the following example,an optional integer argument (n) specifying the position
-of truncated digit can be given.
-If n>0,then the (n+1)th digit counted from the decimal point in fraction part is truncated.
-If n<0,then the n-th digit counted from the decimal point in integer part is truncated.<BR>
+of the target digit can be given.<BR>
+If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
+If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
-c = BigDecimal::new("1.23456")<BR>
-d = c.truncate(4) # d = 1.2345<BR>
-c = BigDecimal::new("15.23456")<BR>
-d = c.truncate(-1) # d = 10.0<BR>
+<PRE><CODE>
+c = BigDecimal::new("1.23456").truncate(4) # ==> 1.2345
+c = BigDecimal::new("15.23456").truncate(-1) # ==> 10.0
+</CODE></PRE>
-<LI><B>divmod</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>divmod</B></LI><BLOCKQUOTE>
c,r = a.divmod(b) # a = c*b + r<BR>
returns the quotient and remainder of a/b.<BR>
a = c * b + r is always satisfied.<BR>
-where c is the integer sutisfying
+where c is the integer satisfying
c = (a/b).floor <BR>
and,therefore
r = a - c*b<BR>
-<LI><B>remainder</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>remainder</B></LI><BLOCKQUOTE>
r=a.remainder(b)<BR>
returns the remainder of a/b.<BR>
-where c is the integer sutisfying
+where c is the integer satisfying
c = (a/b).fix <BR>
and,therefore:
r = a - c*b<BR>
-<LI><B>abs</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>abs</B></LI><BLOCKQUOTE>
c = a.abs<BR>
returns an absolute value of a.<BR>
-<LI><B>to_i</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>to_i</B></LI><BLOCKQUOTE>
changes a to an integer.<BR>
i = a.to_i<BR>
i becomes to Fixnum or Bignum.
-IF a is Infinity or NaN,then i becomes to nil.
+If a is Infinity or NaN,then i becomes to nil.
-<LI><B>to_s[(n)]</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
converts to string(results look like "0.xxxxxEn").<BR>
s = a.to_s<BR>
If n is given,then a space is inserted after every n digits for readability.<BR>
s = a.to_s(n)
-<LI><B>exponent</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>exponent</B></LI><BLOCKQUOTE>
returns an integer holding exponent value of a.<BR>
n = a.exponent <BR>
means a = 0.xxxxxxx*10**n.
-<LI><B>to_f</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>to_f</B></LI><BLOCKQUOTE>
same as dup method.
creates a new BigDecimal object having same value.
+</BLOCKQUOTE>
-<LI><B>E</B></LI><BR>
-e = BigDecimal::E(n)<BR>
-where e(=2.718281828....) is the base value of natural logarithm.<BR>
-n specifies the length of significant digits of e.
-
-<LI><B>PI</B></LI><BR>
-e = BigDecimal::PI(n)<BR>
-returns at least n digits of the ratio of the circumference of a circle to its dirmeter
-(pi=3.14159265358979....) using J.Machin's formula.<BR>
-
-<LI><B>BASE</B></LI><BR>
-Base value used in the BigDecimal calculation.
-On 32 bit integer system,the value of BASE is 10000.<BR>
-b = BigDecimal::BASE<BR>
-
-<LI><B>mode</B></LI><BR>
-mode method controls BigDecimal computation.
-Following usage are defined.<BR>
-
-f = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)<BR>
-
-EXCEPTION_NaN controls the execution once computation results to NaN.
-EXCEPTION_INFINITY controls the execution once computation results to Infinity(±Infinity).
-EXCEPTION_UNDERFLOW controls the execution once computation underflows.
-EXCEPTION_OVERFLOW controls the execution once computation overflows.
-EXCEPTION_ZERODIVIDE controls the execution once zero-division occures.
-EXCEPTION_ALL controls the execution for any exception defined occures.
-If the flag is true,then the relating exception is thrown.
-No exception is thrown when the flag is false(default) and computation
-continues with the result:<BR>
-EXCEPTION_NaN results to NaN<BR>
-EXCEPTION_INFINITY results to +Infinity or -Infinity<BR>
-EXCEPTION_UNDERFLOW results to 0.<BR>
-EXCEPTION_OVERFLOW results to +Infinity or -Infinity<BR>
-EXCEPTION_ZERODIVIDE results to +Infinity or -Infinity<BR>
-EXCEPTION_INFINITY,EXCEPTION_OVERFLOW, and EXCEPTION_ZERODIVIDE are
- currently the same.<BR>
-The return value of mode method is the value set.
-Suppose the return value of the mode method is f,then
- f & BigDecimal::EXCEPTION_NaN !=0 means EXCEPTION_NaN is set to on.
-If the value of the argument flag is other than nil,true nor false then
-current mode status is returned.
-
-<LI><B>limit[(n)]</B></LI><BR>
-Limits the maximum digits that the newly created BigDecimal objects can hold
-never exceed n. Returns maximum value before set.
-Zero,the default value,means no upper limit.<BR>
-mf = BigDecimal::limit(n)<BR>
-
-<LI><B>sign</B></LI><BR>
-returns the 'attribute'.
+</BLOCKQUOTE>
+<LI><B>sign</B></LI><BLOCKQUOTE>
+returns the 'attribute' of a.
n = a.sign <BR>
where the value of n means that a is:<BR>
n = BigDecimal::SIGN_NaN(0) : a is NaN<BR>
@@ -427,28 +412,42 @@ n = BigDecimal::SIGN_POSITIVE_INFINITE(3) : a is +Infinity<BR>
n = BigDecimal::SIGN_NEGATIVE_INFINITE(-3) : a is -Infinity<BR>
The value in () is the actual value,see (<A HREF="#STRUCT">Internal structure</A>.<BR>
-<LI><B>nan?</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>nan?</B></LI><BLOCKQUOTE>
a.nan? returns True when a is NaN.
-<LI><B>infinite?</B></LI><BR>
-a.infinite? returns True when a is +∞ or -∞.
+</BLOCKQUOTE>
+<LI><B>infinite?</B></LI><BLOCKQUOTE>
+a.infinite? returns 1 when a is +∞,-1 when a is -∞, nil otherwise.
+
+</BLOCKQUOTE>
+<LI><B>finite?</B></LI><BLOCKQUOTE>
+a.finite? returns true when a is neither ∞ nor NaN.
+</BLOCKQUOTE>
-<LI><B>finite?</B></LI><BR>
-a.finite? returns True when a is neither ∞ nor NaN.
+<LI><B>zero?</B></LI><BLOCKQUOTE>
+c = a.zero?<BR>
+returns true if a is equal to 0,otherwise returns false<BR>
+</BLOCKQUOTE>
+<LI><B>nonzero?</B></LI><BLOCKQUOTE>
+c = a.nonzero?<BR>
+returns nil if a is 0,otherwise returns a itself.<BR>
+</BLOCKQUOTE>
-<LI><B>to_parts</B></LI><BR>
+<LI><B>split</B></LI><BLOCKQUOTE>
decomposes a BigDecimal value to 4 parts.
All 4 parts are returned as an array.<BR>
Parts consist of a sign(0 when the value is NaN,+1 for positive and
-1 for negative value), a string representing fraction part,base value(always 10 currently),and an integer(Fixnum) for exponent respectively.
-a=BigDecimal::new("3.14159265",10)<BR>
-f,x,y,z = a.to_parts<BR>
+a=BigDecimal::new("3.14159265")<BR>
+f,x,y,z = a.split<BR>
where f=+1,x="314159265",y=10 and z=1<BR>
therefore,you can translate BigDecimal value to Float as:<BR>
s = "0."+x<BR>
b = f*(s.to_f)*(y**z)<BR>
-<LI><B>inspect</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>inspect</B></LI><BLOCKQUOTE>
is used for debugging output.<BR>
p a=BigDecimal::new("3.14",10)<BR>
should produce output like "#&lt;0x112344:'0.314E1',4(12)%gt;".
@@ -457,38 +456,44 @@ where "0x112344" is the address,
and 12 is the maximum number of the significant digits
the object can hold.
-<LI><B>dup</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>dup</B></LI><BLOCKQUOTE>
creates a new BigDecimal object having same value.
-<LI><B>sqrt</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>sqrt</B></LI><BLOCKQUOTE>
c = a.sqrt(n)<BR>
computes square root value of a with significant digit number n at least.<BR>
-<LI><B>sincos</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>sincos</B></LI><BLOCKQUOTE>
computes and returns sine and cosine value of a with significant digit number n at least.<BR>
sin,cos = a.sincos(n)<BR>
Computation may return bad results unless |a|<2*3.1415.....
-<LI><B>exp</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>exp</B></LI><BLOCKQUOTE>
c = a.exp(n)<BR>
computes the base of natural logarithm value(e=2.718281828....) powered by a
with significant digit number n at least.<BR>
-<LI><B>power</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>**</B></LI><BLOCKQUOTE>
+c = a ** n<BR>
+returns the value of a powered by n.
+n must be an integer.<BR>
+
+</BLOCKQUOTE>
+<LI><B>power</B></LI><BLOCKQUOTE>
+The same as ** method.<BR>
c = a.power(n)<BR>
returns the value of a powered by n(c=a**n).
n must be an integer.<BR>
-<LI><B>zero?</B></LI><BR>
-c = a.zero?<BR>
-returns true if a is equal to 0,otherwise returns false<BR>
-
-<LI><B>nonzero?</B></LI><BR>
-c = a.nonzero?<BR>
-returns false if a is 0,otherwise returns a itself.<BR>
-
-<LI><B>&lt;=&gt;</B></LI><BR>
+</BLOCKQUOTE>
+<LI><B>&lt;=&gt;</B></LI><BLOCKQUOTE>
c = a &lt;=&gt; b <BR>
returns 0 if a==b,1 if a &gt b,and returns -1 if a &lt b.<BR>
+</BLOCKQUOTE>
</UL>
Following methods need no explanation.<BR>
diff --git a/ext/bigdecimal/bigdecimal_ja.html b/ext/bigdecimal/bigdecimal_ja.html
index efd4228d9a..56bebaa863 100644
--- a/ext/bigdecimal/bigdecimal_ja.html
+++ b/ext/bigdecimal/bigdecimal_ja.html
@@ -2,90 +2,30 @@
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
<style type="text/css"><!--
-body {
- color: #3f0f0f;
- background: #fefeff;
- margin-left: 2em; margin-right: 2em;
+body { color: #3f0f0f; background: #fefeff; margin-left: 2em; margin-right: 2em;}
+h1 { color: #ffffff; background-color: #3939AD; border-color: #FF00FF; width: 100%;
+ border-style: solid; border-top-width: 0.1em; border-bottom-width: 0.1em; border-right: none;
+ border-left: none; padding: 0.1em; font-weight: bold; font-size: 160%; text-align: center;
}
-h1 {
- color: #ffffff;
- background-color: #3939AD;
- border-color: #FF00FF;
- width: 100%;
- border-style: solid;
- border-top-width: 0.1em;
- border-bottom-width: 0.1em;
- border-right: none;
- border-left: none;
+h2 { color: #00007f; background-color: #e7e7ff; border-color: #000094; width: 100%;
+ border-style: solid; border-left: none; border-right: none; border-top-width: 0.1em; border-bottom-width: 0.1em;
padding: 0.1em;
- font-weight: bold;
- font-size: 160%;
- text-align: center;
-}
-h2 {
- color: #00007f;
- background-color: #e7e7ff;
- border-color: #000094;
- width: 100%;
- border-style: solid;
- border-left: none;
- border-right: none;
- border-top-width: 0.1em;
- border-bottom-width: 0.1em;
- padding: 0.1em;
- font-weight: bold;
- font-size: 110%;
-}
-h3 {
- color: #00007f;
- padding: 0.2em;
- font-size: 110%;
-}
-h4, h5 {
- color: #000000;
- padding: 0.2em;
- font-size: 100%;
-}
-table {
- margin-top: 0.2em; margin-bottom: 0.2em;
- margin-left: 2em; margin-right: 2em;
-}
-caption {
- color: #7f0000;
- font-weight: bold;
-}
-th {
- background: #e7e7ff;
- padding-left: 0.2em; padding-right: 0.2em;
-}
-td {
- background: #f3f7ff;
- padding-left: 0.2em; padding-right: 0.2em;
-}
-code {
- color: #0000df;
-}
-dt {
- margin-top: 0.2em;
-}
-li {
- margin-top: 0.2em;
+ font-weight: bold; font-size: 110%;
}
+h3 { color: #00007f; padding: 0.2em; font-size: 110%;}
+h4, h5 { color: #000000; padding: 0.2em; font-size: 100%;}
+table { margin-top: 0.2em; margin-bottom: 0.2em; margin-left: 2em; margin-right: 2em;}
+caption { color: #7f0000; font-weight: bold;}
+th { background: #e7e7ff; padding-left: 0.2em; padding-right: 0.2em;}
+td { background: #f3f7ff; padding-left: 0.2em; padding-right: 0.2em;}
+code { color: #0000df;}
+dt { margin-top: 0.2em;}
+li { margin-top: 0.2em;}
pre
-{
- BACKGROUND-COLOR: #d0d0d0;
- BORDER-BOTTOM: medium none;
- BORDER-LEFT: medium none;
- BORDER-RIGHT: medium none;
- BORDER-TOP: medium none;
- LINE-HEIGHT: 100%;
- MARGIN: 12px 12px 12px 12px;
- PADDING-BOTTOM: 12px;
- PADDING-LEFT: 12px;
- PADDING-RIGHT: 12px;
- PADDING-TOP: 12px;
- WHITE-SPACE: pre;
- WIDTH: 100%
+{ BACKGROUND-COLOR: #d0d0d0; BORDER-BOTTOM: medium none; BORDER-LEFT: medium none;
+ BORDER-RIGHT: medium none; BORDER-TOP: medium none; LINE-HEIGHT: 100%; MARGIN: 12px 12px 12px 12px;
+ PADDING-BOTTOM: 12px; PADDING-LEFT: 12px; PADDING-RIGHT: 12px; PADDING-TOP: 12px;
+ WHITE-SPACE: pre; WIDTH: 100%
}
--></style>
@@ -99,7 +39,6 @@ BigDecimal はオブジェクト指向の強力なスクリプト言語である Ruby に可変長浮動小数
Ruby についての詳しい内容は以下のURLを参照してください。
<UL>
<LI><A HREF="http://www.ruby-lang.org/ja/">http://www.ruby-lang.org/ja/</A>:Ruby公式ページ</LI>
-<LI><A HREF="http://ruby.freak.ne.jp/">http://ruby.freak.ne.jp/</A>:Rubyに関する情報ページ</LI>
<LI><A HREF="http://kahori.com/ruby/ring/">http://kahori.com/ruby/ring/</A>:Rubyに関するページを辿れます</LI>
</UL>
<hr>
@@ -160,8 +99,9 @@ c=a+b
例えば32ビットのシステムでは10進で4桁毎に計算します。従って、現状では、
内部の「有効桁数」は4の倍数となっています。
+<H4><U>クラスメソッド</U></H4>
<UL>
-<LI>new</LI><BR>
+<LI><B>new</B></LI><BLOCKQUOTE>
新しい BigDecimal オブジェクトを生成します。<BR>
a=BigDecimal::new(s[,n])<BR>
s は初期値を文字列で指定します.
@@ -169,50 +109,151 @@ n は必要な有効桁数(a の最大有効桁数)を整数で指定します。
n が 0 または省略されたときは、n の値は s の有効桁数とみなされます。
s の有効桁数より n が小さいときも n=0 のときと同じです。
a の最大有効桁数は n より若干大い値が採用されます。
-<LI>+</LI><BR>
+</BLOCKQUOTE>
+
+<LI><B>mode</B></LI><BLOCKQUOTE>
+BigDecimalの実行結果を制御します。以下の使用方法が定義されています。
+<P>
+<B>[例外処理]</B><P>
+計算結果が非数(NaN)やゼロによる除算になったときの処理を定義することができます。
+<BLOCKQUOTE>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)<BR>
+f = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)<BR>
+</BLOCKQUOTE>
+
+EXCEPTION_NaN は結果が NaN になったときの指定です。<BR>
+EXCEPTION_INFINITY は結果が無限大(±Infinity)になったときの指定です。<BR>
+EXCEPTION_UNDERFLOW は指数部がアンダーフローするときの指定です。<BR>
+EXCEPTION_OVERFLOW は指数部がオーバーフローするときの指定です。<BR>
+EXCEPTION_ZERODIVIDE はゼロによる割り算を実行したときの指定です。<BR>
+EXCEPTION_ALL は、可能な全てに対して一括して設定するときに使用します。<BR><BR>
+
+flag が true のときは、指定した状態になったときに例外を発行するようになります。<BR>
+flag が false(デフォルト)なら、例外は発行されません。計算結果は以下のようになります。<BR>
+<BLOCKQUOTE>
+EXCEPTION_NaN のとき、非数(NaN)<BR>
+EXCEPTION_INFINITY のとき、無限(+ or -Infinity)<BR>
+EXCEPTION_UNDERFLOW のとき、ゼロ<BR>
+EXCEPTION_OVERFLOW のとき、+Infinity か -Infinity<BR>
+EXCEPTION_ZERODIVIDE のとき、+Infinity か -Infinity<BR>
+</BLOCKQUOTE>
+EXCEPTION_INFINITY、EXCEPTION_OVERFLOW、EXCEPTION_ZERODIVIDE
+は今のところ同じです。<BR>
+戻り値は、設定前の値です。「値」の意味は、例えば
+BigDecimal::EXCEPTION_NaNと「値」の & が ゼロ以外ならば
+EXCEPTION_NaNが設定されているという意味です。<BR>
+引数に正しくないものが指定された場合は nil が返ります。
+
+<P>
+<B>[丸め処理指定]</B><P>
+計算途中の丸め操作の指定ができます。
+<BLOCKQUOTE>
+f = BigDecimal::mode(BigDecimal::COMP_MODE,flag)
+</BLOCKQUOTE>
+の形式で指定します。<BR>
+ここで、flag は以下の一つを指定します。
+<TABLE>
+<TR><TD>COMP_MODE_TRUNCATE</TD><TD>全て切り捨てます(truncate)。</TD></TR>
+<TR><TD>COMP_MODE_ROUNDUP</TD><TD>四捨五入します(roundup、デフォルト)。</TD></TR>
+<TR><TD>COMP_MODE_CEIL</TD><TD>数値の大きい方に繰り上げます(ceil)。</TD></TR>
+<TR><TD>COMP_MODE_FLOOR</TD><TD>数値の小さい方に繰り下げます(floor)。</TD></TR>
+<TR><TD>COMP_MODE_EVEN</TD><TD>四捨六入します。5の時は上位1桁が奇数の時のみ繰り上げます(Banker's rounding)。</TD></TR>
+</TABLE>
+戻り値は指定前の flag の値です。
+引数に正しくないものが指定された場合は nil が返ります。<BR>
+mode メソッドでは丸め操作の位置をユーザが指定することはできません。
+丸め操作と位置を自分で制御したい場合は truncate/roundup/ceil/floor といった
+インスタンスメソッドを使用して下さい。
+</BLOCKQUOTE>
+<LI><B>limit([n])</B></LI><BLOCKQUOTE>
+生成されるBigDecimalオブジェクトの最大桁数をn桁に制限します。戻り値は
+設定する前の値です。設定値のデフォルト値は0で、桁数無制限という意味です。
+nを指定しない場合は、現状の最大桁数が返ります。<BR>
+mf = BigDecimal::limit(n)<BR>
+</BLOCKQUOTE>
+<LI><B>double_fig</B></LI><BLOCKQUOTE>
+Ruby の Float クラスが保持できる有効数字の数を返します。
+<CODE><PRE>
+ p BigDecimal::double_fig # ==> 20 (depends on the CPU etc.)
+</PRE></CODE>
+double_figは以下の C プログラムの結果と同じです。
+<CODE><PRE>
+ double v = 1.0;
+ int double_fig = 0;
+ while(v + 1.0 > 1.0) {
+ ++double_fig;
+ v /= 10;
+ }
+</PRE></CODE>
+</BLOCKQUOTE>
+
+<LI><B>BASE</B></LI><BLOCKQUOTE>
+内部で使用される基数の値です。整数が 32 ビットの処理系では10000です。<BR>
+b = BigDecimal::BASE<BR>
+</BLOCKQUOTE>
+
+<LI><B>E</B></LI><BLOCKQUOTE>
+自然対数の底e(=2.718281828....)を計算します(正直にテイラー展開で)。<BR>
+e = BigDecimal::E(n)<BR>
+nは必要な有効桁数を整数で指定します。
+</BLOCKQUOTE>
+<LI><B>PI</B></LI><BLOCKQUOTE>
+円周率(=3.14159265358979....)を計算します(J.Machinの公式を用います)。<BR>
+e = BigDecimal::PI(n)<BR>
+n は必要な有効桁数を整数で指定します。
+</BLOCKQUOTE>
+</UL>
+
+<H4><U>インスタンスメソッド</U></H4>
+<UL>
+<LI><B>+</B></LI><BLOCKQUOTE>
加算(c = a + b)<BR>
c の精度については「<A HREF="#PREC">計算精度について</A>」を参照してください。
-<LI>-</LI><BR>
+</BLOCKQUOTE>
+
+<LI><B>-</B></LI><BLOCKQUOTE>
減算(c = a - b)、または符号反転(c = -a)<BR>
c の精度については「<A HREF="#PREC">計算精度について</A>」を参照してください。
-<LI>*</LI><BR>
+
+</BLOCKQUOTE>
+<LI><B>*</B></LI><BLOCKQUOTE>
乗算(c = a * b)<BR>
cの精度は(aの精度)+(bの精度)程度です。<br>
詳しくは「<A HREF="#PREC">計算精度について</A>」を参照してください。
-<LI>/</LI><BR>
+</BLOCKQUOTE>
+<LI><B>/</B></LI><BLOCKQUOTE>
除算(c = a / b)<BR>
c の精度については「<A HREF="#PREC">計算精度について</A>」を参照してください。
-<LI>assign</LI><BR>
-以下のように使用します。<BR>
-c = a.assign(n,f)<BR>
-f > 0 なら、a を c に、そのまま代入します。
-f < 0 なら、-a を c に代入します。
-f の絶対値(|f|)は1か2を指定してください。
-|f|=2 のときは、c の最大精度が a の実精度より小さいときには
-丸められます。|f|=1 のときは切り捨てられます。
-n は c の有効桁数です(n 桁以上の精度を持つ c が生成されます)。
-
-<LI>add</LI><BR>
+</BLOCKQUOTE>
+
+<LI><B>add</B></LI><BLOCKQUOTE>
以下のように使用します。<BR>
c = a.add(b,n)<BR>
c = a + b を最大で n 桁まで計算します。
a + b の精度が n より大きいときは丸められます。
-<LI>sub</LI><BR>
+</BLOCKQUOTE>
+<LI><B>sub</B></LI><BLOCKQUOTE>
以下のように使用します。<BR>
c = a.sub(b,n)<BR>
c = a - b を最大で n 桁まで計算します。
a - b の精度が n より大きいときは丸められます。
-<LI>mult</LI><BR>
+</BLOCKQUOTE>
+<LI><B>mult</B></LI><BLOCKQUOTE>
以下のように使用します。<BR>
c = a.mult(b,n)<BR>
c = a * b を最大で n 桁まで計算します。
a * b の精度が n より大きいときは丸められます。
-<LI>div</LI><BR>
+</BLOCKQUOTE>
+<LI><B>div</B></LI><BLOCKQUOTE>
以下のように使用します。<BR>
c,r = a.div(b,n)<BR>
c=a/b の計算をします。 r には剰余が代入されます。a/bは
@@ -220,63 +261,91 @@ c=a/b の計算をします。 r には剰余が代入されます。a/bは
と異なり、c は整数とは限りません。
また、 c は丸められることはありません。
a = c*b + r の関係は成立します。
-<LI>%</LI><BR>
+</BLOCKQUOTE>
+<LI><B>%</B></LI><BLOCKQUOTE>
r = a%b <BR>
a/b の余りを計算します。以下の計算と同じものです。<BR>
r = a-((a/b).floor)*b<BR>
-<LI>fix</LI><BR>
+</BLOCKQUOTE>
+<LI><B>fix</B></LI><BLOCKQUOTE>
a の小数点以下の切り捨て。<BR>
c = a.fix
-<LI>frac</LI><BR>
+</BLOCKQUOTE>
+<LI><B>frac</B></LI><BLOCKQUOTE>
a の整数部分の切り捨て。<BR>
c = a.frac
-<LI>floor</LI><BR>
-a 以下の最大整数を表す値(BigDecimal 値)を返します。<BR>
+</BLOCKQUOTE>
+
+<LI><B>floor[(n)]</B></LI><BLOCKQUOTE>
c = a.floor<BR>
-以下のように引数を与えて、小数点以下 n+1 位の数字を操作することもできます
-(少数点以下を、最大 n 桁にします)。<BR>
-c = BigDecimal("1.23456")<BR>
-d = c.floor(4) # d = 1.2345 になります。<BR>
- n が負のときは小数点以上 n 桁目を操作します。<BR>
-c = BigDecimal("15.23456")<BR>
-d = c.floor(-1) # d = 10.0 になります。<BR>
-
-<LI>ceil</LI><BR>
-a 以上の整数のうち、最も小さい整数を計算し、その値(BigDecimal 値)を返します。<BR>
+a 以下の最大整数(BigDecimal 値)を返します。
+<PRE><CODE>
+c = BigDecimal("1.23456").floor # ==> 1
+c = BigDecimal("-1.23456").floor # ==> -2
+</CODE></PRE>
+以下のように引数 n を与えることもできます。<BR>
+n>=0 なら、小数点以下 n+1 位の数字を操作します(少数点以下を、最大 n 桁にします)。<BR>
+n が負のときは小数点以上 n 桁目を操作します(小数点位置から左に少なくとも n 個の 0 が並びます)。<BR>
+<PRE><CODE>
+ c = BigDecimal::new("1.23456").floor(4) # ==> 1.2345
+ c = BigDecimal::new("15.23456").floor(-1) # ==> 10.0
+</CODE></PRE>
+
+</BLOCKQUOTE>
+<LI><B>ceil[(n)]</B></LI><BLOCKQUOTE>
c = a.ceil<BR>
-以下のように引数を与えて、小数点以下 n+1 位の数字を操作することもできます
-(少数点以下を、最大 n 桁にします)。<BR>
-c = BigDecimal::new("1.23456")<BR>
-d = c.ceil(4) # d = 1.2346 になります。<BR>
- n が負のときは小数点以上 n 桁目をを操作します。<BR>
-c = BigDecimal::new("15.23456")<BR>
-d = c.ceil(-1) # d = 20.0 になります。<BR>
-
-<LI>round</LI><BR>
-小数点以下第一位の数を四捨五入して整数(BigDecimal 値)にします。<BR>
+a 以上の整数のうち、最も小さい整数を計算し、その値(BigDecimal 値)を返します。
+<PRE><CODE>
+c = BigDecimal("1.23456").ceil # ==> 2
+c = BigDecimal("-1.23456").ceil # ==> -1
+</CODE></PRE>
+
+以下のように引数を与えて、小数点以下 n+1 位の数字を操作することもできます。<BR>
+n>=0 なら、小数点以下 n+1 位の数字を操作します(少数点以下を、最大 n 桁にします)。<BR>
+ n が負のときは小数点以上 n 桁目をを操作します(小数点位置から左に少なくとも n 個の 0 が並びます)。<BR>
+<PRE><CODE>
+ c = BigDecimal::new("1.23456").ceil(4) # ==> 1.2346
+ c = BigDecimal::new("15.23456").ceil(-1) # ==> 20.0
+</CODE></PRE>
+
+</BLOCKQUOTE>
+<LI><B>round[(n[,b])]</B></LI><BLOCKQUOTE>
c = a.round<BR>
-以下のように引数を与えて、小数点以下 n+1 位の数字を操作することもできます
-(少数点以下を、最大 n 桁にします)。<BR>
-n が正の時は、小数点以下 n+1 位の数字を四捨五入します。
-c = BigDecimal::new("1.23456")<BR>
-d = c.round(4) # d = 1.235 になります。<BR>
- n が負のときは小数点以上 n 桁目をを操作します。<BR>
-c = BigDecimal::new("15.23456")<BR>
-d = c.round(-1) # d = 20.0 になります。<BR>
-
-<LI>truncate</LI><BR>
-小数点以下の数を切り捨てて整数(BigDecimal 値)にします。<BR>
+小数点以下第一位の数を四捨五入して整数(BigDecimal 値)にします。<BR>
+<PRE><CODE>
+ c = BigDecimal("1.23456").round # ==> 1
+ c = BigDecimal("-1.23456").round # ==> -1
+</CODE></PRE>
+
+以下のように引数を与えて、小数点以下 n+1 位の数字を操作することもできます。<BR>
+n が正の時は、小数点以下 n+1 位の数字を四捨五入します(少数点以下を、最大 n 桁にします)。<BR>
+n が負のときは小数点以上 n 桁目をを操作します(小数点位置から左に少なくとも n 個の 0 が並びます)。
+<PRE><CODE>
+c = BigDecimal::new("1.23456").round(4) # ==> 1.2346
+c = BigDecimal::new("15.23456").round(-1) # ==> 20.0
+</CODE></PRE>
+2番目の引数(デフォルトは 0)にゼロ以外を指定すると、いわゆる Banker's rounding になります。<BR>
+ Banker's rounding とは、四捨五入する数字を p として、p &lt; 5 なら切り捨て p &gt; 5 なら切り上げ、
+p がちょうど5のときだけは切り上げ先の数字+1が偶数になるときだけ切り上げます。
+<PRE><CODE>
+c = BigDecimal::new("1.23456").round(3,1) # ==> 1.234
+c = BigDecimal::new("1.23356").round(3,1) # ==> 1.234
+</CODE></PRE>
+
+</BLOCKQUOTE>
+<LI><B>truncate</B></LI><BLOCKQUOTE>
c = a.truncate<BR>
-以下のように引数を与えて、小数点以下 n+1 位の数字を操作することもできます
-(少数点以下を、最大 n 桁にします)。<BR>
-n が正の時は、小数点以下 n+1 位の数字を切り捨てます。
-c = BigDecimal::new("1.23456")<BR>
-d = c.truncate(4) # d = 1.2345 になります。<BR>
- n が負のときは小数点以上 n 桁目をを操作します。<BR>
-c = BigDecimal::new("15.23456")<BR>
-d = c.truncate(-1) # d = 10.0 になります。<BR>
-
-<LI>divmod</LI><BR>
+小数点以下の数を切り捨てて整数(BigDecimal 値)にします。<BR>
+以下のように引数を与えて、小数点以下 n+1 位の数字を操作することもできます。<BR>
+n が正の時は、小数点以下 n+1 位の数字を切り捨てます(少数点以下を、最大 n 桁にします)。
+n が負のときは小数点以上 n 桁目をを操作します(小数点位置から左に少なくとも n 個の 0 が並びます)。<BR>
+<PRE><CODE>
+c = BigDecimal::new("1.23456").truncate(4) # ==> 1.2345
+c = BigDecimal::new("15.23456").truncate(-1) # ==> 10.0
+</CODE></PRE>
+
+</BLOCKQUOTE>
+<LI><B>divmod</B></LI><BLOCKQUOTE>
商と剰余の配列を返します。<BR>
c,r = a.divmod(b) # a = c*b + r<BR>
divmodメソッドは a = c * b + r となる a / b の浮動小数点型の商 c と剰余 r を
@@ -284,85 +353,44 @@ divmodメソッドは a = c * b + r となる a / b の浮動小数点型の商 c と剰余 r を
c = (a/b).floor <BR>
r = a - c*b<BR>
で計算されます。
-<LI>remainder</LI><BR>
+</BLOCKQUOTE>
+<LI><B>remainder</B></LI><BLOCKQUOTE>
r=a.remainder(b)<BR>
a/b の剰余 r を計算します。<BR>
c = (a/b).fix <BR>
r = a - c*b<BR>
で計算されます。
-<LI>abs</LI><BR>
+</BLOCKQUOTE>
+<LI><B>abs</B></LI><BLOCKQUOTE>
aの絶対値<BR>
c = a.abs<BR>
-<LI>to_i</LI><BR>
+</BLOCKQUOTE>
+<LI><B>to_i</B></LI><BLOCKQUOTE>
少数点以下を切り捨てて整数に変換します。<BR>
i = a.to_i<BR>
i は値に応じて Fixnum か Bignum になります。
a が Infinity や NaN のとき、i は nil になります。
-<LI>to_f</LI><BR>
+</BLOCKQUOTE>
+<LI><B>to_f</B></LI><BLOCKQUOTE>
dup と全く同じです。
同じ値の BigDecimal オブジェクトを生成します。
-<LI>to_s[(n)]</LI><BR>
+</BLOCKQUOTE>
+<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
文字列に変換します("0.xxxxxEn"の形になります)。<BR>
s = a.to_s<BR>
n が指定されたときは、仮数部分を n 桁毎に空白で区切ります。<BR>
s = a.to_s(n)
-<LI>exponent</LI><BR>
+</BLOCKQUOTE>
+<LI><B>exponent</B></LI><BLOCKQUOTE>
指数部を整数値で返します。
n = a.exponent <BR>
は a の値が 0.xxxxxxx*10**n を意味します。
-<LI>E</LI><BR>
-自然対数の底e(=2.718281828....)を計算します(正直にテイラー展開で)。<BR>
-e = BigDecimal::E(n)<BR>
-nは必要な有効桁数を整数で指定します。
-<LI>PI</LI><BR>
-円周率(=3.14159265358979....)を計算します(J.Machinの公式を用います)。<BR>
-e = BigDecimal::PI(n)<BR>
-n は必要な有効桁数を整数で指定します。
-<LI>BASE</LI><BR>
-内部で使用される基数の値です。整数が 32 ビットの処理系では10000です。<BR>
-b = BigDecimal::BASE<BR>
-<LI>mode</LI><BR>
-BigDecimalの実行結果を制御します。以下の使用方法が定義されています。<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)<BR>
-f = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)<BR>
-
-EXCEPTION_NaN は結果が NaN になったときの指定です。
-EXCEPTION_INFINITY は結果が無限大(±Infinity)
-になったときの指定です。
-EXCEPTION_UNDERFLOW は指数部がアンダーフローするときの指定です。
-EXCEPTION_OVERFLOW は指数部がオーバーフローするときの指定です。
-EXCEPTION_ZERODIVIDE はゼロによる割り算を実行したときの指定です。
-EXCEPTION_ALL は、可能な全てに対して一括して設定するときに
-使用します。
-flag が true のときは、指定した状態になったときに例外を発行
-するようになります。
-flag が false(デフォルト)なら、例外は発行されません。計算結果は
-以下のようになります。<BR>
-EXCEPTION_NaN のとき、非数(NaN)<BR>
-EXCEPTION_INFINITY のとき、無限(+ or -Infinity)<BR>
-EXCEPTION_UNDERFLOW のとき、ゼロ<BR>
-EXCEPTION_OVERFLOW のとき、+Infinity か -Infinity<BR>
-EXCEPTION_ZERODIVIDE のとき、+Infinity か -Infinity<BR>
-EXCEPTION_INFINITY、EXCEPTION_OVERFLOW、EXCEPTION_ZERODIVIDE
-は今のところ同じです。<BR>
-戻り値は、設定後の値です。「値」の意味は、例えば
-BigDecimal::EXCEPTION_NaNと「値」の & が ゼロ以外ならば
-EXCEPTION_NaNが設定されているという意味です。
-flag が nil、または、true と false 以外なら現在の設定値が返ります。
+</BLOCKQUOTE>
-<LI>limit([n])</LI><BR>
-生成されるBigDecimalオブジェクトの最大桁数をn桁に制限します。戻り値は
-設定する前の値です。設定値のデフォルト値は0で、桁数無制限という意味です。
-nを指定しない場合は、現状の最大桁数が返ります。<BR>
-mf = BigDecimal::limit(n)<BR>
-<LI>sign</LI><BR>
+<LI><B>sign</B></LI><BLOCKQUOTE>
値の属性を返します。
n = a.sign <BR>
としたとき n の値は a が以下のときを意味します。<BR>
@@ -375,26 +403,40 @@ n = BigDecimal::SIGN_NEGATIVE_FINITE(-2) : a は負の値<BR>
n = BigDecimal::SIGN_POSITIVE_INFINITE(3) : a は+Infinity<BR>
n = BigDecimal::SIGN_NEGATIVE_INFINITE(-3) : a は-Infinity<BR>
-<LI>nan?</LI><BR>
+</BLOCKQUOTE>
+<LI><B>nan?</B></LI><BLOCKQUOTE>
a.nan? は a がNaNのとき真を返します。
-<LI>infinite?</LI><BR>
-a.infinite? は a が+∞または-∞のとき真を返します。
-<LI>finite?</LI><BR>
+</BLOCKQUOTE>
+<LI><B>infinite?</B></LI><BLOCKQUOTE>
+a.infinite? は a が+∞のとき 1 、-∞のときは -1、それ以外のときは nil を返します。
+</BLOCKQUOTE>
+<LI><B>finite?</B></LI><BLOCKQUOTE>
a.finite? は a が∞または NaN でないとき真を返します。
+</BLOCKQUOTE>
-<LI>to_parts</LI><BR>
+<LI><B>zero?</B></LI><BLOCKQUOTE>
+a が 0 なら true になります。<BR>
+c = a.zero?
+</BLOCKQUOTE>
+<LI><B>nonzero?</B></LI><BLOCKQUOTE>
+a が 0 なら nil、0 以外なら a そのものが返ります。<BR>
+c = a.nonzero?
+
+</BLOCKQUOTE>
+<LI><B>split</B></LI><BLOCKQUOTE>
BigDecimal 値を 0.xxxxxxx*10**n と表現したときに、符号(NaNのときは
0、それ以外は+1か-1になります)、
仮数部分の文字列("xxxxxxx")と、基数(10)、更に指数 n を配列で
返します。<BR>
-a=BigDecimal::new("3.14159265",10)<BR>
-f,x,y,z = a.to_parts<BR>
+a=BigDecimal::new("3.14159265")<BR>
+f,x,y,z = a.split<BR>
とすると、f=+1、x="314159265"、y=10、z=1になります。<BR>
従って、<BR>
s = "0."+x<BR>
b = f*(s.to_f)*(y**z)<BR>
で Float に変換することができます。
-<LI>inspect</LI><BR>
+</BLOCKQUOTE>
+<LI><B>inspect</B></LI><BLOCKQUOTE>
デバッグ出力に使用されます。<BR>
p a=BigDecimal::new("3.14",10)<BR>
とすると、[0x112344:'0.314E1',4(12)]のように出力されます。
@@ -402,47 +444,54 @@ p a=BigDecimal::new("3.14",10)<BR>
次の4は現在の有効桁数(表示より若干大きいことがあります)、
最後はオブジェクトが取り得る最大桁数になります。
-<LI>dup</LI><BR>
+</BLOCKQUOTE>
+<LI><B>dup</B></LI><BLOCKQUOTE>
同じ値の BigDecimal オブジェクトを生成します。
-<LI>sqrt</LI><BR>
+</BLOCKQUOTE>
+<LI><B>sqrt</B></LI><BLOCKQUOTE>
aの有効桁 n 桁の平方根(n の平方根ではありません)。
これまた、正直にニュートン法で計算します。<BR>
c = a.sqrt(n)<BR>
-<LI>sincos</LI><BR>
+</BLOCKQUOTE>
+<LI><B>sincos</B></LI><BLOCKQUOTE>
a の有効桁 n 桁の sin と cos を同時に(テイラー展開で)計算して、
sin と cos の配列を返します。
n は必要な有効桁数です( n の sin や cos を計算するわけではありません)。
<BR>
sin,cos = a.sincos(n)<BR>
|a|<2*3.1415....でないと正しい答えを計算できないこともあります。
-<LI>exp</LI><BR>
+</BLOCKQUOTE>
+<LI><B>exp</B></LI><BLOCKQUOTE>
自然対数の底e(=2.718281828....)の a 乗を計算します。<BR>
c = a.exp(n)<BR>
n は必要な有効桁数です。
-<LI>power</LI><BR>
+</BLOCKQUOTE>
+<LI><B>**</B></LI><BLOCKQUOTE>
a の n 乗を計算します。nは整数。<BR>
+c = a ** n<BR>
+結果として c の有効桁は a の n 倍以上になるので注意。
+</BLOCKQUOTE>
+<LI><B>power</B></LI><BLOCKQUOTE>
+** と同じで、a の n 乗を計算します。nは整数。<BR>
c = a.power(n)<BR>
結果として c の有効桁は a の n 倍以上になるので注意。
-<LI>zero?</LI><BR>
-a が 0 なら true になります。<BR>
-c = a.zero?<BR>
-<LI>nonzero?</LI><BR>
-a が 0 なら false、0 以外なら a そのものが返ります。<BR>
-c = a.nonzero?<BR>
-<LI>&lt=&gt</LI><BR>
+</BLOCKQUOTE>
+
+<LI><B>&lt=&gt</B></LI><BLOCKQUOTE>
a==b なら 0、a &gt b なら 1、a &lt b なら -1 になります。<BR>
-c = a &lt=&gt b <BR>
+c = a &lt=&gt b
+</BLOCKQUOTE>
</UL>
後は、読んで字の如くです。<BR>
<UL>
-<LI>==</LI>
-<LI>===</LI>
+<LI><B>==</B></LI>
+<LI><B>===</B></LI>
「==」と同じですが case 文で使用されます。
-<LI>!=</LI>
-<LI>&lt</LI>
-<LI>&lt=</LI>
-<LI>&gt</LI>
-<LI>&gt=</LI>
+<LI><B>!=</B></LI>
+<LI><B>&lt</B></LI>
+<LI><B>&lt=</B></LI>
+<LI><B>&gt</B></LI>
+<LI><B>&gt=</B></LI>
</UL>
<H3>coerceについて</H3>
BigDecimal オブジェクトが算術演算子の左にあるときは、BigDecimal オブジェクトが