mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Ambiguity of BigDecimal::limit removed.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4381 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3d7147bcea
commit
0b6cf4bea8
5 changed files with 97 additions and 70 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Wed Aug 13 23:31:00 2003 Shigeo Kobayashi <shigek@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/bigdecimal.c .h .html: Ambiguity of BigDecimal::limit removed.
|
||||||
|
|
||||||
Wed Aug 13 19:21:34 2003 Christian Neukirchen <chneukirchen@yahoo.de>
|
Wed Aug 13 19:21:34 2003 Christian Neukirchen <chneukirchen@yahoo.de>
|
||||||
|
|
||||||
* lib/webrick/https.rb (HTTPServer#run): should set syncing-mode
|
* lib/webrick/https.rb (HTTPServer#run): should set syncing-mode
|
||||||
|
|
|
@ -8,26 +8,8 @@
|
||||||
* License or the Artistic License, as specified in the README file
|
* License or the Artistic License, as specified in the README file
|
||||||
* of this BigDecimal distribution.
|
* of this BigDecimal distribution.
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTE: Change log in this source removed to reduce source code size.
|
||||||
* For the notes other than listed bellow,see ruby CVS log.
|
* See rev. 1.25 if needed.
|
||||||
* 2003-04-17
|
|
||||||
* Bug in negative.exp(n) reported by Hitoshi Miyazaki fixed.
|
|
||||||
* 2003-03-28
|
|
||||||
* V1.0 checked in to CVS(ruby/ext/bigdecimal).
|
|
||||||
* use rb_str2cstr() instead of STR2CSTR().
|
|
||||||
* 2003-01-03
|
|
||||||
* assign instead of asign(by knu),use string.h functions(by t.saito).
|
|
||||||
* 2002-12-06
|
|
||||||
* The sqrt() bug reported by Bret Jolly fixed.
|
|
||||||
* 2002-5-6
|
|
||||||
* The bug reported by Sako Hiroshi (ruby-list:34988) in to_i fixed.
|
|
||||||
* 2002-4-17
|
|
||||||
* methods prec and double_fig(class method) added(S.K).
|
|
||||||
* 2002-04-04
|
|
||||||
* Copied from BigFloat 1.1.9 and
|
|
||||||
* hash method changed according to the suggestion from Akinori MUSHA <knu@iDaemons.org>.
|
|
||||||
* All ! class methods deactivated(but not actually removed).
|
|
||||||
* to_s and to_s2 merged to one to_s[(n)].
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -74,7 +56,8 @@ BigDecimal_version(VALUE self)
|
||||||
*/
|
*/
|
||||||
static unsigned short VpGetException(void);
|
static unsigned short VpGetException(void);
|
||||||
static void VpSetException(unsigned short f);
|
static void VpSetException(unsigned short f);
|
||||||
static int VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v);
|
static void VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v);
|
||||||
|
static int VpLimitRound(Real *c,U_LONG ixDigit);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* **** BigDecimal part ****
|
* **** BigDecimal part ****
|
||||||
|
@ -229,10 +212,15 @@ BigDecimal_load(VALUE self, VALUE str)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
BigDecimal_mode(VALUE self, VALUE which, VALUE val)
|
BigDecimal_mode(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
|
VALUE which;
|
||||||
|
VALUE val;
|
||||||
|
int na;
|
||||||
unsigned long f,fo;
|
unsigned long f,fo;
|
||||||
|
|
||||||
|
if(rb_scan_args(argc,argv,"11",&which,&val)==1) val = Qnil;
|
||||||
|
|
||||||
Check_Type(which, T_FIXNUM);
|
Check_Type(which, T_FIXNUM);
|
||||||
f = (unsigned long)FIX2INT(which);
|
f = (unsigned long)FIX2INT(which);
|
||||||
|
|
||||||
|
@ -658,7 +646,7 @@ BigDecimal_div(VALUE self, VALUE r)
|
||||||
r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
|
r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
|
||||||
*/
|
*/
|
||||||
/* Round */
|
/* Round */
|
||||||
if(VpIsDef(c) && (!VpIsZero(c))) {
|
if(div->frac[0]) { /* frac[0] must be zero for NaN,INF,Zero */
|
||||||
VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]);
|
VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]);
|
||||||
}
|
}
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
|
@ -816,12 +804,14 @@ BigDecimal_div2(int argc, VALUE *argv, VALUE self)
|
||||||
Real *av=NULL, *bv=NULL, *cv=NULL;
|
Real *av=NULL, *bv=NULL, *cv=NULL;
|
||||||
U_LONG ix = (U_LONG)GetPositiveInt(n);
|
U_LONG ix = (U_LONG)GetPositiveInt(n);
|
||||||
U_LONG mx = (ix+VpBaseFig()*2);
|
U_LONG mx = (ix+VpBaseFig()*2);
|
||||||
|
U_LONG pl = VpSetPrecLimit(0);
|
||||||
GUARD_OBJ(cv,VpCreateRbObject(mx,"0"));
|
GUARD_OBJ(cv,VpCreateRbObject(mx,"0"));
|
||||||
GUARD_OBJ(av,GetVpValue(self,1));
|
GUARD_OBJ(av,GetVpValue(self,1));
|
||||||
GUARD_OBJ(bv,GetVpValue(b,1));
|
GUARD_OBJ(bv,GetVpValue(b,1));
|
||||||
mx = cv->MaxPrec+1;
|
mx = cv->MaxPrec+1;
|
||||||
GUARD_OBJ(res,VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0"));
|
GUARD_OBJ(res,VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0"));
|
||||||
VpDivd(cv,res,av,bv);
|
VpDivd(cv,res,av,bv);
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
VpLeftRound(cv,VpGetRoundMode(),ix);
|
VpLeftRound(cv,VpGetRoundMode(),ix);
|
||||||
return ToValue(cv);
|
return ToValue(cv);
|
||||||
}
|
}
|
||||||
|
@ -833,7 +823,9 @@ BigDecimal_add2(VALUE self, VALUE b, VALUE n)
|
||||||
ENTER(2);
|
ENTER(2);
|
||||||
Real *cv;
|
Real *cv;
|
||||||
U_LONG mx = (U_LONG)GetPositiveInt(n);
|
U_LONG mx = (U_LONG)GetPositiveInt(n);
|
||||||
|
U_LONG pl = VpSetPrecLimit(0);
|
||||||
VALUE c = BigDecimal_add(self,b);
|
VALUE c = BigDecimal_add(self,b);
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
GUARD_OBJ(cv,GetVpValue(c,1));
|
GUARD_OBJ(cv,GetVpValue(c,1));
|
||||||
VpLeftRound(cv,VpGetRoundMode(),mx);
|
VpLeftRound(cv,VpGetRoundMode(),mx);
|
||||||
return ToValue(cv);
|
return ToValue(cv);
|
||||||
|
@ -845,7 +837,9 @@ BigDecimal_sub2(VALUE self, VALUE b, VALUE n)
|
||||||
ENTER(2);
|
ENTER(2);
|
||||||
Real *cv;
|
Real *cv;
|
||||||
U_LONG mx = (U_LONG)GetPositiveInt(n);
|
U_LONG mx = (U_LONG)GetPositiveInt(n);
|
||||||
|
U_LONG pl = VpSetPrecLimit(0);
|
||||||
VALUE c = BigDecimal_sub(self,b);
|
VALUE c = BigDecimal_sub(self,b);
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
GUARD_OBJ(cv,GetVpValue(c,1));
|
GUARD_OBJ(cv,GetVpValue(c,1));
|
||||||
VpLeftRound(cv,VpGetRoundMode(),mx);
|
VpLeftRound(cv,VpGetRoundMode(),mx);
|
||||||
return ToValue(cv);
|
return ToValue(cv);
|
||||||
|
@ -857,7 +851,9 @@ BigDecimal_mult2(VALUE self, VALUE b, VALUE n)
|
||||||
ENTER(2);
|
ENTER(2);
|
||||||
Real *cv;
|
Real *cv;
|
||||||
U_LONG mx = (U_LONG)GetPositiveInt(n);
|
U_LONG mx = (U_LONG)GetPositiveInt(n);
|
||||||
|
U_LONG pl = VpSetPrecLimit(0);
|
||||||
VALUE c = BigDecimal_mult(self,b);
|
VALUE c = BigDecimal_mult(self,b);
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
GUARD_OBJ(cv,GetVpValue(c,1));
|
GUARD_OBJ(cv,GetVpValue(c,1));
|
||||||
VpLeftRound(cv,VpGetRoundMode(),mx);
|
VpLeftRound(cv,VpGetRoundMode(),mx);
|
||||||
return ToValue(cv);
|
return ToValue(cv);
|
||||||
|
@ -919,6 +915,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
||||||
U_LONG mx;
|
U_LONG mx;
|
||||||
VALUE vLoc;
|
VALUE vLoc;
|
||||||
VALUE vRound;
|
VALUE vRound;
|
||||||
|
U_LONG pl;
|
||||||
|
|
||||||
int sw = VpGetRoundMode();
|
int sw = VpGetRoundMode();
|
||||||
|
|
||||||
|
@ -943,9 +940,11 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pl = VpSetPrecLimit(0);
|
||||||
GUARD_OBJ(a,GetVpValue(self,1));
|
GUARD_OBJ(a,GetVpValue(self,1));
|
||||||
mx = a->Prec *(VpBaseFig() + 1);
|
mx = a->Prec *(VpBaseFig() + 1);
|
||||||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
VpActiveRound(c,a,sw,iLoc);
|
VpActiveRound(c,a,sw,iLoc);
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
}
|
}
|
||||||
|
@ -958,6 +957,7 @@ BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
|
||||||
int iLoc;
|
int iLoc;
|
||||||
U_LONG mx;
|
U_LONG mx;
|
||||||
VALUE vLoc;
|
VALUE vLoc;
|
||||||
|
U_LONG pl = VpSetPrecLimit(0);
|
||||||
|
|
||||||
if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
|
if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
|
||||||
iLoc = 0;
|
iLoc = 0;
|
||||||
|
@ -969,6 +969,7 @@ BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
|
||||||
GUARD_OBJ(a,GetVpValue(self,1));
|
GUARD_OBJ(a,GetVpValue(self,1));
|
||||||
mx = a->Prec *(VpBaseFig() + 1);
|
mx = a->Prec *(VpBaseFig() + 1);
|
||||||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
VpActiveRound(c,a,VP_ROUND_DOWN,iLoc); /* 0: truncate */
|
VpActiveRound(c,a,VP_ROUND_DOWN,iLoc); /* 0: truncate */
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
}
|
}
|
||||||
|
@ -995,6 +996,7 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
|
||||||
U_LONG mx;
|
U_LONG mx;
|
||||||
int iLoc;
|
int iLoc;
|
||||||
VALUE vLoc;
|
VALUE vLoc;
|
||||||
|
U_LONG pl = VpSetPrecLimit(0);
|
||||||
|
|
||||||
if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
|
if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
|
||||||
iLoc = 0;
|
iLoc = 0;
|
||||||
|
@ -1006,6 +1008,7 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
|
||||||
GUARD_OBJ(a,GetVpValue(self,1));
|
GUARD_OBJ(a,GetVpValue(self,1));
|
||||||
mx = a->Prec *(VpBaseFig() + 1);
|
mx = a->Prec *(VpBaseFig() + 1);
|
||||||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);
|
VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
}
|
}
|
||||||
|
@ -1018,6 +1021,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
|
||||||
U_LONG mx;
|
U_LONG mx;
|
||||||
int iLoc;
|
int iLoc;
|
||||||
VALUE vLoc;
|
VALUE vLoc;
|
||||||
|
U_LONG pl = VpSetPrecLimit(0);
|
||||||
|
|
||||||
if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
|
if(rb_scan_args(argc,argv,"01",&vLoc)==0) {
|
||||||
iLoc = 0;
|
iLoc = 0;
|
||||||
|
@ -1029,6 +1033,7 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
|
||||||
GUARD_OBJ(a,GetVpValue(self,1));
|
GUARD_OBJ(a,GetVpValue(self,1));
|
||||||
mx = a->Prec *(VpBaseFig() + 1);
|
mx = a->Prec *(VpBaseFig() + 1);
|
||||||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||||
|
VpSetPrecLimit(pl);
|
||||||
VpActiveRound(c,a,VP_ROUND_CEIL,iLoc);
|
VpActiveRound(c,a,VP_ROUND_CEIL,iLoc);
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
}
|
}
|
||||||
|
@ -1205,8 +1210,14 @@ BigDecimal_limit(int argc, VALUE *argv, VALUE self)
|
||||||
VALUE nCur = INT2NUM(VpGetPrecLimit());
|
VALUE nCur = INT2NUM(VpGetPrecLimit());
|
||||||
|
|
||||||
if(rb_scan_args(argc,argv,"01",&nFig)==1) {
|
if(rb_scan_args(argc,argv,"01",&nFig)==1) {
|
||||||
|
int nf;
|
||||||
|
if(nFig==Qnil) return nCur;
|
||||||
Check_Type(nFig, T_FIXNUM);
|
Check_Type(nFig, T_FIXNUM);
|
||||||
VpSetPrecLimit(FIX2INT(nFig));
|
nf = FIX2INT(nFig);
|
||||||
|
if(nf<0) {
|
||||||
|
rb_raise(rb_eArgError, "argument must be positive");
|
||||||
|
}
|
||||||
|
VpSetPrecLimit(nf);
|
||||||
}
|
}
|
||||||
return nCur;
|
return nCur;
|
||||||
}
|
}
|
||||||
|
@ -1298,7 +1309,7 @@ Init_bigdecimal(void)
|
||||||
|
|
||||||
/* Class methods */
|
/* Class methods */
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_new, -1);
|
rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_new, -1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, 2);
|
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "induced_from",BigDecimal_induced_from, 1);
|
rb_define_singleton_method(rb_cBigDecimal, "induced_from",BigDecimal_induced_from, 1);
|
||||||
|
@ -2057,7 +2068,7 @@ VpAsgn(Real *c, Real *a, int isw)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(VpIsInf(a)) {
|
if(VpIsInf(a)) {
|
||||||
VpSetInf(c,isw);
|
VpSetInf(c,isw*VpGetSign(a));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2069,8 +2080,13 @@ VpAsgn(Real *c, Real *a, int isw)
|
||||||
c->Prec = n;
|
c->Prec = n;
|
||||||
memcpy(c->frac, a->frac, n * sizeof(U_LONG));
|
memcpy(c->frac, a->frac, n * sizeof(U_LONG));
|
||||||
/* Needs round ? */
|
/* Needs round ? */
|
||||||
if(c->Prec < a->Prec) {
|
if(isw!=10) {
|
||||||
VpInternalRound(c,n,(n>0)?a->frac[n-1]:0,a->frac[n]);
|
/* Not in ActiveRound */
|
||||||
|
if(c->Prec < a->Prec) {
|
||||||
|
VpInternalRound(c,n,(n>0)?a->frac[n-1]:0,a->frac[n]);
|
||||||
|
} else {
|
||||||
|
VpLimitRound(c,0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The value of 'a' is zero. */
|
/* The value of 'a' is zero. */
|
||||||
|
@ -2292,8 +2308,7 @@ VpAddAbs(Real *a, Real *b, Real *c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c_pos) c->frac[c_pos - 1] += carry;
|
if(c_pos) c->frac[c_pos - 1] += carry;
|
||||||
|
VpInternalRound(c,0,(c->Prec>0)?a->frac[c->Prec-1]:0,mrv);
|
||||||
if(!VpInternalRound(c,0,(c->Prec>0)?a->frac[c->Prec-1]:0,mrv)) VpNmlz(c);
|
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
Assign_a:
|
Assign_a:
|
||||||
|
@ -2406,8 +2421,7 @@ VpSubAbs(Real *a, Real *b, Real *c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c_pos) c->frac[c_pos - 1] -= borrow;
|
if(c_pos) c->frac[c_pos - 1] -= borrow;
|
||||||
|
VpInternalRound(c,0,(c->Prec>0)?a->frac[c->Prec-1]:0,mrv);
|
||||||
if(!VpInternalRound(c,0,(c->Prec>0)?a->frac[c->Prec-1]:0,mrv)) VpNmlz(c);
|
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
Assign_a:
|
Assign_a:
|
||||||
|
@ -3128,8 +3142,7 @@ VpExponent10(Real *a)
|
||||||
S_LONG ex;
|
S_LONG ex;
|
||||||
U_LONG n;
|
U_LONG n;
|
||||||
|
|
||||||
if(!VpIsDef(a)) return 0;
|
if(!VpHasVal(a)) return 0;
|
||||||
if(VpIsZero(a)) return 0;
|
|
||||||
|
|
||||||
ex =(a->exponent) * BASE_FIG;
|
ex =(a->exponent) * BASE_FIG;
|
||||||
n = BASE1;
|
n = BASE1;
|
||||||
|
@ -3564,8 +3577,8 @@ VpDtoV(Real *m, double d)
|
||||||
m->Prec = ind_m + 1;
|
m->Prec = ind_m + 1;
|
||||||
m->exponent = ne;
|
m->exponent = ne;
|
||||||
|
|
||||||
if(!VpInternalRound(m,0,(m->Prec>0)?m->frac[m->Prec-1]:0,
|
VpInternalRound(m,0,(m->Prec>0)?m->frac[m->Prec-1]:0,
|
||||||
(U_LONG)(val*((double)((S_INT)BASE))))) VpNmlz(m);
|
(U_LONG)(val*((double)((S_INT)BASE))));
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -3653,19 +3666,14 @@ VpSqrt(Real *y, Real *x)
|
||||||
S_LONG nr;
|
S_LONG nr;
|
||||||
double val;
|
double val;
|
||||||
|
|
||||||
if(!VpIsDef(x)) {
|
if(!VpHasVal(x)) {
|
||||||
VpAsgn(y,x,1);
|
VpAsgn(y,x,1);
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VpIsZero(x)) {
|
|
||||||
VpSetZero(y,VpGetSign(x));
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(VpGetSign(x) < 0) {
|
if(VpGetSign(x) < 0) {
|
||||||
VpSetZero(y,VpGetSign(x));
|
VpSetNaN(y);
|
||||||
return VpException(VP_EXCEPTION_OP,"(VpSqrt) SQRT(negative valuw)",0);
|
return VpException(VP_EXCEPTION_OP,"(VpSqrt) SQRT(negative value)",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = (S_LONG)y->MaxPrec;
|
n = (S_LONG)y->MaxPrec;
|
||||||
|
@ -3769,7 +3777,6 @@ VpMidRound(Real *y, int f, int nf)
|
||||||
if(ix<0 || ((U_LONG)ix)>=y->Prec) return; /* Unable to round */
|
if(ix<0 || ((U_LONG)ix)>=y->Prec) return; /* Unable to round */
|
||||||
ioffset = nf - ix*((int)BASE_FIG);
|
ioffset = nf - ix*((int)BASE_FIG);
|
||||||
memset(y->frac+ix+1, 0, (y->Prec - (ix+1)) * sizeof(U_LONG));
|
memset(y->frac+ix+1, 0, (y->Prec - (ix+1)) * sizeof(U_LONG));
|
||||||
/* VpNmlz(y); */
|
|
||||||
v = y->frac[ix];
|
v = y->frac[ix];
|
||||||
/* drop digits after pointed digit */
|
/* drop digits after pointed digit */
|
||||||
n = BASE_FIG - ioffset - 1;
|
n = BASE_FIG - ioffset - 1;
|
||||||
|
@ -3830,8 +3837,7 @@ VpLeftRound(Real *y, int f, int nf)
|
||||||
{
|
{
|
||||||
U_LONG v;
|
U_LONG v;
|
||||||
|
|
||||||
if(!VpIsDef(y)) return; /* Unable to round */
|
if(!VpHasVal(y)) return; /* Unable to round */
|
||||||
if(VpIsZero(y)) return;
|
|
||||||
|
|
||||||
v = y->frac[0];
|
v = y->frac[0];
|
||||||
nf -= VpExponent(y)*BASE_FIG;
|
nf -= VpExponent(y)*BASE_FIG;
|
||||||
|
@ -3844,19 +3850,31 @@ VP_EXPORT void
|
||||||
VpActiveRound(Real *y, Real *x, int f, int nf)
|
VpActiveRound(Real *y, Real *x, int f, int nf)
|
||||||
{
|
{
|
||||||
/* First,assign whole value in truncation mode */
|
/* First,assign whole value in truncation mode */
|
||||||
VpAsgn(y, x, 1); /* 1 round off,2 round up */
|
if(VpAsgn(y, x, 10)<=1) return; /* Zero,NaN,or Infinity */
|
||||||
if(!VpIsDef(y)) return; /* Unable to round */
|
|
||||||
if(VpIsZero(y)) return;
|
|
||||||
VpMidRound(y,f,nf);
|
VpMidRound(y,f,nf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
VpLimitRound(Real *c,U_LONG ixDigit)
|
||||||
|
{
|
||||||
|
U_LONG ix = VpGetPrecLimit();
|
||||||
|
if(!ix) return 0;
|
||||||
|
if(!ixDigit) ixDigit = c->Prec;
|
||||||
|
if((ix+BASE_FIG-1)/BASE_FIG >= ixDigit) return 0;
|
||||||
|
VpLeftRound(c,VpGetRoundMode(),ix);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v)
|
VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v)
|
||||||
{
|
{
|
||||||
int f = 0;
|
int f = 0;
|
||||||
|
|
||||||
if(!VpIsDef(c)) return f; /* Unable to round */
|
VpNmlz(c);
|
||||||
if(VpIsZero(c)) return f;
|
|
||||||
|
if(!VpHasVal(c)) return; /* Unable to round */
|
||||||
|
|
||||||
|
if(VpLimitRound(c,ixDigit)) return;
|
||||||
|
|
||||||
v /= BASE1;
|
v /= BASE1;
|
||||||
switch(gfRoundMode) {
|
switch(gfRoundMode) {
|
||||||
|
@ -3882,8 +3900,10 @@ VpInternalRound(Real *c,int ixDigit,U_LONG vPrev,U_LONG v)
|
||||||
else if(v==5 && vPrev%2) f = 1;
|
else if(v==5 && vPrev%2) f = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(f) VpRdup(c,ixDigit); /* round up */
|
if(f) {
|
||||||
return f;
|
VpRdup(c,ixDigit); /* round up */
|
||||||
|
VpNmlz(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3919,7 +3939,7 @@ VpFrac(Real *y, Real *x)
|
||||||
{
|
{
|
||||||
U_LONG my, ind_y, ind_x;
|
U_LONG my, ind_y, ind_x;
|
||||||
|
|
||||||
if(!VpIsDef(x) || VpIsZero(x)) {
|
if(!VpHasVal(x)) {
|
||||||
VpAsgn(y,x,1);
|
VpAsgn(y,x,1);
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,7 @@ VP_EXPORT void VpSinCos(Real *psin,Real *pcos,Real *x);
|
||||||
#define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE)
|
#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 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 VpSetInf(a,s) ( ((s)>0)?VpSetPosInf(a):VpSetNegInf(a) )
|
||||||
|
#define VpHasVal(a) (a->frac[0])
|
||||||
#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1))
|
#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1))
|
||||||
#define VpExponent(a) (a->exponent)
|
#define VpExponent(a) (a->exponent)
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
|
@ -118,7 +118,10 @@ but the resulting digits obtained may differ in future version.
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<LI><B>mode</B></LI><BLOCKQUOTE>
|
<LI><B>mode</B></LI><BLOCKQUOTE>
|
||||||
mode method controls BigDecimal computation.Following usage are defined.<BR>
|
f = BigDecimal.mode(s[,v])<BR>
|
||||||
|
mode method controls BigDecimal computation. If the second argument is not given or is nil,then the value
|
||||||
|
of current setting is returned.
|
||||||
|
Following usage are defined.<BR>
|
||||||
<P><B>[EXCEPTION control]</B><P>
|
<P><B>[EXCEPTION control]</B><P>
|
||||||
Actions when computation results NaN or Infinity can be defined as follows.
|
Actions when computation results NaN or Infinity can be defined as follows.
|
||||||
<P>
|
<P>
|
||||||
|
@ -175,13 +178,12 @@ use truncate/round/ceil/floor/add/sub/mult/div mthods for each instance instead.
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<LI><B>limit[(n)]</B></LI><BLOCKQUOTE>
|
<LI><B>limit[(n)]</B></LI><BLOCKQUOTE>
|
||||||
Limits the maximum digits that the newly created BigDecimal objects can hold
|
Limits the maximum digits that the newly created BigDecimal objects can hold never exceed n.
|
||||||
never exceed n+? (Currently,? can not be determined beforehand,but not so big).
|
|
||||||
This means the rounding operation specified by BigDecimal.mode is
|
This means the rounding operation specified by BigDecimal.mode is
|
||||||
performed if necessary.
|
performed if necessary.
|
||||||
limit returns maximum value before set.
|
limit returns the value before set if n is nil or is not specified.
|
||||||
Zero,the default value,means no upper limit.<BR>
|
Zero,the default value,means no upper limit.<BR>
|
||||||
Except for zero,the limit has more priority than instance methods such as truncate,round,ceil,floor,add,sub,mult,and div. <BR>
|
The limit has no more priority than instance methods such as truncate,round,ceil,floor,add,sub,mult,and div. <BR>
|
||||||
mf = BigDecimal::limit(n)<BR>
|
mf = BigDecimal::limit(n)<BR>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,10 @@ BigDecimal("1",10) / BigDecimal("3",10) # => 0.3333333333 3333333333 33333333E0
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<LI><B>mode</B></LI><BLOCKQUOTE>
|
<LI><B>mode</B></LI><BLOCKQUOTE>
|
||||||
BigDecimalの実行結果を制御します。以下の使用方法が定義されています。
|
f = BigDecimal.mode(s[,v])<BR>
|
||||||
|
BigDecimalの実行結果を制御します。第2引数を省略、または nil を指定すると
|
||||||
|
現状の設定値が戻ります。<BR>
|
||||||
|
以下の使用方法が定義されています。
|
||||||
<P>
|
<P>
|
||||||
<B>[例外処理]</B><P>
|
<B>[例外処理]</B><P>
|
||||||
計算結果が非数(NaN)やゼロによる除算になったときの処理を定義することができます。
|
計算結果が非数(NaN)やゼロによる除算になったときの処理を定義することができます。
|
||||||
|
@ -159,8 +162,7 @@ EXCEPTION_INFINITY
|
||||||
は今のところ同じです。<BR>
|
は今のところ同じです。<BR>
|
||||||
戻り値は、設定後の値です。「値」の意味は、例えば
|
戻り値は、設定後の値です。「値」の意味は、例えば
|
||||||
BigDecimal::EXCEPTION_NaNと「値」の & が ゼロ以外ならば
|
BigDecimal::EXCEPTION_NaNと「値」の & が ゼロ以外ならば
|
||||||
EXCEPTION_NaNが設定されているという意味です。<BR>
|
EXCEPTION_NaNが設定されているという意味です。
|
||||||
第2引数に nil を指定すると、現状の設定値が返ります。
|
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<B>[丸め処理指定]</B><P>
|
<B>[丸め処理指定]</B><P>
|
||||||
|
@ -183,20 +185,18 @@ f = BigDecimal::mode(BigDecimal::ROUND_MODE,flag)
|
||||||
戻り値は指定後の flag の値です。
|
戻り値は指定後の flag の値です。
|
||||||
第2引数に nil を指定すると、現状の設定値が返ります。
|
第2引数に nil を指定すると、現状の設定値が返ります。
|
||||||
mode メソッドでは丸め操作の位置をユーザが指定することはできません。
|
mode メソッドでは丸め操作の位置をユーザが指定することはできません。
|
||||||
丸め操作と位置を自分で制御したい場合は truncate/round/ceil/floor や
|
丸め操作と位置を自分で制御したい場合は BigDecimal::limit や truncate/round/ceil/floor、
|
||||||
add/sub/mult/div といったインスタンスメソッドを使用して下さい。
|
add/sub/mult/div といったインスタンスメソッドを使用して下さい。
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>limit([n])</B></LI><BLOCKQUOTE>
|
<LI><B>limit([n])</B></LI><BLOCKQUOTE>
|
||||||
生成されるBigDecimalオブジェクトの最大桁数をn桁に制限します。
|
生成されるBigDecimalオブジェクトの最大桁数をn桁に制限します。
|
||||||
戻り値は設定する前の値です。設定値のデフォルト値は0で、桁数無制限という意味です。
|
戻り値は設定する前の値です。設定値のデフォルト値は0で、桁数無制限という意味です。
|
||||||
n を指定しない場合は、現状の最大桁数が返ります。<BR>
|
n を指定しない、または n が nil の場合は、現状の最大桁数が返ります。<BR>
|
||||||
計算を続行する間に、数字の桁数が無制限に増えてしまうような場合
|
計算を続行する間に、数字の桁数が無制限に増えてしまうような場合
|
||||||
limit で予め桁数を制限できます。この場合 BigDecimal.mode で指定された
|
limit で予め桁数を制限できます。この場合 BigDecimal.mode で指定された
|
||||||
丸め処理が実行されます。
|
丸め処理が実行されます。
|
||||||
ただし、実際には n より若干大きい
|
ただし、インスタンスメソッド (truncate/round/ceil/floor/add/sub/mult/div) の
|
||||||
桁数が確保されます。また、limit による桁数制限は(無制限を除いて)、
|
桁数制限は limit より優先されます。<BR>
|
||||||
インスタンスメソッド (truncate/round/ceil/floor/add/sub/mult/div) より
|
|
||||||
優先されるので注意が必要です。<BR>
|
|
||||||
mf = BigDecimal::limit(n)<BR>
|
mf = BigDecimal::limit(n)<BR>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue