mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
7e91b4b546
commit
d3ce235bab
4 changed files with 735 additions and 609 deletions
|
@ -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;
|
||||
unsigned long f,fo;
|
||||
|
||||
if(TYPE(which)!=T_FIXNUM) return INT2FIX(fo);
|
||||
if(val!=Qfalse && val!=Qtrue) return INT2FIX(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);
|
||||
|
@ -813,20 +819,6 @@ BigDecimal_divmod2(VALUE self, VALUE b, VALUE n)
|
|||
return obj;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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 3: /* floor */
|
||||
if(v) {
|
||||
if(VpGetSign(x)<0) ++div;
|
||||
case VP_COMP_MODE_FLOOR: /* floor */
|
||||
if(v && (VpGetSign(x)<0)) ++div;
|
||||
break;
|
||||
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! */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>double_fig</B></LI><BR>
|
||||
<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(<28>}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 & 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>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>+</B></LI><BR>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
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>
|
||||
|
||||
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>
|
||||
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>
|
||||
|
||||
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>
|
||||
|
||||
<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>
|
||||
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>
|
||||
|
||||
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>
|
||||
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>
|
||||
|
||||
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>
|
||||
|
||||
<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<>D<BR>
|
||||
round a to the nearest 1<>D<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<>D<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(<28>}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 +<2B>‡ or -<2D>‡.
|
||||
</BLOCKQUOTE>
|
||||
<LI><B>infinite?</B></LI><BLOCKQUOTE>
|
||||
a.infinite? returns 1 when a is +<2B>‡,-1 when a is -<2D>‡, nil otherwise.
|
||||
|
||||
<LI><B>finite?</B></LI><BR>
|
||||
a.finite? returns True when a is neither <20>‡ nor NaN.
|
||||
</BLOCKQUOTE>
|
||||
<LI><B>finite?</B></LI><BLOCKQUOTE>
|
||||
a.finite? returns true when a is neither <20>‡ nor NaN.
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<LI><B>to_parts</B></LI><BR>
|
||||
<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>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 "#<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><=></B></LI><BR>
|
||||
</BLOCKQUOTE>
|
||||
<LI><B><=></B></LI><BLOCKQUOTE>
|
||||
c = a <=> b <BR>
|
||||
returns 0 if a==b,1 if a > b,and returns -1 if a < b.<BR>
|
||||
</BLOCKQUOTE>
|
||||
</UL>
|
||||
|
||||
Following methods need no explanation.<BR>
|
||||
|
|
|
@ -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 についての詳しい内容は以下の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
|
|||
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 が生成されます)。
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<LI>add</LI><BR>
|
||||
<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
|
|||
と異なり、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>
|
||||
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>
|
||||
|
||||
<LI>ceil</LI><BR>
|
||||
a 以上の整数のうち、最も小さい整数を計算し、その値(BigDecimal 値)を返します。<BR>
|
||||
</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>
|
||||
a 以上の整数のうち、最も小さい整数を計算し、その値(BigDecimal 値)を返します。
|
||||
<PRE><CODE>
|
||||
c = BigDecimal("1.23456").ceil # ==> 2
|
||||
c = BigDecimal("-1.23456").ceil # ==> -1
|
||||
</CODE></PRE>
|
||||
|
||||
<LI>round</LI><BR>
|
||||
小数点以下第一位の数を四捨五入して整数(BigDecimal 値)にします。<BR>
|
||||
以下のように引数を与えて、小数点以下 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>
|
||||
小数点以下第一位の数を四捨五入して整数(BigDecimal 値)にします。<BR>
|
||||
<PRE><CODE>
|
||||
c = BigDecimal("1.23456").round # ==> 1
|
||||
c = BigDecimal("-1.23456").round # ==> -1
|
||||
</CODE></PRE>
|
||||
|
||||
<LI>truncate</LI><BR>
|
||||
小数点以下の数を切り捨てて整数(BigDecimal 値)にします。<BR>
|
||||
以下のように引数を与えて、小数点以下 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 < 5 なら切り捨て p > 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>
|
||||
小数点以下の数を切り捨てて整数(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>
|
||||
|
||||
<LI>divmod</LI><BR>
|
||||
</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
|
|||
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>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
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 以外なら現在の設定値が返ります。
|
||||
|
||||
<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
|
|||
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><=></LI><BR>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<LI><B><=></B></LI><BLOCKQUOTE>
|
||||
a==b なら 0、a > b なら 1、a < b なら -1 になります。<BR>
|
||||
c = a <=> b <BR>
|
||||
c = a <=> b
|
||||
</BLOCKQUOTE>
|
||||
</UL>
|
||||
後は、読んで字の如くです。<BR>
|
||||
<UL>
|
||||
<LI>==</LI>
|
||||
<LI>===</LI>
|
||||
<LI><B>==</B></LI>
|
||||
<LI><B>===</B></LI>
|
||||
「==」と同じですが case 文で使用されます。
|
||||
<LI>!=</LI>
|
||||
<LI><</LI>
|
||||
<LI><=</LI>
|
||||
<LI>></LI>
|
||||
<LI>>=</LI>
|
||||
<LI><B>!=</B></LI>
|
||||
<LI><B><</B></LI>
|
||||
<LI><B><=</B></LI>
|
||||
<LI><B>></B></LI>
|
||||
<LI><B>>=</B></LI>
|
||||
</UL>
|
||||
<H3>coerceについて</H3>
|
||||
BigDecimal オブジェクトが算術演算子の左にあるときは、BigDecimal オブジェクトが
|
||||
|
|
Loading…
Add table
Reference in a new issue