From e52a4a70a95e3d334608ab7534cda83b03512365 Mon Sep 17 00:00:00 2001 From: mrkn Date: Fri, 22 Mar 2013 01:38:55 +0000 Subject: * ext/bigdecimal/bigdecimal.c: Fix style. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39872 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/bigdecimal/bigdecimal.c | 3379 ++++++++++++++++++++++--------------------- 1 file changed, 1720 insertions(+), 1659 deletions(-) (limited to 'ext/bigdecimal/bigdecimal.c') diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index fe181d5b8d..871001f1f6 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -149,7 +149,7 @@ BigDecimal_memsize(const void *ptr) static const rb_data_type_t BigDecimal_data_type = { "BigDecimal", - {0, BigDecimal_delete, BigDecimal_memsize,}, + { 0, BigDecimal_delete, BigDecimal_memsize, }, }; static inline int @@ -161,12 +161,14 @@ is_kind_of_BigDecimal(VALUE const v) static VALUE ToValue(Real *p) { - if(VpIsNaN(p)) { - VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",0); - } else if(VpIsPosInf(p)) { - VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",0); - } else if(VpIsNegInf(p)) { - VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",0); + if (VpIsNaN(p)) { + VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'(Not a Number)", 0); + } + else if (VpIsPosInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0); + } + else if (VpIsNegInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 0); } return p->obj; } @@ -200,11 +202,10 @@ GetVpValueWithPrec(VALUE v, long prec, int must) VALUE orig = Qundef; again: - switch(TYPE(v)) - { + switch(TYPE(v)) { case T_FLOAT: if (prec < 0) goto unable_to_coerce_without_prec; - if (prec > DBL_DIG+1)goto SomeOneMayDoIt; + if (prec > DBL_DIG+1) goto SomeOneMayDoIt; v = rb_funcall(v, id_to_r, 0); goto again; case T_RATIONAL: @@ -303,7 +304,7 @@ BigDecimal_prec(VALUE self) Real *p; VALUE obj; - GUARD_OBJ(p,GetVpValue(self,1)); + GUARD_OBJ(p, GetVpValue(self, 1)); obj = rb_assoc_new(INT2NUM(p->Prec*VpBaseFig()), INT2NUM(p->MaxPrec*VpBaseFig())); return obj; @@ -324,7 +325,7 @@ BigDecimal_hash(VALUE self) Real *p; st_index_t hash; - GUARD_OBJ(p,GetVpValue(self,1)); + GUARD_OBJ(p, GetVpValue(self, 1)); hash = (st_index_t)p->sign; /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */ if(hash == 2 || hash == (st_index_t)-2) { @@ -356,8 +357,8 @@ BigDecimal_dump(int argc, VALUE *argv, VALUE self) volatile VALUE dump; rb_scan_args(argc, argv, "01", &dummy); - GUARD_OBJ(vp,GetVpValue(self,1)); - dump = rb_str_new(0,VpNumOfChars(vp,"E")+50); + GUARD_OBJ(vp,GetVpValue(self, 1)); + dump = rb_str_new(0, VpNumOfChars(vp, "E")+50); psz = RSTRING_PTR(dump); sprintf(psz, "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig()); VpToString(vp, psz+strlen(psz), 0, 0); @@ -380,16 +381,18 @@ BigDecimal_load(VALUE self, VALUE str) SafeStringValue(str); pch = (unsigned char *)RSTRING_PTR(str); /* First get max prec */ - while((*pch)!=(unsigned char)'\0' && (ch=*pch++)!=(unsigned char)':') { + while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') { if(!ISDIGIT(ch)) { rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string"); } m = m*10 + (unsigned long)(ch-'0'); } - if(m>VpBaseFig()) m -= VpBaseFig(); - GUARD_OBJ(pv,VpNewRbClass(m,(char *)pch,self)); + if (m > VpBaseFig()) m -= VpBaseFig(); + GUARD_OBJ(pv, VpNewRbClass(m, (char *)pch, self)); m /= VpBaseFig(); - if(m && pv->MaxPrec>m) pv->MaxPrec = m+1; + if (m && pv->MaxPrec > m) { + pv->MaxPrec = m+1; + } return ToValue(pv); } @@ -474,40 +477,39 @@ BigDecimal_mode(int argc, VALUE *argv, VALUE self) VALUE val; unsigned long f,fo; - if(rb_scan_args(argc,argv,"11",&which,&val)==1) val = Qnil; - + rb_scan_args(argc, argv, "11", &which, &val); Check_Type(which, T_FIXNUM); f = (unsigned long)FIX2INT(which); - if(f&VP_EXCEPTION_ALL) { - /* Exception mode setting */ - fo = VpGetException(); - if(val==Qnil) return INT2FIX(fo); - if(val!=Qfalse && val!=Qtrue) { - rb_raise(rb_eArgError, "second argument must be true or false"); - return Qnil; /* Not reached */ - } - if(f&VP_EXCEPTION_INFINITY) { - VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY): - (fo&(~VP_EXCEPTION_INFINITY)))); - } - fo = VpGetException(); - if(f&VP_EXCEPTION_NaN) { - VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN): - (fo&(~VP_EXCEPTION_NaN)))); - } - fo = VpGetException(); - if(f&VP_EXCEPTION_UNDERFLOW) { - VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_UNDERFLOW): - (fo&(~VP_EXCEPTION_UNDERFLOW)))); - } - fo = VpGetException(); - if(f&VP_EXCEPTION_ZERODIVIDE) { - VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_ZERODIVIDE): - (fo&(~VP_EXCEPTION_ZERODIVIDE)))); - } - fo = VpGetException(); - return INT2FIX(fo); + if (f & VP_EXCEPTION_ALL) { + /* Exception mode setting */ + fo = VpGetException(); + if (val == Qnil) return INT2FIX(fo); + if (val != Qfalse && val!=Qtrue) { + rb_raise(rb_eArgError, "second argument must be true or false"); + return Qnil; /* Not reached */ + } + if (f & VP_EXCEPTION_INFINITY) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_INFINITY) : + (fo & (~VP_EXCEPTION_INFINITY)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_NaN) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_NaN) : + (fo & (~VP_EXCEPTION_NaN)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_UNDERFLOW) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_UNDERFLOW) : + (fo & (~VP_EXCEPTION_UNDERFLOW)))); + } + fo = VpGetException(); + if(f & VP_EXCEPTION_ZERODIVIDE) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_ZERODIVIDE) : + (fo & (~VP_EXCEPTION_ZERODIVIDE)))); + } + fo = VpGetException(); + return INT2FIX(fo); } if (VP_ROUND_MODE == f) { /* Rounding mode setting */ @@ -529,16 +531,16 @@ GetAddSubPrec(Real *a, Real *b) size_t mx = a->Prec; SIGNED_VALUE d; - if(!VpIsDef(a) || !VpIsDef(b)) return (size_t)-1L; - if(mx < b->Prec) mx = b->Prec; - if(a->exponent!=b->exponent) { - mxs = mx; - d = a->exponent - b->exponent; - if (d < 0) d = -d; - mx = mx + (size_t)d; - if (mxPrec) mx = b->Prec; + if (a->exponent != b->exponent) { + mxs = mx; + d = a->exponent - b->exponent; + if (d < 0) d = -d; + mx = mx + (size_t)d; + if (mx < mxs) { + return VpException(VP_EXCEPTION_INFINITY, "Exponent overflow", 0); + } } return mx; } @@ -550,7 +552,7 @@ GetPositiveInt(VALUE v) Check_Type(v, T_FIXNUM); n = FIX2INT(v); if (n < 0) { - rb_raise(rb_eArgError, "argument must be positive"); + rb_raise(rb_eArgError, "argument must be positive"); } return n; } @@ -594,8 +596,8 @@ VpCopy(Real *pv, Real const* const x) static VALUE BigDecimal_IsNaN(VALUE self) { - Real *p = GetVpValue(self,1); - if(VpIsNaN(p)) return Qtrue; + Real *p = GetVpValue(self, 1); + if (VpIsNaN(p)) return Qtrue; return Qfalse; } @@ -605,9 +607,9 @@ BigDecimal_IsNaN(VALUE self) static VALUE BigDecimal_IsInfinite(VALUE self) { - Real *p = GetVpValue(self,1); - if(VpIsPosInf(p)) return INT2FIX(1); - if(VpIsNegInf(p)) return INT2FIX(-1); + Real *p = GetVpValue(self, 1); + if (VpIsPosInf(p)) return INT2FIX(1); + if (VpIsNegInf(p)) return INT2FIX(-1); return Qnil; } @@ -615,21 +617,23 @@ BigDecimal_IsInfinite(VALUE self) static VALUE BigDecimal_IsFinite(VALUE self) { - Real *p = GetVpValue(self,1); - if(VpIsNaN(p)) return Qfalse; - if(VpIsInf(p)) return Qfalse; + Real *p = GetVpValue(self, 1); + if (VpIsNaN(p)) return Qfalse; + if (VpIsInf(p)) return Qfalse; return Qtrue; } static void BigDecimal_check_num(Real *p) { - if(VpIsNaN(p)) { - VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",1); - } else if(VpIsPosInf(p)) { - VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",1); - } else if(VpIsNegInf(p)) { - VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",1); + if (VpIsNaN(p)) { + VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'(Not a Number)", 1); + } + else if (VpIsPosInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 1); + } + else if (VpIsNegInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 1); } } @@ -646,14 +650,14 @@ BigDecimal_to_i(VALUE self) ssize_t e, nf; Real *p; - GUARD_OBJ(p,GetVpValue(self,1)); + GUARD_OBJ(p, GetVpValue(self, 1)); BigDecimal_check_num(p); e = VpExponent10(p); - if(e<=0) return INT2FIX(0); + if (e <= 0) return INT2FIX(0); nf = VpBaseFig(); - if(e<=nf) { - return LONG2NUM((long)(VpGetSign(p)*(BDIGIT_DBL_SIGNED)p->frac[0])); + if (e <= nf) { + return LONG2NUM((long)(VpGetSign(p) * (BDIGIT_DBL_SIGNED)p->frac[0])); } else { VALUE a = BigDecimal_split(self); @@ -670,12 +674,14 @@ BigDecimal_to_i(VALUE self) rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(-dpower))); } - else + else { ret = rb_funcall(numerator, '*', 1, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(dpower))); - if (RB_TYPE_P(ret, T_FLOAT)) + } + if (RB_TYPE_P(ret, T_FLOAT)) { rb_raise(rb_eFloatDomainError, "Infinity"); + } return ret; } } @@ -702,7 +708,7 @@ BigDecimal_to_f(VALUE self) if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-BASE_FIG)) goto underflow; - str = rb_str_new(0, VpNumOfChars(p,"E")); + str = rb_str_new(0, VpNumOfChars(p, "E")); buf = RSTRING_PTR(str); VpToString(p, buf, 0, 0); errno = 0; @@ -738,7 +744,7 @@ BigDecimal_to_r(VALUE self) ssize_t sign, power, denomi_power; VALUE a, digits, numerator; - p = GetVpValue(self,1); + p = GetVpValue(self, 1); BigDecimal_check_num(p); sign = VpGetSign(p); @@ -757,7 +763,7 @@ BigDecimal_to_r(VALUE self) INT2FIX(-denomi_power))); } else { - return rb_Rational1(rb_funcall(numerator, '*', 1, + return rb_Rational1(rb_funcall(numerator, '*', 1, rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(denomi_power)))); } @@ -847,7 +853,7 @@ BigDecimal_add(VALUE self, VALUE r) b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); } else { - b = GetVpValue(r,0); + b = GetVpValue(r, 0); } if (!b) return DoSomeOne(self,r,'+'); @@ -893,7 +899,7 @@ BigDecimal_sub(VALUE self, VALUE r) Real *c, *a, *b; size_t mx; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self,1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } @@ -904,23 +910,25 @@ BigDecimal_sub(VALUE self, VALUE r) b = GetVpValue(r,0); } - if(!b) return DoSomeOne(self,r,'-'); + if (!b) return DoSomeOne(self,r,'-'); SAVE(b); - if(VpIsNaN(b)) return b->obj; - if(VpIsNaN(a)) return a->obj; + if (VpIsNaN(b)) return b->obj; + if (VpIsNaN(a)) return a->obj; mx = GetAddSubPrec(a,b); if (mx == (size_t)-1L) { - GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0")); - VpAddSub(c, a, b, -1); - } else { - GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0")); - if(!mx) { - VpSetInf(c,VpGetSign(a)); - } else { - VpAddSub(c, a, b, -1); - } + GUARD_OBJ(c,VpCreateRbObject(VpBaseFig() + 1, "0")); + VpAddSub(c, a, b, -1); + } + else { + GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0")); + if (!mx) { + VpSetInf(c,VpGetSign(a)); + } + else { + VpAddSub(c, a, b, -1); + } } return ToValue(c); } @@ -931,7 +939,7 @@ BigDecimalCmp(VALUE self, VALUE r,char op) ENTER(5); SIGNED_VALUE e; Real *a, *b=0; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); switch (TYPE(r)) { case T_DATA: if (!is_kind_of_BigDecimal(r)) break; @@ -939,7 +947,7 @@ BigDecimalCmp(VALUE self, VALUE r,char op) case T_FIXNUM: /* fall through */ case T_BIGNUM: - GUARD_OBJ(b, GetVpValue(r,0)); + GUARD_OBJ(b, GetVpValue(r, 0)); break; case T_FLOAT: @@ -991,23 +999,23 @@ BigDecimalCmp(VALUE self, VALUE r,char op) return INT2FIX(e); /* any op */ case '=': - if(e==0) return Qtrue; + if (e == 0) return Qtrue; return Qfalse; case 'G': - if(e>=0) return Qtrue; + if (e >= 0) return Qtrue; return Qfalse; case '>': - if(e> 0) return Qtrue; + if (e > 0) return Qtrue; return Qfalse; case 'L': - if(e<=0) return Qtrue; + if (e <= 0) return Qtrue; return Qfalse; case '<': - if(e< 0) return Qtrue; + if (e < 0) return Qtrue; return Qfalse; default: @@ -1023,7 +1031,7 @@ BigDecimalCmp(VALUE self, VALUE r,char op) static VALUE BigDecimal_zero(VALUE self) { - Real *a = GetVpValue(self,1); + Real *a = GetVpValue(self, 1); return VpIsZero(a) ? Qtrue : Qfalse; } @@ -1031,7 +1039,7 @@ BigDecimal_zero(VALUE self) static VALUE BigDecimal_nonzero(VALUE self) { - Real *a = GetVpValue(self,1); + Real *a = GetVpValue(self, 1); return VpIsZero(a) ? Qnil : self; } @@ -1126,8 +1134,8 @@ BigDecimal_neg(VALUE self) { ENTER(5); Real *c, *a; - GUARD_OBJ(a,GetVpValue(self,1)); - GUARD_OBJ(c,VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0")); + GUARD_OBJ(a, GetVpValue(self, 1)); + GUARD_OBJ(c, VpCreateRbObject(a->Prec *(VpBaseFig() + 1), "0")); VpAsgn(c, a, -1); return ToValue(c); } @@ -1154,7 +1162,7 @@ BigDecimal_mult(VALUE self, VALUE r) Real *c, *a, *b; size_t mx; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } @@ -1165,11 +1173,11 @@ BigDecimal_mult(VALUE self, VALUE r) b = GetVpValue(r,0); } - if(!b) return DoSomeOne(self,r,'*'); + if (!b) return DoSomeOne(self, r, '*'); SAVE(b); mx = a->Prec + b->Prec; - GUARD_OBJ(c,VpCreateRbObject(mx *(VpBaseFig() + 1), "0")); + GUARD_OBJ(c, VpCreateRbObject(mx *(VpBaseFig() + 1), "0")); VpMult(c, a, b); return ToValue(c); } @@ -1182,26 +1190,26 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r) Real *a, *b; size_t mx; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } else if (RB_TYPE_P(r, T_RATIONAL)) { b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); - } + } else { - b = GetVpValue(r,0); + b = GetVpValue(r, 0); } - if(!b) return DoSomeOne(self,r,'/'); + if (!b) return DoSomeOne(self, r, '/'); SAVE(b); *div = b; mx = a->Prec + vabs(a->exponent); - if(mxPrec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); + if (mxPrec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); mx =(mx + 1) * VpBaseFig(); - GUARD_OBJ((*c),VpCreateRbObject(mx, "#0")); - GUARD_OBJ((*res),VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); + GUARD_OBJ((*c), VpCreateRbObject(mx, "#0")); + GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); VpDivd(*c, *res, a, b); return (VALUE)0; } @@ -1232,15 +1240,15 @@ BigDecimal_div(VALUE self, VALUE r) ENTER(5); Real *c=NULL, *res=NULL, *div = NULL; r = BigDecimal_divide(&c, &res, &div, self, r); - if(r!=(VALUE)0) return r; /* coerced by other */ - SAVE(c);SAVE(res);SAVE(div); + if (r != (VALUE)0) return r; /* coerced by other */ + SAVE(c); SAVE(res); SAVE(div); /* a/b = c + r/b */ /* c xxxxx r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE */ /* Round */ - if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */ - VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal()*(BDIGIT_DBL)res->frac[0]/div->frac[0])); + if (VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */ + VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal() * (BDIGIT_DBL)res->frac[0] / div->frac[0])); } return ToValue(c); } @@ -1257,7 +1265,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) Real *a, *b; size_t mx; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } @@ -1265,65 +1273,65 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); } else { - b = GetVpValue(r,0); + b = GetVpValue(r, 0); } - if(!b) return Qfalse; + if (!b) return Qfalse; SAVE(b); - if(VpIsNaN(a) || VpIsNaN(b)) goto NaN; - if(VpIsInf(a) && VpIsInf(b)) goto NaN; - if(VpIsZero(b)) { + if (VpIsNaN(a) || VpIsNaN(b)) goto NaN; + if (VpIsInf(a) && VpIsInf(b)) goto NaN; + if (VpIsZero(b)) { rb_raise(rb_eZeroDivError, "divided by 0"); } - if(VpIsInf(a)) { - GUARD_OBJ(d,VpCreateRbObject(1, "0")); - VpSetInf(d, (SIGNED_VALUE)(VpGetSign(a) == VpGetSign(b) ? 1 : -1)); - GUARD_OBJ(c,VpCreateRbObject(1, "NaN")); - *div = d; - *mod = c; - return Qtrue; + if (VpIsInf(a)) { + GUARD_OBJ(d, VpCreateRbObject(1, "0")); + VpSetInf(d, (SIGNED_VALUE)(VpGetSign(a) == VpGetSign(b) ? 1 : -1)); + GUARD_OBJ(c, VpCreateRbObject(1, "NaN")); + *div = d; + *mod = c; + return Qtrue; } - if(VpIsInf(b)) { - GUARD_OBJ(d,VpCreateRbObject(1, "0")); - *div = d; - *mod = a; - return Qtrue; + if (VpIsInf(b)) { + GUARD_OBJ(d, VpCreateRbObject(1, "0")); + *div = d; + *mod = a; + return Qtrue; } - if(VpIsZero(a)) { - GUARD_OBJ(c,VpCreateRbObject(1, "0")); - GUARD_OBJ(d,VpCreateRbObject(1, "0")); - *div = d; - *mod = c; - return Qtrue; + if (VpIsZero(a)) { + GUARD_OBJ(c, VpCreateRbObject(1, "0")); + GUARD_OBJ(d, VpCreateRbObject(1, "0")); + *div = d; + *mod = c; + return Qtrue; } mx = a->Prec + vabs(a->exponent); - if(mxPrec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); - mx =(mx + 1) * VpBaseFig(); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); - GUARD_OBJ(res,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); + if (mxPrec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); + mx = (mx + 1) * VpBaseFig(); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); + GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); VpDivd(c, res, a, b); - mx = c->Prec *(VpBaseFig() + 1); - GUARD_OBJ(d,VpCreateRbObject(mx, "0")); - VpActiveRound(d,c,VP_ROUND_DOWN,0); - VpMult(res,d,b); - VpAddSub(c,a,res,-1); - if(!VpIsZero(c) && (VpGetSign(a)*VpGetSign(b)<0)) { - VpAddSub(res,d,VpOne(),-1); - GUARD_OBJ(d,VpCreateRbObject(GetAddSubPrec(c, b)*(VpBaseFig() + 1), "0")); - VpAddSub(d ,c,b, 1); - *div = res; - *mod = d; + mx = c->Prec * (VpBaseFig() + 1); + GUARD_OBJ(d, VpCreateRbObject(mx, "0")); + VpActiveRound(d, c, VP_ROUND_DOWN, 0); + VpMult(res, d, b); + VpAddSub(c, a, res, -1); + if (!VpIsZero(c) && (VpGetSign(a) * VpGetSign(b) < 0)) { + VpAddSub(res, d, VpOne(), -1); + GUARD_OBJ(d, VpCreateRbObject(GetAddSubPrec(c, b)*(VpBaseFig() + 1), "0")); + VpAddSub(d, c, b, 1); + *div = res; + *mod = d; } else { - *div = d; - *mod = c; + *div = d; + *mod = c; } return Qtrue; NaN: - GUARD_OBJ(c,VpCreateRbObject(1, "NaN")); - GUARD_OBJ(d,VpCreateRbObject(1, "NaN")); + GUARD_OBJ(c, VpCreateRbObject(1, "NaN")); + GUARD_OBJ(d, VpCreateRbObject(1, "NaN")); *div = d; *mod = c; return Qtrue; @@ -1341,13 +1349,13 @@ static VALUE BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ { ENTER(3); - Real *div=NULL, *mod=NULL; + Real *div = NULL, *mod = NULL; - if(BigDecimal_DoDivmod(self,r,&div,&mod)) { + if (BigDecimal_DoDivmod(self, r, &div, &mod)) { SAVE(div); SAVE(mod); return ToValue(mod); } - return DoSomeOne(self,r,'%'); + return DoSomeOne(self, r, '%'); } static VALUE @@ -1355,10 +1363,10 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv) { ENTER(10); size_t mx; - Real *a=NULL, *b=NULL, *c=NULL, *res=NULL, *d=NULL, *rr=NULL, *ff=NULL; - Real *f=NULL; + Real *a = NULL, *b = NULL, *c = NULL, *res = NULL, *d = NULL, *rr = NULL, *ff = NULL; + Real *f = NULL; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); if (RB_TYPE_P(r, T_FLOAT)) { b = GetVpValueWithPrec(r, DBL_DIG+1, 1); } @@ -1366,30 +1374,30 @@ BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv) b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); } else { - b = GetVpValue(r,0); + b = GetVpValue(r, 0); } - if(!b) return DoSomeOne(self,r,rb_intern("remainder")); + if (!b) return DoSomeOne(self, r, rb_intern("remainder")); SAVE(b); - mx =(a->MaxPrec + b->MaxPrec) *VpBaseFig(); - GUARD_OBJ(c ,VpCreateRbObject(mx, "0")); - GUARD_OBJ(res,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); - GUARD_OBJ(rr ,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); - GUARD_OBJ(ff ,VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); + mx = (a->MaxPrec + b->MaxPrec) *VpBaseFig(); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); + GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0")); + GUARD_OBJ(rr, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0")); + GUARD_OBJ(ff, VpCreateRbObject((mx+1) * 2 + (VpBaseFig() + 1), "#0")); VpDivd(c, res, a, b); mx = c->Prec *(VpBaseFig() + 1); - GUARD_OBJ(d,VpCreateRbObject(mx, "0")); - GUARD_OBJ(f,VpCreateRbObject(mx, "0")); + GUARD_OBJ(d, VpCreateRbObject(mx, "0")); + GUARD_OBJ(f, VpCreateRbObject(mx, "0")); - VpActiveRound(d,c,VP_ROUND_DOWN,0); /* 0: round off */ + VpActiveRound(d, c, VP_ROUND_DOWN, 0); /* 0: round off */ VpFrac(f, c); - VpMult(rr,f,b); - VpAddSub(ff,res,rr,1); + VpMult(rr, f, b); + VpAddSub(ff, res, rr, 1); *dv = d; *rv = ff; @@ -1404,9 +1412,9 @@ static VALUE BigDecimal_remainder(VALUE self, VALUE r) /* remainder */ { VALUE f; - Real *d,*rv=0; - f = BigDecimal_divremain(self,r,&d,&rv); - if(f!=(VALUE)0) return f; + Real *d, *rv = 0; + f = BigDecimal_divremain(self, r, &d, &rv); + if (f != (VALUE)0) return f; return ToValue(rv); } @@ -1433,9 +1441,9 @@ static VALUE BigDecimal_divmod(VALUE self, VALUE r) { ENTER(5); - Real *div=NULL, *mod=NULL; + Real *div = NULL, *mod = NULL; - if(BigDecimal_DoDivmod(self,r,&div,&mod)) { + if (BigDecimal_DoDivmod(self, r, &div, &mod)) { SAVE(div); SAVE(mod); return rb_assoc_new(ToValue(div), ToValue(mod)); } @@ -1450,34 +1458,34 @@ BigDecimal_div2(int argc, VALUE *argv, VALUE self) { ENTER(5); VALUE b,n; - int na = rb_scan_args(argc,argv,"11",&b,&n); - if(na==1) { /* div in Float sense */ - Real *div=NULL; - Real *mod; - if(BigDecimal_DoDivmod(self,b,&div,&mod)) { - return BigDecimal_to_i(ToValue(div)); - } - return DoSomeOne(self,b,rb_intern("div")); + int na = rb_scan_args(argc, argv, "11", &b, &n); + if (na == 1) { /* div in Float sense */ + Real *div = NULL; + Real *mod; + if (BigDecimal_DoDivmod(self, b, &div, &mod)) { + return BigDecimal_to_i(ToValue(div)); + } + return DoSomeOne(self, b, rb_intern("div")); } else { /* div in BigDecimal sense */ - SIGNED_VALUE ix = GetPositiveInt(n); - if (ix == 0) return BigDecimal_div(self, b); - else { - Real *res=NULL; - Real *av=NULL, *bv=NULL, *cv=NULL; - size_t mx = (ix+VpBaseFig()*2); - size_t pl = VpSetPrecLimit(0); - - GUARD_OBJ(cv,VpCreateRbObject(mx,"0")); - GUARD_OBJ(av,GetVpValue(self,1)); - GUARD_OBJ(bv,GetVpValue(b,1)); - mx = av->Prec + bv->Prec + 2; - if(mx <= cv->MaxPrec) mx = cv->MaxPrec+1; - GUARD_OBJ(res,VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0")); - VpDivd(cv,res,av,bv); - VpSetPrecLimit(pl); - VpLeftRound(cv,VpGetRoundMode(),ix); - return ToValue(cv); - } + SIGNED_VALUE ix = GetPositiveInt(n); + if (ix == 0) return BigDecimal_div(self, b); + else { + Real *res = NULL; + Real *av = NULL, *bv = NULL, *cv = NULL; + size_t mx = ix + VpBaseFig()*2; + size_t pl = VpSetPrecLimit(0); + + GUARD_OBJ(cv, VpCreateRbObject(mx, "0")); + GUARD_OBJ(av, GetVpValue(self, 1)); + GUARD_OBJ(bv, GetVpValue(b, 1)); + mx = av->Prec + bv->Prec + 2; + if (mx <= cv->MaxPrec) mx = cv->MaxPrec + 1; + GUARD_OBJ(res, VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0")); + VpDivd(cv, res, av, bv); + VpSetPrecLimit(pl); + VpLeftRound(cv, VpGetRoundMode(), ix); + return ToValue(cv); + } } } @@ -1485,16 +1493,16 @@ static VALUE BigDecimal_add2(VALUE self, VALUE b, VALUE n) { ENTER(2); - Real *cv; + Real *cv; SIGNED_VALUE mx = GetPositiveInt(n); if (mx == 0) return BigDecimal_add(self, b); else { - size_t pl = VpSetPrecLimit(0); - VALUE c = BigDecimal_add(self,b); - VpSetPrecLimit(pl); - GUARD_OBJ(cv,GetVpValue(c,1)); - VpLeftRound(cv,VpGetRoundMode(),mx); - return ToValue(cv); + size_t pl = VpSetPrecLimit(0); + VALUE c = BigDecimal_add(self, b); + VpSetPrecLimit(pl); + GUARD_OBJ(cv, GetVpValue(c, 1)); + VpLeftRound(cv, VpGetRoundMode(), mx); + return ToValue(cv); } } @@ -1506,12 +1514,12 @@ BigDecimal_sub2(VALUE self, VALUE b, VALUE n) SIGNED_VALUE mx = GetPositiveInt(n); if (mx == 0) return BigDecimal_sub(self, b); else { - size_t pl = VpSetPrecLimit(0); - VALUE c = BigDecimal_sub(self,b); - VpSetPrecLimit(pl); - GUARD_OBJ(cv,GetVpValue(c,1)); - VpLeftRound(cv,VpGetRoundMode(),mx); - return ToValue(cv); + size_t pl = VpSetPrecLimit(0); + VALUE c = BigDecimal_sub(self, b); + VpSetPrecLimit(pl); + GUARD_OBJ(cv, GetVpValue(c, 1)); + VpLeftRound(cv, VpGetRoundMode(), mx); + return ToValue(cv); } } @@ -1523,12 +1531,12 @@ BigDecimal_mult2(VALUE self, VALUE b, VALUE n) SIGNED_VALUE mx = GetPositiveInt(n); if (mx == 0) return BigDecimal_mult(self, b); else { - size_t pl = VpSetPrecLimit(0); - VALUE c = BigDecimal_mult(self,b); - VpSetPrecLimit(pl); - GUARD_OBJ(cv,GetVpValue(c,1)); - VpLeftRound(cv,VpGetRoundMode(),mx); - return ToValue(cv); + size_t pl = VpSetPrecLimit(0); + VALUE c = BigDecimal_mult(self, b); + VpSetPrecLimit(pl); + GUARD_OBJ(cv, GetVpValue(c, 1)); + VpLeftRound(cv, VpGetRoundMode(), mx); + return ToValue(cv); } } @@ -1545,9 +1553,9 @@ BigDecimal_abs(VALUE self) Real *c, *a; size_t mx; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); VpAsgn(c, a, 1); VpChangeSign(c, 1); return ToValue(c); @@ -1567,12 +1575,12 @@ BigDecimal_sqrt(VALUE self, VALUE nFig) Real *c, *a; size_t mx, n; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); mx = a->Prec *(VpBaseFig() + 1); n = GetPositiveInt(nFig) + VpDblFig() + 1; if(mx <= n) mx = n; - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); VpSqrt(c, a); return ToValue(c); } @@ -1586,10 +1594,10 @@ BigDecimal_fix(VALUE self) Real *c, *a; size_t mx; - GUARD_OBJ(a,GetVpValue(self,1)); + GUARD_OBJ(a, GetVpValue(self, 1)); mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); - VpActiveRound(c,a,VP_ROUND_DOWN,0); /* 0: round off */ + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); + VpActiveRound(c, a, VP_ROUND_DOWN, 0); /* 0: round off */ return ToValue(c); } @@ -1626,26 +1634,28 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self) unsigned short sw = VpGetRoundMode(); switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) { - case 0: - iLoc = 0; - break; - case 1: - Check_Type(vLoc, T_FIXNUM); - iLoc = FIX2INT(vLoc); - break; - case 2: + case 0: + iLoc = 0; + break; + case 1: + Check_Type(vLoc, T_FIXNUM); + iLoc = FIX2INT(vLoc); + break; + case 2: Check_Type(vLoc, T_FIXNUM); iLoc = FIX2INT(vLoc); sw = check_rounding_mode(vRound); break; + default: + break; } pl = VpSetPrecLimit(0); - GUARD_OBJ(a,GetVpValue(self,1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); VpSetPrecLimit(pl); - VpActiveRound(c,a,sw,iLoc); + VpActiveRound(c, a, sw, iLoc); if (argc == 0) { return BigDecimal_to_i(ToValue(c)); } @@ -1678,18 +1688,19 @@ BigDecimal_truncate(int argc, VALUE *argv, VALUE self) VALUE vLoc; size_t mx, pl = VpSetPrecLimit(0); - if(rb_scan_args(argc,argv,"01",&vLoc)==0) { - iLoc = 0; - } else { - Check_Type(vLoc, T_FIXNUM); - iLoc = FIX2INT(vLoc); + if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { + iLoc = 0; + } + else { + Check_Type(vLoc, T_FIXNUM); + iLoc = FIX2INT(vLoc); } - GUARD_OBJ(a,GetVpValue(self,1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + 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 */ if (argc == 0) { return BigDecimal_to_i(ToValue(c)); } @@ -1705,9 +1716,9 @@ BigDecimal_frac(VALUE self) Real *c, *a; size_t mx; - GUARD_OBJ(a,GetVpValue(self,1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); VpFrac(c, a); return ToValue(c); } @@ -1738,18 +1749,19 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self) VALUE vLoc; size_t mx, pl = VpSetPrecLimit(0); - if(rb_scan_args(argc,argv,"01",&vLoc)==0) { - iLoc = 0; - } else { - Check_Type(vLoc, T_FIXNUM); - iLoc = FIX2INT(vLoc); + if (rb_scan_args(argc, argv, "01", &vLoc)==0) { + iLoc = 0; + } + else { + Check_Type(vLoc, T_FIXNUM); + iLoc = FIX2INT(vLoc); } - GUARD_OBJ(a,GetVpValue(self,1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); VpSetPrecLimit(pl); - VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc); + VpActiveRound(c, a, VP_ROUND_FLOOR, iLoc); #ifdef BIGDECIMAL_DEBUG VPrint(stderr, "floor: c=%\n", c); #endif @@ -1785,18 +1797,18 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self) VALUE vLoc; size_t mx, pl = VpSetPrecLimit(0); - if(rb_scan_args(argc,argv,"01",&vLoc)==0) { - iLoc = 0; + if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { + iLoc = 0; } else { - Check_Type(vLoc, T_FIXNUM); - iLoc = FIX2INT(vLoc); + Check_Type(vLoc, T_FIXNUM); + iLoc = FIX2INT(vLoc); } - GUARD_OBJ(a,GetVpValue(self,1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, VpCreateRbObject(mx, "0")); VpSetPrecLimit(pl); - VpActiveRound(c,a,VP_ROUND_CEIL,iLoc); + VpActiveRound(c, a, VP_ROUND_CEIL, iLoc); if (argc == 0) { return BigDecimal_to_i(ToValue(c)); } @@ -1849,9 +1861,9 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self) size_t nc, mc = 0; VALUE f; - GUARD_OBJ(vp,GetVpValue(self,1)); + GUARD_OBJ(vp, GetVpValue(self, 1)); - if (rb_scan_args(argc,argv,"01",&f)==1) { + if (rb_scan_args(argc, argv, "01", &f) == 1) { if (RB_TYPE_P(f, T_STRING)) { SafeStringValue(f); psz = RSTRING_PTR(f); @@ -1873,7 +1885,7 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self) } break; } - mc = mc * 10 + ch - '0'; + mc = mc*10 + ch - '0'; } } else { @@ -1936,21 +1948,21 @@ BigDecimal_split(VALUE self) ssize_t e, s; char *psz1; - GUARD_OBJ(vp,GetVpValue(self,1)); - str = rb_str_new(0, VpNumOfChars(vp,"E")); + GUARD_OBJ(vp, GetVpValue(self, 1)); + str = rb_str_new(0, VpNumOfChars(vp, "E")); psz1 = RSTRING_PTR(str); - VpSzMantissa(vp,psz1); + VpSzMantissa(vp, psz1); s = 1; - if(psz1[0]=='-') { - size_t len = strlen(psz1+1); + if(psz1[0] == '-') { + size_t len = strlen(psz1 + 1); - memmove(psz1, psz1+1, len); + memmove(psz1, psz1 + 1, len); psz1[len] = '\0'; s = -1; } - if(psz1[0]=='N') s=0; /* NaN */ + if (psz1[0] == 'N') s = 0; /* NaN */ e = VpExponent10(vp); - obj = rb_ary_new2(4); + obj = rb_ary_new2(4); rb_ary_push(obj, INT2FIX(s)); rb_ary_push(obj, str); rb_str_resize(str, strlen(psz1)); @@ -1990,13 +2002,13 @@ BigDecimal_inspect(VALUE self) size_t nc; char *psz, *tmp; - GUARD_OBJ(vp,GetVpValue(self,1)); - nc = VpNumOfChars(vp,"E"); - nc +=(nc + 9) / 10; + GUARD_OBJ(vp, GetVpValue(self, 1)); + nc = VpNumOfChars(vp, "E"); + nc += (nc + 9) / 10; obj = rb_str_new(0, nc+256); psz = RSTRING_PTR(obj); - sprintf(psz,"#Prec * (VpBaseFig() + 1); - GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0")); + mp = x->Prec * (VpBaseFig() + 1); + GUARD_OBJ(y, VpCreateRbObject(mp * (ma + 1), "0")); } else { - GUARD_OBJ(y, VpCreateRbObject(1, "0")); + GUARD_OBJ(y, VpCreateRbObject(1, "0")); } VpPower(y, x, int_exp); return ToValue(y); @@ -2492,15 +2504,15 @@ BigDecimal_limit(int argc, VALUE *argv, VALUE self) VALUE nFig; VALUE nCur = INT2NUM(VpGetPrecLimit()); - if(rb_scan_args(argc,argv,"01",&nFig)==1) { - int nf; - if(nFig==Qnil) return nCur; - Check_Type(nFig, T_FIXNUM); - nf = FIX2INT(nFig); - if(nf<0) { - rb_raise(rb_eArgError, "argument must be positive"); - } - VpSetPrecLimit(nf); + if (rb_scan_args(argc, argv, "01", &nFig) == 1) { + int nf; + if (NIL_P(nFig)) return nCur; + Check_Type(nFig, T_FIXNUM); + nf = FIX2INT(nFig); + if (nf < 0) { + rb_raise(rb_eArgError, "argument must be positive"); + } + VpSetPrecLimit(nf); } return nCur; } @@ -2524,7 +2536,7 @@ BigDecimal_limit(int argc, VALUE *argv, VALUE self) static VALUE BigDecimal_sign(VALUE self) { /* sign */ - int s = GetVpValue(self,1)->sign; + int s = GetVpValue(self, 1)->sign; return INT2FIX(s); } @@ -2698,10 +2710,10 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec) } RB_GC_GUARD(one) = ToValue(VpCreateRbObject(1, "1")); - RB_GC_GUARD(x1) = one; - RB_GC_GUARD(y) = one; - RB_GC_GUARD(d) = y; - RB_GC_GUARD(z) = one; + RB_GC_GUARD(x1) = one; + RB_GC_GUARD(y) = one; + RB_GC_GUARD(d) = y; + RB_GC_GUARD(z) = one; i = 0; while (!VpIsZero((Real*)DATA_PTR(d))) { @@ -3020,7 +3032,7 @@ Init_bigdecimal(void) VpInit(0UL); /* Class and method registration */ - rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric); + rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric); rb_define_alloc_func(rb_cBigDecimal, BigDecimal_s_allocate); /* Global function */ @@ -3054,92 +3066,92 @@ Init_bigdecimal(void) * 0xff: Determines whether overflow, underflow or zero divide result in * an exception being thrown. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_ALL",INT2FIX(VP_EXCEPTION_ALL)); + rb_define_const(rb_cBigDecimal, "EXCEPTION_ALL", INT2FIX(VP_EXCEPTION_ALL)); /* * 0x02: Determines what happens when the result of a computation is not a * number (NaN). See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_NaN",INT2FIX(VP_EXCEPTION_NaN)); + rb_define_const(rb_cBigDecimal, "EXCEPTION_NaN", INT2FIX(VP_EXCEPTION_NaN)); /* * 0x01: Determines what happens when the result of a computation is * infinity. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_INFINITY",INT2FIX(VP_EXCEPTION_INFINITY)); + rb_define_const(rb_cBigDecimal, "EXCEPTION_INFINITY", INT2FIX(VP_EXCEPTION_INFINITY)); /* * 0x04: Determines what happens when the result of a computation is an * underflow (a result too small to be represented). See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_UNDERFLOW",INT2FIX(VP_EXCEPTION_UNDERFLOW)); + rb_define_const(rb_cBigDecimal, "EXCEPTION_UNDERFLOW", INT2FIX(VP_EXCEPTION_UNDERFLOW)); /* * 0x01: Determines what happens when the result of a computation is an * overflow (a result too large to be represented). See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW",INT2FIX(VP_EXCEPTION_OVERFLOW)); + rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW", INT2FIX(VP_EXCEPTION_OVERFLOW)); /* * 0x01: Determines what happens when a division by zero is performed. * See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE",INT2FIX(VP_EXCEPTION_ZERODIVIDE)); + rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE", INT2FIX(VP_EXCEPTION_ZERODIVIDE)); /* * 0x100: Determines what happens when a result must be rounded in order to * fit in the appropriate number of significant digits. See * BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_MODE",INT2FIX(VP_ROUND_MODE)); + rb_define_const(rb_cBigDecimal, "ROUND_MODE", INT2FIX(VP_ROUND_MODE)); /* 1: Indicates that values should be rounded away from zero. See * BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_UP",INT2FIX(VP_ROUND_UP)); + rb_define_const(rb_cBigDecimal, "ROUND_UP", INT2FIX(VP_ROUND_UP)); /* 2: Indicates that values should be rounded towards zero. See * BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_DOWN",INT2FIX(VP_ROUND_DOWN)); + rb_define_const(rb_cBigDecimal, "ROUND_DOWN", INT2FIX(VP_ROUND_DOWN)); /* 3: Indicates that digits >= 5 should be rounded up, others rounded down. * See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_HALF_UP",INT2FIX(VP_ROUND_HALF_UP)); + rb_define_const(rb_cBigDecimal, "ROUND_HALF_UP", INT2FIX(VP_ROUND_HALF_UP)); /* 4: Indicates that digits >= 6 should be rounded up, others rounded down. * See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_HALF_DOWN",INT2FIX(VP_ROUND_HALF_DOWN)); + rb_define_const(rb_cBigDecimal, "ROUND_HALF_DOWN", INT2FIX(VP_ROUND_HALF_DOWN)); /* 5: Round towards +infinity. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_CEILING",INT2FIX(VP_ROUND_CEIL)); + rb_define_const(rb_cBigDecimal, "ROUND_CEILING", INT2FIX(VP_ROUND_CEIL)); /* 6: Round towards -infinity. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_FLOOR",INT2FIX(VP_ROUND_FLOOR)); + rb_define_const(rb_cBigDecimal, "ROUND_FLOOR", INT2FIX(VP_ROUND_FLOOR)); /* 7: Round towards the even neighbor. See BigDecimal.mode. */ - rb_define_const(rb_cBigDecimal, "ROUND_HALF_EVEN",INT2FIX(VP_ROUND_HALF_EVEN)); + rb_define_const(rb_cBigDecimal, "ROUND_HALF_EVEN", INT2FIX(VP_ROUND_HALF_EVEN)); /* 0: Indicates that a value is not a number. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NaN",INT2FIX(VP_SIGN_NaN)); + rb_define_const(rb_cBigDecimal, "SIGN_NaN", INT2FIX(VP_SIGN_NaN)); /* 1: Indicates that a value is +0. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_ZERO",INT2FIX(VP_SIGN_POSITIVE_ZERO)); + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_ZERO", INT2FIX(VP_SIGN_POSITIVE_ZERO)); /* -1: Indicates that a value is -0. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_ZERO",INT2FIX(VP_SIGN_NEGATIVE_ZERO)); + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_ZERO", INT2FIX(VP_SIGN_NEGATIVE_ZERO)); /* 2: Indicates that a value is positive and finite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_FINITE",INT2FIX(VP_SIGN_POSITIVE_FINITE)); + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_FINITE", INT2FIX(VP_SIGN_POSITIVE_FINITE)); /* -2: Indicates that a value is negative and finite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_FINITE",INT2FIX(VP_SIGN_NEGATIVE_FINITE)); + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_FINITE", INT2FIX(VP_SIGN_NEGATIVE_FINITE)); /* 3: Indicates that a value is positive and infinite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_INFINITE",INT2FIX(VP_SIGN_POSITIVE_INFINITE)); + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_INFINITE", INT2FIX(VP_SIGN_POSITIVE_INFINITE)); /* -3: Indicates that a value is negative and infinite. See BigDecimal.sign. */ - rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE",INT2FIX(VP_SIGN_NEGATIVE_INFINITE)); + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE)); arg = rb_str_new2("+Infinity"); /* Positive infinity value. */ @@ -3261,7 +3273,7 @@ static void VpFormatSt(char *psz, size_t fFmt); static int VpRdup(Real *m, size_t ind_m); #ifdef BIGDECIMAL_DEBUG -static int gnAlloc=0; /* Memory allocation counter */ +static int gnAlloc = 0; /* Memory allocation counter */ #endif /* BIGDECIMAL_DEBUG */ VP_EXPORT void * @@ -3269,7 +3281,7 @@ VpMemAlloc(size_t mb) { void *p = xmalloc(mb); if (!p) { - VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1); + VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1); } memset(p, 0, mb); #ifdef BIGDECIMAL_DEBUG @@ -3278,12 +3290,12 @@ VpMemAlloc(size_t mb) return p; } -VP_EXPORT void * + VP_EXPORT void * VpMemRealloc(void *ptr, size_t mb) { void *p = xrealloc(ptr, mb); if (!p) { - VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1); + VpException(VP_EXCEPTION_MEMORY, "failed to allocate memory", 1); } return p; } @@ -3291,18 +3303,18 @@ VpMemRealloc(void *ptr, size_t mb) VP_EXPORT void VpFree(Real *pv) { - if(pv != NULL) { - xfree(pv); + if (pv != NULL) { + xfree(pv); #ifdef BIGDECIMAL_DEBUG - gnAlloc--; /* Decrement allocation count */ - if(gnAlloc==0) { - printf(" *************** All memories allocated freed ****************"); - getchar(); - } - if(gnAlloc<0) { - printf(" ??????????? Too many memory free calls(%d) ?????????????\n",gnAlloc); - getchar(); - } + gnAlloc--; /* Decrement allocation count */ + if (gnAlloc == 0) { + printf(" *************** All memories allocated freed ****************"); + getchar(); + } + if (gnAlloc < 0) { + printf(" ??????????? Too many memory free calls(%d) ?????????????\n", gnAlloc); + getchar(); + } #endif /* BIGDECIMAL_DEBUG */ } } @@ -3473,7 +3485,7 @@ VP_EXPORT double VpGetDoubleNaN(void) /* Returns the value of NaN */ { static double fNaN = 0.0; - if(fNaN==0.0) fNaN = Zero()/Zero(); + if (fNaN == 0.0) fNaN = Zero()/Zero(); return fNaN; } @@ -3481,7 +3493,7 @@ VP_EXPORT double VpGetDoublePosInf(void) /* Returns the value of +Infinity */ { static double fInf = 0.0; - if(fInf==0.0) fInf = One()/Zero(); + if (fInf == 0.0) fInf = One()/Zero(); return fInf; } @@ -3489,7 +3501,7 @@ VP_EXPORT double VpGetDoubleNegInf(void) /* Returns the value of -Infinity */ { static double fInf = 0.0; - if(fInf==0.0) fInf = -(One()/Zero()); + if (fInf == 0.0) fInf = -(One()/Zero()); return fInf; } @@ -3497,7 +3509,7 @@ VP_EXPORT double VpGetDoubleNegZero(void) /* Returns the value of -0 */ { static double nzero = 1000.0; - if(nzero!=0.0) nzero = (One()/VpGetDoubleNegInf()); + if (nzero != 0.0) nzero = (One()/VpGetDoubleNegInf()); return nzero; } @@ -3517,34 +3529,31 @@ VpException(unsigned short f, const char *str,int always) int fatal=0; unsigned short const exception_mode = VpGetException(); - if(f==VP_EXCEPTION_OP || f==VP_EXCEPTION_MEMORY) always = 1; + if (f == VP_EXCEPTION_OP || f == VP_EXCEPTION_MEMORY) always = 1; if (always || (exception_mode & f)) { - switch(f) - { - /* - case VP_EXCEPTION_OVERFLOW: - */ - case VP_EXCEPTION_ZERODIVIDE: - case VP_EXCEPTION_INFINITY: - case VP_EXCEPTION_NaN: - case VP_EXCEPTION_UNDERFLOW: - case VP_EXCEPTION_OP: - exc = rb_eFloatDomainError; - goto raise; - case VP_EXCEPTION_MEMORY: - fatal = 1; - goto raise; - default: - fatal = 1; - goto raise; - } + switch(f) { + /* case VP_EXCEPTION_OVERFLOW: */ + case VP_EXCEPTION_ZERODIVIDE: + case VP_EXCEPTION_INFINITY: + case VP_EXCEPTION_NaN: + case VP_EXCEPTION_UNDERFLOW: + case VP_EXCEPTION_OP: + exc = rb_eFloatDomainError; + goto raise; + case VP_EXCEPTION_MEMORY: + fatal = 1; + goto raise; + default: + fatal = 1; + goto raise; + } } return 0; /* 0 Means VpException() raised no exception */ raise: - if(fatal) rb_fatal("%s", str); - else rb_raise(exc, "%s", str); + if (fatal) rb_fatal("%s", str); + else rb_raise(exc, "%s", str); return 0; } @@ -3553,91 +3562,90 @@ raise: static int VpIsDefOP(Real *c,Real *a,Real *b,int sw) { - if(VpIsNaN(a) || VpIsNaN(b)) { - /* at least a or b is NaN */ - VpSetNaN(c); - goto NaN; - } - - if(VpIsInf(a)) { - if(VpIsInf(b)) { - switch(sw) - { - case 1: /* + */ - if(VpGetSign(a)==VpGetSign(b)) { - VpSetInf(c,VpGetSign(a)); - goto Inf; - } else { - VpSetNaN(c); - goto NaN; - } - case 2: /* - */ - if(VpGetSign(a)!=VpGetSign(b)) { - VpSetInf(c,VpGetSign(a)); - goto Inf; - } else { - VpSetNaN(c); - goto NaN; - } - break; - case 3: /* * */ - VpSetInf(c,VpGetSign(a)*VpGetSign(b)); - goto Inf; - break; - case 4: /* / */ - VpSetNaN(c); - goto NaN; - } - VpSetNaN(c); - goto NaN; - } - /* Inf op Finite */ - switch(sw) - { - case 1: /* + */ - case 2: /* - */ - VpSetInf(c,VpGetSign(a)); - break; - case 3: /* * */ - if(VpIsZero(b)) { - VpSetNaN(c); - goto NaN; - } - VpSetInf(c,VpGetSign(a)*VpGetSign(b)); - break; - case 4: /* / */ - VpSetInf(c,VpGetSign(a)*VpGetSign(b)); - } - goto Inf; - } - - if(VpIsInf(b)) { - switch(sw) - { - case 1: /* + */ - VpSetInf(c,VpGetSign(b)); - break; - case 2: /* - */ - VpSetInf(c,-VpGetSign(b)); - break; - case 3: /* * */ - if(VpIsZero(a)) { - VpSetNaN(c); - goto NaN; - } - VpSetInf(c,VpGetSign(a)*VpGetSign(b)); - break; - case 4: /* / */ - VpSetZero(c,VpGetSign(a)*VpGetSign(b)); - } - goto Inf; + if (VpIsNaN(a) || VpIsNaN(b)) { + /* at least a or b is NaN */ + VpSetNaN(c); + goto NaN; + } + + if (VpIsInf(a)) { + if (VpIsInf(b)) { + switch(sw) { + case 1: /* + */ + if (VpGetSign(a) == VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + case 2: /* - */ + if (VpGetSign(a) != VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + break; + case 3: /* * */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + goto Inf; + break; + case 4: /* / */ + VpSetNaN(c); + goto NaN; + } + VpSetNaN(c); + goto NaN; + } + /* Inf op Finite */ + switch(sw) { + case 1: /* + */ + case 2: /* - */ + VpSetInf(c, VpGetSign(a)); + break; + case 3: /* * */ + if (VpIsZero(b)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case 4: /* / */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; + } + + if (VpIsInf(b)) { + switch(sw) { + case 1: /* + */ + VpSetInf(c, VpGetSign(b)); + break; + case 2: /* - */ + VpSetInf(c, -VpGetSign(b)); + break; + case 3: /* * */ + if (VpIsZero(a)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case 4: /* / */ + VpSetZero(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; } return 1; /* Results OK */ Inf: - return VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",0); + return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0); NaN: - return VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'",0); + return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); } /* @@ -3653,26 +3661,26 @@ VpNumOfChars(Real *vp,const char *pszFmt) SIGNED_VALUE ex; size_t nc; - if(vp == NULL) return BASE_FIG*2+6; - if(!VpIsDef(vp)) return 32; /* not sure,may be OK */ - - switch(*pszFmt) - { - case 'F': - nc = BASE_FIG*(vp->Prec + 1)+2; - ex = vp->exponent; - if(ex < 0) { - nc += BASE_FIG*(size_t)(-ex); - } - else { - if((size_t)ex > vp->Prec) { - nc += BASE_FIG*((size_t)ex - vp->Prec); - } - } - break; - case 'E': - default: - nc = BASE_FIG*(vp->Prec + 2)+6; /* 3: sign + exponent chars */ + if (vp == NULL) return BASE_FIG*2+6; + if (!VpIsDef(vp)) return 32; /* not sure,may be OK */ + + switch(*pszFmt) { + case 'F': + nc = BASE_FIG*(vp->Prec + 1)+2; + ex = vp->exponent; + if (ex < 0) { + nc += BASE_FIG*(size_t)(-ex); + } + else { + if ((size_t)ex > vp->Prec) { + nc += BASE_FIG*((size_t)ex - vp->Prec); + } + } + break; + case 'E': + /* fall through */ + default: + nc = BASE_FIG*(vp->Prec + 2)+6; /* 3: sign + exponent chars */ } return nc; } @@ -3709,13 +3717,13 @@ VpInit(BDIGIT BaseVal) #endif /* BIGDECIMAL_DEBUG */ #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - printf("VpInit: BaseVal = %lu\n", BaseVal); - printf(" BASE = %lu\n", BASE); - printf(" HALF_BASE = %lu\n", HALF_BASE); - printf(" BASE1 = %lu\n", BASE1); - printf(" BASE_FIG = %u\n", BASE_FIG); - printf(" DBLE_FIG = %d\n", DBLE_FIG); + if (gfDebug) { + printf("VpInit: BaseVal = %lu\n", BaseVal); + printf(" BASE = %lu\n", BASE); + printf(" HALF_BASE = %lu\n", HALF_BASE); + printf(" BASE1 = %lu\n", BASE1); + printf(" BASE_FIG = %u\n", BASE_FIG); + printf(" DBLE_FIG = %d\n", DBLE_FIG); } #endif /* BIGDECIMAL_DEBUG */ @@ -3735,28 +3743,29 @@ AddExponent(Real *a, SIGNED_VALUE n) SIGNED_VALUE e = a->exponent; SIGNED_VALUE m = e+n; SIGNED_VALUE eb, mb; - if(e>0) { - if(n>0) { - mb = m*(SIGNED_VALUE)BASE_FIG; - eb = e*(SIGNED_VALUE)BASE_FIG; - if(mbeb) goto underflow; + if (e > 0) { + if (n > 0) { + mb = m*(SIGNED_VALUE)BASE_FIG; + eb = e*(SIGNED_VALUE)BASE_FIG; + if (mb < eb) goto overflow; + } + } + else if (n < 0) { + mb = m*(SIGNED_VALUE)BASE_FIG; + eb = e*(SIGNED_VALUE)BASE_FIG; + if (mb > eb) goto underflow; } a->exponent = m; return 1; /* Overflow/Underflow ==> Raise exception or returns 0 */ underflow: - VpSetZero(a,VpGetSign(a)); - return VpException(VP_EXCEPTION_UNDERFLOW,"Exponent underflow",0); + VpSetZero(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_UNDERFLOW, "Exponent underflow", 0); overflow: - VpSetInf(a,VpGetSign(a)); - return VpException(VP_EXCEPTION_OVERFLOW,"Exponent overflow",0); + VpSetInf(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0); } /* @@ -3776,7 +3785,7 @@ VP_EXPORT Real * VpAlloc(size_t mx, const char *szVal) { size_t i, ni, ipn, ipf, nf, ipe, ne, nalloc; - char v,*psz; + char v, *psz; int sign=1; Real *vp = NULL; size_t mf = VpGetPrecLimit(); @@ -3784,72 +3793,74 @@ VpAlloc(size_t mx, const char *szVal) mx = (mx + BASE_FIG - 1) / BASE_FIG + 1; /* Determine allocation unit. */ if (szVal) { - while (ISSPACE(*szVal)) szVal++; - if (*szVal != '#') { - if (mf) { - mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */ - if (mx > mf) { - mx = mf; - } - } - } + while (ISSPACE(*szVal)) szVal++; + if (*szVal != '#') { + if (mf) { + mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */ + if (mx > mf) { + mx = mf; + } + } + } else { - ++szVal; - } + ++szVal; + } } else { - /* necessary to be able to store */ - /* at least mx digits. */ - /* szVal==NULL ==> allocate zero value. */ - vp = VpAllocReal(mx); - /* xmalloc() alway returns(or throw interruption) */ - vp->MaxPrec = mx; /* set max precision */ - VpSetZero(vp,1); /* initialize vp to zero. */ - return vp; + /* necessary to be able to store */ + /* at least mx digits. */ + /* szVal==NULL ==> allocate zero value. */ + vp = VpAllocReal(mx); + /* xmalloc() alway returns(or throw interruption) */ + vp->MaxPrec = mx; /* set max precision */ + VpSetZero(vp, 1); /* initialize vp to zero. */ + return vp; } /* Skip all '_' after digit: 2006-6-30 */ ni = 0; - buf = rb_str_tmp_new(strlen(szVal)+1); + buf = rb_str_tmp_new(strlen(szVal) + 1); psz = RSTRING_PTR(buf); i = 0; ipn = 0; - while ((psz[i]=szVal[ipn]) != 0) { - if (ISDIGIT(psz[i])) ++ni; - if (psz[i] == '_') { - if (ni > 0) { ipn++; continue; } - psz[i] = 0; - break; - } - ++i; + while ((psz[i] = szVal[ipn]) != 0) { + if (ISDIGIT(psz[i])) ++ni; + if (psz[i] == '_') { + if (ni > 0) { + ipn++; + continue; + } + psz[i] = 0; + break; + } + ++i; ++ipn; } /* Skip trailing spaces */ while (--i > 0) { - if (ISSPACE(psz[i])) psz[i] = 0; - else break; + if (ISSPACE(psz[i])) psz[i] = 0; + else break; } szVal = psz; /* Check on Inf & NaN */ - if (StrCmp(szVal, SZ_PINF) == 0 || - StrCmp(szVal, SZ_INF) == 0 ) { - vp = VpAllocReal(1); - vp->MaxPrec = 1; /* set max precision */ - VpSetPosInf(vp); - return vp; + if (StrCmp(szVal, SZ_PINF) == 0 || StrCmp(szVal, SZ_INF) == 0 ) { + vp = VpAllocReal(1); + vp->MaxPrec = 1; /* set max precision */ + VpSetPosInf(vp); + return vp; } if (StrCmp(szVal, SZ_NINF) == 0) { - vp = VpAllocReal(1); - vp->MaxPrec = 1; /* set max precision */ - VpSetNegInf(vp); - return vp; + vp = VpAllocReal(1); + vp->MaxPrec = 1; /* set max precision */ + VpSetNegInf(vp); + return vp; } if (StrCmp(szVal, SZ_NaN) == 0) { - vp = VpAllocReal(1); - vp->MaxPrec = 1; /* set max precision */ - VpSetNaN(vp); - return vp; + vp = VpAllocReal(1); + vp->MaxPrec = 1; /* set max precision */ + VpSetNaN(vp); + return vp; } /* check on number szVal[] */ @@ -3859,45 +3870,45 @@ VpAlloc(size_t mx, const char *szVal) /* Skip digits */ ni = 0; /* digits in mantissa */ while ((v = szVal[i]) != 0) { - if (!ISDIGIT(v)) break; - ++i; - ++ni; + if (!ISDIGIT(v)) break; + ++i; + ++ni; } nf = 0; ipf = 0; ipe = 0; ne = 0; if (v) { - /* other than digit nor \0 */ - if (szVal[i] == '.') { /* xxx. */ - ++i; - ipf = i; - while ((v = szVal[i]) != 0) { /* get fraction part. */ - if (!ISDIGIT(v)) break; - ++i; - ++nf; - } - } - ipe = 0; /* Exponent */ + /* other than digit nor \0 */ + if (szVal[i] == '.') { /* xxx. */ + ++i; + ipf = i; + while ((v = szVal[i]) != 0) { /* get fraction part. */ + if (!ISDIGIT(v)) break; + ++i; + ++nf; + } + } + ipe = 0; /* Exponent */ - switch (szVal[i]) { - case '\0': + switch (szVal[i]) { + case '\0': break; - case 'e': case 'E': - case 'd': case 'D': - ++i; - ipe = i; - v = szVal[i]; - if ((v == '-') || (v == '+')) ++i; - while ((v=szVal[i]) != 0) { - if (!ISDIGIT(v)) break; - ++i; - ++ne; - } - break; - default: - break; - } + case 'e': case 'E': + case 'd': case 'D': + ++i; + ipe = i; + v = szVal[i]; + if ((v == '-') || (v == '+')) ++i; + while ((v=szVal[i]) != 0) { + if (!ISDIGIT(v)) break; + ++i; + ++ne; + } + break; + default: + break; + } } nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */ /* units for szVal[] */ @@ -3929,37 +3940,39 @@ VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw) { size_t n; - if(VpIsNaN(a)) { - VpSetNaN(c); - return 0; + if (VpIsNaN(a)) { + VpSetNaN(c); + return 0; } - if(VpIsInf(a)) { - VpSetInf(c,isw*VpGetSign(a)); - return 0; + if (VpIsInf(a)) { + VpSetInf(c, isw * VpGetSign(a)); + return 0; } /* check if the RHS is zero */ - if(!VpIsZero(a)) { - c->exponent = a->exponent; /* store exponent */ - VpSetSign(c,(isw*VpGetSign(a))); /* set sign */ - n =(a->Prec < c->MaxPrec) ?(a->Prec) :(c->MaxPrec); - c->Prec = n; - memcpy(c->frac, a->frac, n * sizeof(BDIGIT)); - /* Needs round ? */ - if(isw!=10) { - /* Not in ActiveRound */ - if(c->Prec < a->Prec) { - VpInternalRound(c,n,(n>0)?a->frac[n-1]:0,a->frac[n]); - } else { + if (!VpIsZero(a)) { + c->exponent = a->exponent; /* store exponent */ + VpSetSign(c, isw * VpGetSign(a)); /* set sign */ + n = (a->Prec < c->MaxPrec) ? (a->Prec) : (c->MaxPrec); + c->Prec = n; + memcpy(c->frac, a->frac, n * sizeof(BDIGIT)); + /* Needs round ? */ + if (isw != 10) { + /* 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 { - /* The value of 'a' is zero. */ - VpSetZero(c,isw*VpGetSign(a)); - return 1; + } + } } - return c->Prec*BASE_FIG; + else { + /* The value of 'a' is zero. */ + VpSetZero(c, isw * VpGetSign(a)); + return 1; + } + return c->Prec * BASE_FIG; } /* @@ -3976,83 +3989,87 @@ VpAddSub(Real *c, Real *a, Real *b, int operation) BDIGIT mrv; #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpAddSub(enter) a=% \n", a); - VPrint(stdout, " b=% \n", b); - printf(" operation=%d\n", operation); + if (gfDebug) { + VPrint(stdout, "VpAddSub(enter) a=% \n", a); + VPrint(stdout, " b=% \n", b); + printf(" operation=%d\n", operation); } #endif /* BIGDECIMAL_DEBUG */ - if(!VpIsDefOP(c,a,b,(operation>0)?1:2)) return 0; /* No significant digits */ + if (!VpIsDefOP(c, a, b, (operation > 0) ? 1 : 2)) return 0; /* No significant digits */ /* check if a or b is zero */ - if(VpIsZero(a)) { - /* a is zero,then assign b to c */ - if(!VpIsZero(b)) { - VpAsgn(c, b, operation); - } else { - /* Both a and b are zero. */ - if(VpGetSign(a)<0 && operation*VpGetSign(b)<0) { - /* -0 -0 */ - VpSetZero(c,-1); - } else { - VpSetZero(c,1); - } - return 1; /* 0: 1 significant digits */ - } - return c->Prec*BASE_FIG; + if (VpIsZero(a)) { + /* a is zero,then assign b to c */ + if (!VpIsZero(b)) { + VpAsgn(c, b, operation); + } + else { + /* Both a and b are zero. */ + if (VpGetSign(a) < 0 && operation * VpGetSign(b) < 0) { + /* -0 -0 */ + VpSetZero(c, -1); + } + else { + VpSetZero(c, 1); + } + return 1; /* 0: 1 significant digits */ + } + return c->Prec * BASE_FIG; } - if(VpIsZero(b)) { - /* b is zero,then assign a to c. */ - VpAsgn(c, a, 1); - return c->Prec*BASE_FIG; + if (VpIsZero(b)) { + /* b is zero,then assign a to c. */ + VpAsgn(c, a, 1); + return c->Prec*BASE_FIG; } - if(operation < 0) sw = -1; - else sw = 1; + if (operation < 0) sw = -1; + else sw = 1; /* compare absolute value. As a result,|a_ptr|>=|b_ptr| */ - if(a->exponent > b->exponent) { - a_ptr = a; - b_ptr = b; + if (a->exponent > b->exponent) { + a_ptr = a; + b_ptr = b; } /* |a|>|b| */ - else if(a->exponent < b->exponent) { - a_ptr = b; - b_ptr = a; + else if (a->exponent < b->exponent) { + a_ptr = b; + b_ptr = a; } /* |a|<|b| */ else { - /* Exponent part of a and b is the same,then compare fraction */ - /* part */ - na = a->Prec; - nb = b->Prec; - n = Min(na, nb); - for(i=0;i < n; ++i) { - if(a->frac[i] > b->frac[i]) { - a_ptr = a; - b_ptr = b; - goto end_if; - } else if(a->frac[i] < b->frac[i]) { - a_ptr = b; - b_ptr = a; - goto end_if; - } - } - if(na > nb) { - a_ptr = a; - b_ptr = b; - goto end_if; - } else if(na < nb) { - a_ptr = b; - b_ptr = a; - goto end_if; - } - /* |a| == |b| */ - if(VpGetSign(a) + sw *VpGetSign(b) == 0) { - VpSetZero(c,1); /* abs(a)=abs(b) and operation = '-' */ - return c->Prec*BASE_FIG; - } - a_ptr = a; - b_ptr = b; + /* Exponent part of a and b is the same,then compare fraction */ + /* part */ + na = a->Prec; + nb = b->Prec; + n = Min(na, nb); + for (i=0; i < n; ++i) { + if (a->frac[i] > b->frac[i]) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (a->frac[i] < b->frac[i]) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + } + if (na > nb) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (na < nb) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + /* |a| == |b| */ + if (VpGetSign(a) + sw *VpGetSign(b) == 0) { + VpSetZero(c, 1); /* abs(a)=abs(b) and operation = '-' */ + return c->Prec * BASE_FIG; + } + a_ptr = a; + b_ptr = b; } end_if: @@ -4063,31 +4080,33 @@ end_if: * =-2 ...(-1)+(-1),(-1)-( 1) * If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|) * else c =(Sign ofisw)(|a_ptr|+|b_ptr|) - */ - if(isw) { /* addition */ - VpSetSign(c, 1); - mrv = VpAddAbs(a_ptr, b_ptr, c); - VpSetSign(c, isw / 2); - } else { /* subtraction */ - VpSetSign(c, 1); - mrv = VpSubAbs(a_ptr, b_ptr, c); - if(a_ptr == a) { - VpSetSign(c,VpGetSign(a)); - } else { - VpSetSign(c,VpGetSign(a_ptr) * sw); - } + */ + if (isw) { /* addition */ + VpSetSign(c, 1); + mrv = VpAddAbs(a_ptr, b_ptr, c); + VpSetSign(c, isw / 2); + } + else { /* subtraction */ + VpSetSign(c, 1); + mrv = VpSubAbs(a_ptr, b_ptr, c); + if (a_ptr == a) { + VpSetSign(c,VpGetSign(a)); + } + else { + VpSetSign(c, VpGetSign(a_ptr) * sw); + } } - VpInternalRound(c,0,(c->Prec>0)?c->frac[c->Prec-1]:0,mrv); + VpInternalRound(c, 0, (c->Prec > 0) ? c->frac[c->Prec-1] : 0, mrv); #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpAddSub(result) c=% \n", c); - VPrint(stdout, " a=% \n", a); - VPrint(stdout, " b=% \n", b); - printf(" operation=%d\n", operation); + if (gfDebug) { + VPrint(stdout, "VpAddSub(result) c=% \n", c); + VPrint(stdout, " a=% \n", a); + VPrint(stdout, " b=% \n", b); + printf(" operation=%d\n", operation); } #endif /* BIGDECIMAL_DEBUG */ - return c->Prec*BASE_FIG; + return c->Prec * BASE_FIG; } /* @@ -4108,9 +4127,9 @@ VpAddAbs(Real *a, Real *b, Real *c) BDIGIT av, bv, carry, mrv; #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpAddAbs called: a = %\n", a); - VPrint(stdout, " b = %\n", b); + if (gfDebug) { + VPrint(stdout, "VpAddAbs called: a = %\n", a); + VPrint(stdout, " b = %\n", b); } #endif /* BIGDECIMAL_DEBUG */ @@ -4118,55 +4137,58 @@ VpAddAbs(Real *a, Real *b, Real *c) a_pos = ap; b_pos = bp; c_pos = cp; - if(word_shift==(size_t)-1L) return 0; /* Overflow */ - if(b_pos == (size_t)-1L) goto Assign_a; + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; 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. */ - while(b_pos + word_shift > a_pos) { - --c_pos; - if(b_pos > 0) { - c->frac[c_pos] = b->frac[--b_pos]; - } else { - --word_shift; - c->frac[c_pos] = 0; - } + while (b_pos + word_shift > a_pos) { + --c_pos; + if (b_pos > 0) { + c->frac[c_pos] = b->frac[--b_pos]; + } + else { + --word_shift; + c->frac[c_pos] = 0; + } } /* Just assign the last few digits of a to c because b has no */ /* corresponding digits to be added. */ b_pos_with_word_shift = b_pos + word_shift; - while(a_pos > b_pos_with_word_shift) { - c->frac[--c_pos] = a->frac[--a_pos]; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; } carry = 0; /* set first carry be zero */ /* Now perform addition until every digits of b will be */ /* exhausted. */ - while(b_pos > 0) { - c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry; - if(c->frac[c_pos] >= BASE) { - c->frac[c_pos] -= BASE; - carry = 1; - } else { - carry = 0; - } + while (b_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } } /* Just assign the first few digits of a with considering */ /* the carry obtained so far because b has been exhausted. */ - while(a_pos > 0) { - c->frac[--c_pos] = a->frac[--a_pos] + carry; - if(c->frac[c_pos] >= BASE) { - c->frac[c_pos] -= BASE; - carry = 1; - } else { - carry = 0; - } + while (a_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } } - if(c_pos) c->frac[c_pos - 1] += carry; + if (c_pos) c->frac[c_pos - 1] += carry; goto Exit; Assign_a: @@ -4176,8 +4198,8 @@ Assign_a: Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpAddAbs exit: c=% \n", c); + if (gfDebug) { + VPrint(stdout, "VpAddAbs exit: c=% \n", c); } #endif /* BIGDECIMAL_DEBUG */ return mrv; @@ -4199,9 +4221,9 @@ VpSubAbs(Real *a, Real *b, Real *c) BDIGIT av, bv, borrow, mrv; #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpSubAbs called: a = %\n", a); - VPrint(stdout, " b = %\n", b); + if (gfDebug) { + VPrint(stdout, "VpSubAbs called: a = %\n", a); + VPrint(stdout, " b = %\n", b); } #endif /* BIGDECIMAL_DEBUG */ @@ -4209,66 +4231,70 @@ VpSubAbs(Real *a, Real *b, Real *c) a_pos = ap; b_pos = bp; c_pos = cp; - if(word_shift==(size_t)-1L) return 0; /* Overflow */ - if(b_pos == (size_t)-1L) goto Assign_a; + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; - if(av >= bv) { - mrv = av - bv; - borrow = 0; - } else { - mrv = 0; - borrow = 1; + if (av >= bv) { + mrv = av - bv; + borrow = 0; + } + else { + mrv = 0; + borrow = 1; } /* Just assign the values which are the BASE subtracted by */ /* each of the last few digits of the b because the a has no */ /* corresponding digits to be subtracted. */ - if(b_pos + word_shift > a_pos) { - while(b_pos + word_shift > a_pos) { - --c_pos; - if(b_pos > 0) { - c->frac[c_pos] = BASE - b->frac[--b_pos] - borrow; - } else { - --word_shift; - c->frac[c_pos] = BASE - borrow; - } - borrow = 1; - } + if (b_pos + word_shift > a_pos) { + while (b_pos + word_shift > a_pos) { + --c_pos; + if (b_pos > 0) { + c->frac[c_pos] = BASE - b->frac[--b_pos] - borrow; + } + else { + --word_shift; + c->frac[c_pos] = BASE - borrow; + } + borrow = 1; + } } /* Just assign the last few digits of a to c because b has no */ /* corresponding digits to subtract. */ b_pos_with_word_shift = b_pos + word_shift; - while(a_pos > b_pos_with_word_shift) { - c->frac[--c_pos] = a->frac[--a_pos]; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; } /* Now perform subtraction until every digits of b will be */ /* exhausted. */ - while(b_pos > 0) { - --c_pos; - if(a->frac[--a_pos] < b->frac[--b_pos] + borrow) { - c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow; - borrow = 1; - } else { - c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow; - borrow = 0; - } + while (b_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < b->frac[--b_pos] + borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 0; + } } /* Just assign the first few digits of a with considering */ /* the borrow obtained so far because b has been exhausted. */ - while(a_pos > 0) { - --c_pos; - if(a->frac[--a_pos] < borrow) { - c->frac[c_pos] = BASE + a->frac[a_pos] - borrow; - borrow = 1; - } else { - c->frac[c_pos] = a->frac[a_pos] - borrow; - borrow = 0; - } + while (a_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - borrow; + borrow = 0; + } } - if(c_pos) c->frac[c_pos - 1] -= borrow; + if (c_pos) c->frac[c_pos - 1] -= borrow; goto Exit; Assign_a: @@ -4277,8 +4303,8 @@ Assign_a: Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpSubAbs exit: c=% \n", c); + if (gfDebug) { + VPrint(stdout, "VpSubAbs exit: c=% \n", c); } #endif /* BIGDECIMAL_DEBUG */ return mrv; @@ -4304,77 +4330,81 @@ VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, size_t left_word, right_word, word_shift; c->frac[0] = 0; *av = *bv = 0; - word_shift =((a->exponent) -(b->exponent)); + word_shift = (a->exponent - b->exponent); left_word = b->Prec + word_shift; - right_word = Max((a->Prec),left_word); - left_word =(c->MaxPrec) - 1; /* -1 ... prepare for round up */ + right_word = Max(a->Prec, left_word); + left_word = c->MaxPrec - 1; /* -1 ... prepare for round up */ /* * check if 'round' is needed. */ - if(right_word > left_word) { /* round ? */ - /*--------------------------------- - * Actual size of a = xxxxxxAxx - * Actual size of b = xxxBxxxxx - * Max. size of c = xxxxxx - * Round off = |-----| - * c_pos = | - * right_word = | - * a_pos = | - */ - *c_pos = right_word = left_word + 1; /* Set resulting precision */ - /* be equal to that of c */ - if((a->Prec) >=(c->MaxPrec)) { - /* - * a = xxxxxxAxxx - * c = xxxxxx - * a_pos = | - */ - *a_pos = left_word; - *av = a->frac[*a_pos]; /* av is 'A' shown in above. */ - } else { - /* - * a = xxxxxxx - * c = xxxxxxxxxx - * a_pos = | - */ - *a_pos = a->Prec; - } - if((b->Prec + word_shift) >= c->MaxPrec) { - /* - * a = xxxxxxxxx - * b = xxxxxxxBxxx - * c = xxxxxxxxxxx - * b_pos = | - */ - if(c->MaxPrec >=(word_shift + 1)) { - *b_pos = c->MaxPrec - word_shift - 1; - *bv = b->frac[*b_pos]; - } else { - *b_pos = -1L; - } - } else { - /* - * a = xxxxxxxxxxxxxxxx - * b = xxxxxx - * c = xxxxxxxxxxxxx - * b_pos = | - */ - *b_pos = b->Prec; - } - } else { /* The MaxPrec of c - 1 > The Prec of a + b */ - /* - * a = xxxxxxx - * b = xxxxxx - * c = xxxxxxxxxxx - * c_pos = | - */ - *b_pos = b->Prec; - *a_pos = a->Prec; - *c_pos = right_word + 1; + if (right_word > left_word) { /* round ? */ + /*--------------------------------- + * Actual size of a = xxxxxxAxx + * Actual size of b = xxxBxxxxx + * Max. size of c = xxxxxx + * Round off = |-----| + * c_pos = | + * right_word = | + * a_pos = | + */ + *c_pos = right_word = left_word + 1; /* Set resulting precision */ + /* be equal to that of c */ + if (a->Prec >= c->MaxPrec) { + /* + * a = xxxxxxAxxx + * c = xxxxxx + * a_pos = | + */ + *a_pos = left_word; + *av = a->frac[*a_pos]; /* av is 'A' shown in above. */ + } + else { + /* + * a = xxxxxxx + * c = xxxxxxxxxx + * a_pos = | + */ + *a_pos = a->Prec; + } + if (b->Prec + word_shift >= c->MaxPrec) { + /* + * a = xxxxxxxxx + * b = xxxxxxxBxxx + * c = xxxxxxxxxxx + * b_pos = | + */ + if (c->MaxPrec >= word_shift + 1) { + *b_pos = c->MaxPrec - word_shift - 1; + *bv = b->frac[*b_pos]; + } + else { + *b_pos = -1L; + } + } + else { + /* + * a = xxxxxxxxxxxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxxxx + * b_pos = | + */ + *b_pos = b->Prec; + } + } + else { /* The MaxPrec of c - 1 > The Prec of a + b */ + /* + * a = xxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxx + * c_pos = | + */ + *b_pos = b->Prec; + *a_pos = a->Prec; + *c_pos = right_word + 1; } c->Prec = *c_pos; c->exponent = a->exponent; - if(!AddExponent(c,1)) return (size_t)-1L; + if (!AddExponent(c, 1)) return (size_t)-1L; return word_shift; } @@ -4404,33 +4434,33 @@ VpMult(Real *c, Real *a, Real *b) Real *w; #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpMult(Enter): a=% \n", a); - VPrint(stdout, " b=% \n", b); + if (gfDebug) { + VPrint(stdout, "VpMult(Enter): a=% \n", a); + VPrint(stdout, " b=% \n", b); } #endif /* BIGDECIMAL_DEBUG */ - if(!VpIsDefOP(c,a,b,3)) return 0; /* No significant digit */ + if (!VpIsDefOP(c, a, b, 3)) return 0; /* No significant digit */ - if(VpIsZero(a) || VpIsZero(b)) { - /* at least a or b is zero */ - VpSetZero(c,VpGetSign(a)*VpGetSign(b)); - return 1; /* 0: 1 significant digit */ + if (VpIsZero(a) || VpIsZero(b)) { + /* at least a or b is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + return 1; /* 0: 1 significant digit */ } - if(VpIsOne(a)) { - VpAsgn(c, b, VpGetSign(a)); - goto Exit; + if (VpIsOne(a)) { + VpAsgn(c, b, VpGetSign(a)); + goto Exit; } - if(VpIsOne(b)) { - VpAsgn(c, a, VpGetSign(b)); - goto Exit; + if (VpIsOne(b)) { + VpAsgn(c, a, VpGetSign(b)); + goto Exit; } - if((b->Prec) >(a->Prec)) { - /* Adjust so that digits(a)>digits(b) */ - w = a; - a = b; - b = w; + if (b->Prec > a->Prec) { + /* Adjust so that digits(a)>digits(b) */ + w = a; + a = b; + b = w; } w = NULL; MxIndA = a->Prec - 1; @@ -4438,78 +4468,82 @@ VpMult(Real *c, Real *a, Real *b) MxIndC = c->MaxPrec - 1; MxIndAB = a->Prec + b->Prec - 1; - if(MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */ - w = c; - c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0"); - MxIndC = MxIndAB; + if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */ + w = c; + c = VpAlloc((size_t)((MxIndAB + 1) * BASE_FIG), "#0"); + MxIndC = MxIndAB; } /* set LHSV c info */ c->exponent = a->exponent; /* set exponent */ - if(!AddExponent(c,b->exponent)) { - if(w) VpFree(c); + if (!AddExponent(c, b->exponent)) { + if (w) VpFree(c); return 0; } - VpSetSign(c,VpGetSign(a)*VpGetSign(b)); /* set sign */ + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); /* set sign */ carry = 0; nc = ind_c = MxIndAB; memset(c->frac, 0, (nc + 1) * sizeof(BDIGIT)); /* Initialize c */ c->Prec = nc + 1; /* set precision */ - for(nc = 0; nc < MxIndAB; ++nc, --ind_c) { - if(nc < MxIndB) { /* The left triangle of the Fig. */ - ind_as = MxIndA - nc; - ind_ae = MxIndA; - ind_bs = MxIndB; - } else if(nc <= MxIndA) { /* The middle rectangular of the Fig. */ - ind_as = MxIndA - nc; - ind_ae = MxIndA -(nc - MxIndB); - ind_bs = MxIndB; - } else if(nc > MxIndA) { /* The right triangle of the Fig. */ - ind_as = 0; - ind_ae = MxIndAB - nc - 1; - ind_bs = MxIndB -(nc - MxIndA); - } + for (nc = 0; nc < MxIndAB; ++nc, --ind_c) { + if (nc < MxIndB) { /* The left triangle of the Fig. */ + ind_as = MxIndA - nc; + ind_ae = MxIndA; + ind_bs = MxIndB; + } + else if (nc <= MxIndA) { /* The middle rectangular of the Fig. */ + ind_as = MxIndA - nc; + ind_ae = MxIndA - (nc - MxIndB); + ind_bs = MxIndB; + } + else if (nc > MxIndA) { /* The right triangle of the Fig. */ + ind_as = 0; + ind_ae = MxIndAB - nc - 1; + ind_bs = MxIndB - (nc - MxIndA); + } - for(i = ind_as; i <= ind_ae; ++i) { - s = (BDIGIT_DBL)a->frac[i] * b->frac[ind_bs--]; - carry = (BDIGIT)(s / BASE); - s -= (BDIGIT_DBL)carry * BASE; - c->frac[ind_c] += (BDIGIT)s; - if(c->frac[ind_c] >= BASE) { - s = c->frac[ind_c] / BASE; - carry += (BDIGIT)s; - c->frac[ind_c] -= (BDIGIT)(s * BASE); - } - if(carry) { - ii = ind_c; - while(ii-- > 0) { - c->frac[ii] += carry; - if(c->frac[ii] >= BASE) { - carry = c->frac[ii] / BASE; - c->frac[ii] -= (carry * BASE); - } else { - break; - } - } - } - } + for (i = ind_as; i <= ind_ae; ++i) { + s = (BDIGIT_DBL)a->frac[i] * b->frac[ind_bs--]; + carry = (BDIGIT)(s / BASE); + s -= (BDIGIT_DBL)carry * BASE; + c->frac[ind_c] += (BDIGIT)s; + if (c->frac[ind_c] >= BASE) { + s = c->frac[ind_c] / BASE; + carry += (BDIGIT)s; + c->frac[ind_c] -= (BDIGIT)(s * BASE); + } + if (carry) { + ii = ind_c; + while (ii-- > 0) { + c->frac[ii] += carry; + if (c->frac[ii] >= BASE) { + carry = c->frac[ii] / BASE; + c->frac[ii] -= (carry * BASE); + } + else { + break; + } + } + } + } } - if(w != NULL) { /* free work variable */ - VpNmlz(c); - VpAsgn(w, c, 1); - VpFree(c); - c = w; - } else { - VpLimitRound(c,0); + if (w != NULL) { /* free work variable */ + VpNmlz(c); + VpAsgn(w, c, 1); + VpFree(c); + c = w; + } + else { + VpLimitRound(c,0); } Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpMult(c=a*b): c=% \n", c); - VPrint(stdout, " a=% \n", a); - VPrint(stdout, " b=% \n", b); + if (gfDebug) { + VPrint(stdout, "VpMult(c=a*b): c=% \n", c); + VPrint(stdout, " a=% \n", a); + VPrint(stdout, " b=% \n", b); } #endif /*BIGDECIMAL_DEBUG */ return c->Prec*BASE_FIG; @@ -4518,7 +4552,7 @@ Exit: /* * c = a / b, remainder = r */ -VP_EXPORT size_t + VP_EXPORT size_t VpDivd(Real *c, Real *r, Real *a, Real *b) { size_t word_a, word_b, word_c, word_r; @@ -4529,33 +4563,33 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) BDIGIT_DBL qb; #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, " VpDivd(c=a/b) a=% \n", a); - VPrint(stdout, " b=% \n", b); + if (gfDebug) { + VPrint(stdout, " VpDivd(c=a/b) a=% \n", a); + VPrint(stdout, " b=% \n", b); } #endif /*BIGDECIMAL_DEBUG */ VpSetNaN(r); - if(!VpIsDefOP(c,a,b,4)) goto Exit; - if(VpIsZero(a)&&VpIsZero(b)) { - VpSetNaN(c); - return VpException(VP_EXCEPTION_NaN,"(VpDivd) 0/0 not defined(NaN)",0); + if (!VpIsDefOP(c, a, b, 4)) goto Exit; + if (VpIsZero(a) && VpIsZero(b)) { + VpSetNaN(c); + return VpException(VP_EXCEPTION_NaN, "(VpDivd) 0/0 not defined(NaN)", 0); } - if(VpIsZero(b)) { - VpSetInf(c,VpGetSign(a)*VpGetSign(b)); - return VpException(VP_EXCEPTION_ZERODIVIDE,"(VpDivd) Divide by zero",0); + if (VpIsZero(b)) { + VpSetInf(c, VpGetSign(a) * VpGetSign(b)); + return VpException(VP_EXCEPTION_ZERODIVIDE, "(VpDivd) Divide by zero", 0); } - if(VpIsZero(a)) { - /* numerator a is zero */ - VpSetZero(c,VpGetSign(a)*VpGetSign(b)); - VpSetZero(r,VpGetSign(a)*VpGetSign(b)); - goto Exit; + if (VpIsZero(a)) { + /* numerator a is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + VpSetZero(r, VpGetSign(a) * VpGetSign(b)); + goto Exit; } - if(VpIsOne(b)) { - /* divide by one */ - VpAsgn(c, a, VpGetSign(b)); - VpSetZero(r,VpGetSign(a)); - goto Exit; + if (VpIsOne(b)) { + /* divide by one */ + VpAsgn(c, a, VpGetSign(b)); + VpSetZero(r, VpGetSign(a)); + goto Exit; } word_a = a->Prec; @@ -4566,25 +4600,26 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) ind_c = 0; ind_r = 1; - if(word_a >= word_r) goto space_error; + if (word_a >= word_r) goto space_error; r->frac[0] = 0; - while(ind_r <= word_a) { - r->frac[ind_r] = a->frac[ind_r - 1]; - ++ind_r; + while (ind_r <= word_a) { + r->frac[ind_r] = a->frac[ind_r - 1]; + ++ind_r; } - while(ind_r < word_r) r->frac[ind_r++] = 0; - while(ind_c < word_c) c->frac[ind_c++] = 0; + while (ind_r < word_r) r->frac[ind_r++] = 0; + while (ind_c < word_c) c->frac[ind_c++] = 0; /* initial procedure */ b1 = b1p1 = b->frac[0]; - if(b->Prec <= 1) { - b1b2p1 = b1b2 = b1p1 * BASE; - } else { - b1p1 = b1 + 1; - b1b2p1 = b1b2 = b1 * BASE + b->frac[1]; - if(b->Prec > 2) ++b1b2p1; + if (b->Prec <= 1) { + b1b2p1 = b1b2 = b1p1 * BASE; + } + else { + b1p1 = b1 + 1; + b1b2p1 = b1b2 = b1 * BASE + b->frac[1]; + if (b->Prec > 2) ++b1b2p1; } /* */ @@ -4592,137 +4627,140 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) ind_c = word_r - 1; nLoop = Min(word_c,ind_c); ind_c = 1; - while(ind_c < nLoop) { - if(r->frac[ind_c] == 0) { - ++ind_c; - continue; - } - r1r2 = (BDIGIT_DBL)r->frac[ind_c] * BASE + r->frac[ind_c + 1]; - if(r1r2 == b1b2) { - /* The first two word digits is the same */ - ind_b = 2; - ind_a = ind_c + 2; - while(ind_b < word_b) { - if(r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1; - if(r->frac[ind_a] > b->frac[ind_b]) break; - ++ind_a; - ++ind_b; - } - /* The first few word digits of r and b is the same and */ - /* the first different word digit of w is greater than that */ - /* of b, so quotinet is 1 and just subtract b from r. */ - borrow = 0; /* quotient=1, then just r-b */ - ind_b = b->Prec - 1; - ind_r = ind_c + ind_b; - if(ind_r >= word_r) goto space_error; - n = ind_b; - for(i = 0; i <= n; ++i) { - if(r->frac[ind_r] < b->frac[ind_b] + borrow) { - r->frac[ind_r] += (BASE - (b->frac[ind_b] + borrow)); - borrow = 1; - } else { - r->frac[ind_r] = r->frac[ind_r] - b->frac[ind_b] - borrow; - borrow = 0; - } - --ind_r; - --ind_b; - } - ++c->frac[ind_c]; - goto carry; - } - /* The first two word digits is not the same, */ - /* then compare magnitude, and divide actually. */ - if(r1r2 >= b1b2p1) { - q = r1r2 / b1b2p1; /* q == (BDIGIT)q */ - c->frac[ind_c] += (BDIGIT)q; - ind_r = b->Prec + ind_c - 1; - goto sub_mult; - } + while (ind_c < nLoop) { + if (r->frac[ind_c] == 0) { + ++ind_c; + continue; + } + r1r2 = (BDIGIT_DBL)r->frac[ind_c] * BASE + r->frac[ind_c + 1]; + if (r1r2 == b1b2) { + /* The first two word digits is the same */ + ind_b = 2; + ind_a = ind_c + 2; + while (ind_b < word_b) { + if (r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1; + if (r->frac[ind_a] > b->frac[ind_b]) break; + ++ind_a; + ++ind_b; + } + /* The first few word digits of r and b is the same and */ + /* the first different word digit of w is greater than that */ + /* of b, so quotinet is 1 and just subtract b from r. */ + borrow = 0; /* quotient=1, then just r-b */ + ind_b = b->Prec - 1; + ind_r = ind_c + ind_b; + if (ind_r >= word_r) goto space_error; + n = ind_b; + for (i = 0; i <= n; ++i) { + if (r->frac[ind_r] < b->frac[ind_b] + borrow) { + r->frac[ind_r] += (BASE - (b->frac[ind_b] + borrow)); + borrow = 1; + } + else { + r->frac[ind_r] = r->frac[ind_r] - b->frac[ind_b] - borrow; + borrow = 0; + } + --ind_r; + --ind_b; + } + ++c->frac[ind_c]; + goto carry; + } + /* The first two word digits is not the same, */ + /* then compare magnitude, and divide actually. */ + if (r1r2 >= b1b2p1) { + q = r1r2 / b1b2p1; /* q == (BDIGIT)q */ + c->frac[ind_c] += (BDIGIT)q; + ind_r = b->Prec + ind_c - 1; + goto sub_mult; + } div_b1p1: - if(ind_c + 1 >= word_c) goto out_side; - q = r1r2 / b1p1; /* q == (BDIGIT)q */ - c->frac[ind_c + 1] += (BDIGIT)q; - ind_r = b->Prec + ind_c; + if (ind_c + 1 >= word_c) goto out_side; + q = r1r2 / b1p1; /* q == (BDIGIT)q */ + c->frac[ind_c + 1] += (BDIGIT)q; + ind_r = b->Prec + ind_c; sub_mult: - borrow1 = borrow2 = 0; - ind_b = word_b - 1; - if(ind_r >= word_r) goto space_error; - n = ind_b; - for(i = 0; i <= n; ++i) { - /* now, perform r = r - q * b */ - qb = q * b->frac[ind_b]; - if (qb < BASE) borrow1 = 0; - else { - borrow1 = (BDIGIT)(qb / BASE); - qb -= (BDIGIT_DBL)borrow1 * BASE; /* get qb < BASE */ - } - if(r->frac[ind_r] < qb) { - r->frac[ind_r] += (BDIGIT)(BASE - qb); - borrow2 = borrow2 + borrow1 + 1; - } else { - r->frac[ind_r] -= (BDIGIT)qb; - borrow2 += borrow1; - } - if(borrow2) { - if(r->frac[ind_r - 1] < borrow2) { - r->frac[ind_r - 1] += (BASE - borrow2); - borrow2 = 1; - } else { - r->frac[ind_r - 1] -= borrow2; - borrow2 = 0; - } - } - --ind_r; - --ind_b; - } + borrow1 = borrow2 = 0; + ind_b = word_b - 1; + if (ind_r >= word_r) goto space_error; + n = ind_b; + for (i = 0; i <= n; ++i) { + /* now, perform r = r - q * b */ + qb = q * b->frac[ind_b]; + if (qb < BASE) borrow1 = 0; + else { + borrow1 = (BDIGIT)(qb / BASE); + qb -= (BDIGIT_DBL)borrow1 * BASE; /* get qb < BASE */ + } + if(r->frac[ind_r] < qb) { + r->frac[ind_r] += (BDIGIT)(BASE - qb); + borrow2 = borrow2 + borrow1 + 1; + } + else { + r->frac[ind_r] -= (BDIGIT)qb; + borrow2 += borrow1; + } + if (borrow2) { + if(r->frac[ind_r - 1] < borrow2) { + r->frac[ind_r - 1] += (BASE - borrow2); + borrow2 = 1; + } + else { + r->frac[ind_r - 1] -= borrow2; + borrow2 = 0; + } + } + --ind_r; + --ind_b; + } - r->frac[ind_r] -= borrow2; + r->frac[ind_r] -= borrow2; carry: - ind_r = ind_c; - while(c->frac[ind_r] >= BASE) { - c->frac[ind_r] -= BASE; - --ind_r; - ++c->frac[ind_r]; - } + ind_r = ind_c; + while (c->frac[ind_r] >= BASE) { + c->frac[ind_r] -= BASE; + --ind_r; + ++c->frac[ind_r]; + } } /* End of operation, now final arrangement */ out_side: c->Prec = word_c; c->exponent = a->exponent; - if(!AddExponent(c,2)) return 0; - if(!AddExponent(c,-(b->exponent))) return 0; + if (!AddExponent(c, 2)) return 0; + if (!AddExponent(c, -(b->exponent))) return 0; - VpSetSign(c,VpGetSign(a)*VpGetSign(b)); + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); VpNmlz(c); /* normalize c */ r->Prec = word_r; r->exponent = a->exponent; - if(!AddExponent(r,1)) return 0; - VpSetSign(r,VpGetSign(a)); + if (!AddExponent(r, 1)) return 0; + VpSetSign(r, VpGetSign(a)); VpNmlz(r); /* normalize r(remainder) */ goto Exit; space_error: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - printf(" word_a=%lu\n", word_a); - printf(" word_b=%lu\n", word_b); - printf(" word_c=%lu\n", word_c); - printf(" word_r=%lu\n", word_r); - printf(" ind_r =%lu\n", ind_r); + if (gfDebug) { + printf(" word_a=%lu\n", word_a); + printf(" word_b=%lu\n", word_b); + printf(" word_c=%lu\n", word_c); + printf(" word_r=%lu\n", word_r); + printf(" ind_r =%lu\n", ind_r); } #endif /* BIGDECIMAL_DEBUG */ rb_bug("ERROR(VpDivd): space for remainder too small."); Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, " VpDivd(c=a/b), c=% \n", c); - VPrint(stdout, " r=% \n", r); + if (gfDebug) { + VPrint(stdout, " VpDivd(c=a/b), c=% \n", c); + VPrint(stdout, " r=% \n", r); } #endif /* BIGDECIMAL_DEBUG */ - return c->Prec*BASE_FIG; + return c->Prec * BASE_FIG; } /* @@ -4739,17 +4777,17 @@ VpNmlz(Real *a) ind_a = a->Prec; while (ind_a--) { - if (a->frac[ind_a]) { - a->Prec = ind_a + 1; - i = 0; - while (a->frac[i] == 0) ++i; /* skip the first few zeros */ - if (i) { - a->Prec -= i; - if (!AddExponent(a, -(SIGNED_VALUE)i)) return 0; - memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(BDIGIT)); - } - return 1; - } + if (a->frac[ind_a]) { + a->Prec = ind_a + 1; + i = 0; + while (a->frac[i] == 0) ++i; /* skip the first few zeros */ + if (i) { + a->Prec -= i; + if (!AddExponent(a, -(SIGNED_VALUE)i)) return 0; + memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(BDIGIT)); + } + return 1; + } } /* a is zero(no non-zero digit) */ VpSetZero(a, VpGetSign(a)); @@ -4774,79 +4812,81 @@ VpComp(Real *a, Real *b) size_t mx, ind; int e; val = 0; - if(VpIsNaN(a)||VpIsNaN(b)) return 999; - if(!VpIsDef(a)) { - if(!VpIsDef(b)) e = a->sign - b->sign; - else e = a->sign; - if(e>0) return 1; - else if(e<0) return -1; - else return 0; - } - if(!VpIsDef(b)) { - e = -b->sign; - if(e>0) return 1; - else return -1; + if (VpIsNaN(a) || VpIsNaN(b)) return 999; + if (!VpIsDef(a)) { + if (!VpIsDef(b)) e = a->sign - b->sign; + else e = a->sign; + + if (e > 0) return 1; + else if (e < 0) return -1; + else return 0; + } + if (!VpIsDef(b)) { + e = -b->sign; + if (e > 0) return 1; + else return -1; } /* Zero check */ - if(VpIsZero(a)) { - if(VpIsZero(b)) return 0; /* both zero */ - val = -VpGetSign(b); - goto Exit; + if (VpIsZero(a)) { + if (VpIsZero(b)) return 0; /* both zero */ + val = -VpGetSign(b); + goto Exit; } - if(VpIsZero(b)) { - val = VpGetSign(a); - goto Exit; + if (VpIsZero(b)) { + val = VpGetSign(a); + goto Exit; } /* compare sign */ - if(VpGetSign(a) > VpGetSign(b)) { - val = 1; /* a>b */ - goto Exit; + if (VpGetSign(a) > VpGetSign(b)) { + val = 1; /* a>b */ + goto Exit; } - if(VpGetSign(a) < VpGetSign(b)) { - val = -1; /* aexponent) >(b->exponent)) { - val = VpGetSign(a); - goto Exit; + if (a->exponent > b->exponent) { + val = VpGetSign(a); + goto Exit; } - if((a->exponent) <(b->exponent)) { - val = -VpGetSign(b); - goto Exit; + if (a->exponent < b->exponent) { + val = -VpGetSign(b); + goto Exit; } /* a and b have same exponent, then compare significand. */ - mx =((a->Prec) <(b->Prec)) ?(a->Prec) :(b->Prec); + mx = (a->Prec < b->Prec) ? a->Prec : b->Prec; ind = 0; - while(ind < mx) { - if((a->frac[ind]) >(b->frac[ind])) { - val = VpGetSign(a); - goto Exit; - } - if((a->frac[ind]) <(b->frac[ind])) { - val = -VpGetSign(b); - goto Exit; - } - ++ind; + while (ind < mx) { + if (a->frac[ind] > b->frac[ind]) { + val = VpGetSign(a); + goto Exit; + } + if (a->frac[ind] < b->frac[ind]) { + val = -VpGetSign(b); + goto Exit; + } + ++ind; + } + if (a->Prec > b->Prec) { + val = VpGetSign(a); } - if((a->Prec) >(b->Prec)) { - val = VpGetSign(a); - } else if((a->Prec) <(b->Prec)) { - val = -VpGetSign(b); + else if (a->Prec < b->Prec) { + val = -VpGetSign(b); } Exit: - if (val> 1) val = 1; - else if(val<-1) val = -1; + if (val > 1) val = 1; + else if (val < -1) val = -1; #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, " VpComp a=%\n", a); - VPrint(stdout, " b=%\n", b); - printf(" ans=%d\n", val); + if (gfDebug) { + VPrint(stdout, " VpComp a=%\n", a); + VPrint(stdout, " b=%\n", b); + printf(" ans=%d\n", val); } #endif /* BIGDECIMAL_DEBUG */ return (int)val; @@ -4863,28 +4903,28 @@ Exit: * Note: % must must not appear more than once * a ... VP variable to be printed */ -VP_EXPORT int + VP_EXPORT int VPrint(FILE *fp, const char *cntl_chr, Real *a) { size_t i, j, nc, nd, ZeroSup; BDIGIT m, e, nn; /* Check if NaN & Inf. */ - if(VpIsNaN(a)) { - fprintf(fp,SZ_NaN); - return 8; + if (VpIsNaN(a)) { + fprintf(fp, SZ_NaN); + return 8; } - if(VpIsPosInf(a)) { - fprintf(fp,SZ_INF); - return 8; + if (VpIsPosInf(a)) { + fprintf(fp, SZ_INF); + return 8; } - if(VpIsNegInf(a)) { - fprintf(fp,SZ_NINF); - return 9; + if (VpIsNegInf(a)) { + fprintf(fp, SZ_NINF); + return 9; } - if(VpIsZero(a)) { - fprintf(fp,"0.0"); - return 3; + if (VpIsZero(a)) { + fprintf(fp, "0.0"); + return 3; } j = 0; @@ -4892,65 +4932,68 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a) /* nd<=10). */ /* nc : number of caracters printed */ ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ - while(*(cntl_chr + j)) { - if((*(cntl_chr + j) == '%') &&(*(cntl_chr + j + 1) != '%')) { - nc = 0; - if(!VpIsZero(a)) { - if(VpGetSign(a) < 0) { - fprintf(fp, "-"); - ++nc; - } - nc += fprintf(fp, "0."); - for(i=0; i < a->Prec; ++i) { + while (*(cntl_chr + j)) { + if (*(cntl_chr + j) == '%' && *(cntl_chr + j + 1) != '%') { + nc = 0; + if (!VpIsZero(a)) { + if (VpGetSign(a) < 0) { + fprintf(fp, "-"); + ++nc; + } + nc += fprintf(fp, "0."); + for (i = 0; i < a->Prec; ++i) { m = BASE1; - e = a->frac[i]; - while(m) { - nn = e / m; - if((!ZeroSup) || nn) { - nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */ - /* as 0.00xx will not */ - /* be printed. */ - ++nd; - ZeroSup = 0; /* Set to print succeeding zeros */ - } - if(nd >= 10) { /* print ' ' after every 10 digits */ - nd = 0; - nc += fprintf(fp, " "); - } - e = e - nn * m; - m /= 10; - } - } - nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a)); - } else { - nc += fprintf(fp, "0.0"); - } - } else { - ++nc; - if(*(cntl_chr + j) == '\\') { - switch(*(cntl_chr + j + 1)) { - case 'n': - fprintf(fp, "\n"); - ++j; - break; - case 't': - fprintf(fp, "\t"); - ++j; - break; - case 'b': - fprintf(fp, "\n"); - ++j; - break; - default: - fprintf(fp, "%c", *(cntl_chr + j)); - break; - } - } else { - fprintf(fp, "%c", *(cntl_chr + j)); - if(*(cntl_chr + j) == '%') ++j; - } - } - j++; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */ + /* as 0.00xx will not */ + /* be printed. */ + ++nd; + ZeroSup = 0; /* Set to print succeeding zeros */ + } + if (nd >= 10) { /* print ' ' after every 10 digits */ + nd = 0; + nc += fprintf(fp, " "); + } + e = e - nn * m; + m /= 10; + } + } + nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a)); + } + else { + nc += fprintf(fp, "0.0"); + } + } + else { + ++nc; + if (*(cntl_chr + j) == '\\') { + switch (*(cntl_chr + j + 1)) { + case 'n': + fprintf(fp, "\n"); + ++j; + break; + case 't': + fprintf(fp, "\t"); + ++j; + break; + case 'b': + fprintf(fp, "\n"); + ++j; + break; + default: + fprintf(fp, "%c", *(cntl_chr + j)); + break; + } + } + else { + fprintf(fp, "%c", *(cntl_chr + j)); + if (*(cntl_chr + j) == '%') ++j; + } + } + j++; } return (int)nc; } @@ -4962,22 +5005,22 @@ VpFormatSt(char *psz, size_t fFmt) size_t ie, i, nf = 0; char ch; - if(fFmt<=0) return; + if (fFmt <= 0) return; ie = strlen(psz); - for(i = 0; i < ie; ++i) { - ch = psz[i]; - if(!ch) break; - if(ISSPACE(ch) || ch=='-' || ch=='+') continue; - if(ch == '.') { nf = 0;continue;} - if(ch == 'E') break; - nf++; - if(nf > fFmt) { - memmove(psz + i + 1, psz + i, ie - i + 1); - ++ie; - nf = 0; - psz[i] = ' '; - } + for (i = 0; i < ie; ++i) { + ch = psz[i]; + if (!ch) break; + if (ISSPACE(ch) || ch=='-' || ch=='+') continue; + if (ch == '.') { nf = 0; continue; } + if (ch == 'E') break; + + if (++nf > fFmt) { + memmove(psz + i + 1, psz + i, ie - i + 1); + ++ie; + nf = 0; + psz[i] = ' '; + } } } @@ -4992,8 +5035,8 @@ VpExponent10(Real *a) ex = a->exponent * (ssize_t)BASE_FIG; n = BASE1; while ((a->frac[0] / n) == 0) { - --ex; - n /= 10; + --ex; + n /= 10; } return ex; } @@ -5004,75 +5047,78 @@ VpSzMantissa(Real *a,char *psz) size_t i, n, ZeroSup; BDIGIT_DBL m, e, nn; - if(VpIsNaN(a)) { - sprintf(psz,SZ_NaN); - return; + if (VpIsNaN(a)) { + sprintf(psz, SZ_NaN); + return; } - if(VpIsPosInf(a)) { - sprintf(psz,SZ_INF); - return; + if (VpIsPosInf(a)) { + sprintf(psz, SZ_INF); + return; } - if(VpIsNegInf(a)) { - sprintf(psz,SZ_NINF); - return; + if (VpIsNegInf(a)) { + sprintf(psz, SZ_NINF); + return; } ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ - if(!VpIsZero(a)) { - if(VpGetSign(a) < 0) *psz++ = '-'; - n = a->Prec; - for (i=0; i < n; ++i) { - m = BASE1; - e = a->frac[i]; - while (m) { - nn = e / m; - if((!ZeroSup) || nn) { - sprintf(psz, "%lu", (unsigned long)nn); /* The leading zero(s) */ - psz += strlen(psz); - /* as 0.00xx will be ignored. */ - ZeroSup = 0; /* Set to print succeeding zeros */ - } - e = e - nn * m; - m /= 10; - } - } - *psz = 0; - while(psz[-1]=='0') *(--psz) = 0; - } else { - if(VpIsPosZero(a)) sprintf(psz, "0"); - else sprintf(psz, "-0"); + if (!VpIsZero(a)) { + if (VpGetSign(a) < 0) *psz++ = '-'; + n = a->Prec; + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + sprintf(psz, "%lu", (unsigned long)nn); /* The leading zero(s) */ + psz += strlen(psz); + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } + } + *psz = 0; + while (psz[-1] == '0') *(--psz) = 0; + } + else { + if (VpIsPosZero(a)) sprintf(psz, "0"); + else sprintf(psz, "-0"); } } VP_EXPORT int VpToSpecialString(Real *a,char *psz,int fPlus) -/* fPlus =0:default, =1: set ' ' before digits , =2: set '+' before digits. */ + /* fPlus =0:default, =1: set ' ' before digits , =2: set '+' before digits. */ { - if(VpIsNaN(a)) { - sprintf(psz,SZ_NaN); - return 1; + if (VpIsNaN(a)) { + sprintf(psz,SZ_NaN); + return 1; } - if(VpIsPosInf(a)) { - if(fPlus==1) { - *psz++ = ' '; - } else if(fPlus==2) { - *psz++ = '+'; - } - sprintf(psz,SZ_INF); - return 1; + if (VpIsPosInf(a)) { + if (fPlus == 1) { + *psz++ = ' '; + } + else if (fPlus == 2) { + *psz++ = '+'; + } + sprintf(psz, SZ_INF); + return 1; } - if(VpIsNegInf(a)) { - sprintf(psz,SZ_NINF); - return 1; + if (VpIsNegInf(a)) { + sprintf(psz, SZ_NINF); + return 1; } - if(VpIsZero(a)) { - if(VpIsPosZero(a)) { - if(fPlus==1) sprintf(psz, " 0.0"); - else if(fPlus==2) sprintf(psz, "+0.0"); - else sprintf(psz, "0.0"); - } else sprintf(psz, "-0.0"); - return 1; + if (VpIsZero(a)) { + if (VpIsPosZero(a)) { + if (fPlus == 1) sprintf(psz, " 0.0"); + else if (fPlus == 2) sprintf(psz, "+0.0"); + else sprintf(psz, "0.0"); + } + else sprintf(psz, "-0.0"); + return 1; } return 0; } @@ -5097,30 +5143,32 @@ VpToString(Real *a, char *psz, size_t fFmt, int fPlus) *psz++ = '0'; *psz++ = '.'; n = a->Prec; - for(i=0;i < n;++i) { - m = BASE1; - e = a->frac[i]; - while(m) { - nn = e / m; - if((!ZeroSup) || nn) { - sprintf(psz, "%lu", (unsigned long)nn); /* The reading zero(s) */ - psz += strlen(psz); - /* as 0.00xx will be ignored. */ - ZeroSup = 0; /* Set to print succeeding zeros */ - } - e = e - nn * m; - m /= 10; - } + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + sprintf(psz, "%lu", (unsigned long)nn); /* The reading zero(s) */ + psz += strlen(psz); + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } } ex = a->exponent * (ssize_t)BASE_FIG; shift = BASE1; - while(a->frac[0] / shift == 0) { - --ex; - shift /= 10; + while (a->frac[0] / shift == 0) { + --ex; + shift /= 10; + } + while (psz[-1] == '0') { + *(--psz) = 0; } - while(psz[-1]=='0') *(--psz) = 0; sprintf(psz, "E%"PRIdSIZE, ex); - if(fFmt) VpFormatSt(pszSav, fFmt); + if (fFmt) VpFormatSt(pszSav, fFmt); } VP_EXPORT void @@ -5132,49 +5180,50 @@ VpToFString(Real *a, char *psz, size_t fFmt, int fPlus) char *pszSav = psz; ssize_t ex; - if(VpToSpecialString(a,psz,fPlus)) return; + if (VpToSpecialString(a, psz, fPlus)) return; - if(VpGetSign(a) < 0) *psz++ = '-'; - else if(fPlus==1) *psz++ = ' '; - else if(fPlus==2) *psz++ = '+'; + if (VpGetSign(a) < 0) *psz++ = '-'; + else if (fPlus == 1) *psz++ = ' '; + else if (fPlus == 2) *psz++ = '+'; n = a->Prec; ex = a->exponent; - if(ex<=0) { - *psz++ = '0';*psz++ = '.'; - while(ex<0) { - for(i=0;i= 0) { - sprintf(psz, "%lu", (unsigned long)a->frac[i]); - psz += strlen(psz); - } else { - m = BASE1; - e = a->frac[i]; - while(m) { - nn = e / m; - *psz++ = (char)(nn + '0'); - e = e - nn * m; - m /= 10; - } - } - if(ex == 0) *psz++ = '.'; - } - while(--ex>=0) { - m = BASE; - while(m/=10) *psz++ = '0'; - if(ex == 0) *psz++ = '.'; + if (ex <= 0) { + *psz++ = '0';*psz++ = '.'; + while (ex < 0) { + for (i=0; i < BASE_FIG; ++i) *psz++ = '0'; + ++ex; + } + ex = -1; + } + + for (i = 0; i < n; ++i) { + --ex; + if (i == 0 && ex >= 0) { + sprintf(psz, "%lu", (unsigned long)a->frac[i]); + psz += strlen(psz); + } + else { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + *psz++ = (char)(nn + '0'); + e = e - nn * m; + m /= 10; + } + } + if (ex == 0) *psz++ = '.'; + } + while (--ex>=0) { + m = BASE; + while (m /= 10) *psz++ = '0'; + if (ex == 0) *psz++ = '.'; } *psz = 0; - while(psz[-1]=='0') *(--psz) = 0; - if(psz[-1]=='.') sprintf(psz, "0"); - if(fFmt) VpFormatSt(pszSav, fFmt); + while (psz[-1] == '0') *(--psz) = 0; + if (psz[-1] == '.') sprintf(psz, "0"); + if (fFmt) VpFormatSt(pszSav, fFmt); } /* @@ -5204,40 +5253,41 @@ VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, con exponent_overflow = 0; memset(a->frac, 0, ma * sizeof(BDIGIT)); if (ne > 0) { - i = 0; - if (exp_chr[0] == '-') { - signe = -1; - ++i; - ++me; - } + i = 0; + if (exp_chr[0] == '-') { + signe = -1; + ++i; + ++me; + } else if (exp_chr[0] == '+') { - ++i; - ++me; - } - while (i < me) { - es = e * (SIGNED_VALUE)BASE_FIG; - e = e * 10 + exp_chr[i] - '0'; - if (es > (SIGNED_VALUE)(e*BASE_FIG)) { + ++i; + ++me; + } + while (i < me) { + es = e * (SIGNED_VALUE)BASE_FIG; + e = e * 10 + exp_chr[i] - '0'; + if (es > (SIGNED_VALUE)(e * BASE_FIG)) { exponent_overflow = 1; e = es; /* keep sign */ break; - } - ++i; - } + } + ++i; + } } /* get integer part */ i = 0; sign = 1; - if(1 /*ni >= 0*/) { - if(int_chr[0] == '-') { - sign = -1; - ++i; - ++mi; - } else if(int_chr[0] == '+') { - ++i; - ++mi; - } + if (1 /*ni >= 0*/) { + if (int_chr[0] == '-') { + sign = -1; + ++i; + ++mi; + } + else if (int_chr[0] == '+') { + ++i; + ++mi; + } } e = signe * e; /* e: The value of exponent part. */ @@ -5250,14 +5300,14 @@ VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, con j = 0; ef = 1; while (ef) { - if (e >= 0) eb = e; - else eb = -e; - ef = eb / (SIGNED_VALUE)BASE_FIG; - ef = eb - ef * (SIGNED_VALUE)BASE_FIG; - if (ef) { - ++j; /* Means to add one more preceding zero */ - ++e; - } + if (e >= 0) eb = e; + else eb = -e; + ef = eb / (SIGNED_VALUE)BASE_FIG; + ef = eb - ef * (SIGNED_VALUE)BASE_FIG; + if (ef) { + ++j; /* Means to add one more preceding zero */ + ++e; + } } eb = e / (SIGNED_VALUE)BASE_FIG; @@ -5276,33 +5326,33 @@ VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, con ind_a = 0; while (i < mi) { - a->frac[ind_a] = 0; - while ((j < BASE_FIG) && (i < mi)) { - a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0'; - ++j; - ++i; - } - if (i < mi) { - ++ind_a; - if (ind_a >= ma) goto over_flow; - j = 0; - } + a->frac[ind_a] = 0; + while (j < BASE_FIG && i < mi) { + a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0'; + ++j; + ++i; + } + if (i < mi) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } } /* get fraction part */ i = 0; - while(i < nf) { - while((j < BASE_FIG) && (i < nf)) { - a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0'; - ++j; - ++i; - } - if(i < nf) { - ++ind_a; - if(ind_a >= ma) goto over_flow; - j = 0; - } + while (i < nf) { + while (j < BASE_FIG && i < nf) { + a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0'; + ++j; + ++i; + } + if (i < nf) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } } goto Final; @@ -5312,12 +5362,12 @@ over_flow: Final: if (ind_a >= ma) ind_a = ma - 1; while (j < BASE_FIG) { - a->frac[ind_a] = a->frac[ind_a] * 10; - ++j; + a->frac[ind_a] = a->frac[ind_a] * 10; + ++j; } a->Prec = ind_a + 1; a->exponent = eb; - VpSetSign(a,sign); + VpSetSign(a, sign); VpNmlz(a); return 1; } @@ -5344,55 +5394,55 @@ VpVtoD(double *d, SIGNED_VALUE *e, Real *m) double div; int f = 1; - if(VpIsNaN(m)) { - *d = VpGetDoubleNaN(); - *e = 0; - f = -1; /* NaN */ - goto Exit; - } else - if(VpIsPosZero(m)) { - *d = 0.0; - *e = 0; - f = 0; - goto Exit; - } else - if(VpIsNegZero(m)) { - *d = VpGetDoubleNegZero(); - *e = 0; - f = 0; - goto Exit; - } else - if(VpIsPosInf(m)) { - *d = VpGetDoublePosInf(); - *e = 0; - f = 2; - goto Exit; - } else - if(VpIsNegInf(m)) { - *d = VpGetDoubleNegInf(); - *e = 0; - f = 2; - goto Exit; + if (VpIsNaN(m)) { + *d = VpGetDoubleNaN(); + *e = 0; + f = -1; /* NaN */ + goto Exit; + } + else if (VpIsPosZero(m)) { + *d = 0.0; + *e = 0; + f = 0; + goto Exit; + } + else if (VpIsNegZero(m)) { + *d = VpGetDoubleNegZero(); + *e = 0; + f = 0; + goto Exit; + } + else if (VpIsPosInf(m)) { + *d = VpGetDoublePosInf(); + *e = 0; + f = 2; + goto Exit; + } + else if (VpIsNegInf(m)) { + *d = VpGetDoubleNegInf(); + *e = 0; + f = 2; + goto Exit; } /* Normal number */ - fig =(DBLE_FIG + BASE_FIG - 1) / BASE_FIG; + fig = (DBLE_FIG + BASE_FIG - 1) / BASE_FIG; ind_m = 0; - mm = Min(fig,(m->Prec)); + mm = Min(fig, m->Prec); *d = 0.0; div = 1.; - while(ind_m < mm) { - div /= (double)BASE; - *d = *d + (double)m->frac[ind_m++] * div; + while (ind_m < mm) { + div /= (double)BASE; + *d = *d + (double)m->frac[ind_m++] * div; } *e = m->exponent * (SIGNED_VALUE)BASE_FIG; *d *= VpGetSign(m); Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, " VpVtoD: m=%\n", m); - printf(" d=%e * 10 **%ld\n", *d, *e); - printf(" DBLE_FIG = %d\n", DBLE_FIG); + if (gfDebug) { + VPrint(stdout, " VpVtoD: m=%\n", m); + printf(" d=%e * 10 **%ld\n", *d, *e); + printf(" DBLE_FIG = %d\n", DBLE_FIG); } #endif /*BIGDECIMAL_DEBUG */ return f; @@ -5409,57 +5459,58 @@ VpDtoV(Real *m, double d) BDIGIT i; double val, val2; - if(isnan(d)) { - VpSetNaN(m); - goto Exit; + if (isnan(d)) { + VpSetNaN(m); + goto Exit; } - if(isinf(d)) { - if(d>0.0) VpSetPosInf(m); - else VpSetNegInf(m); - goto Exit; + if (isinf(d)) { + if (d > 0.0) VpSetPosInf(m); + else VpSetNegInf(m); + goto Exit; } - if(d == 0.0) { - VpSetZero(m,1); - goto Exit; + if (d == 0.0) { + VpSetZero(m, 1); + goto Exit; } - val =(d > 0.) ? d :(-d); + val = (d > 0.) ? d : -d; ne = 0; - if(val >= 1.0) { - while(val >= 1.0) { - val /= (double)BASE; - ++ne; - } - } else { - val2 = 1.0 /(double)BASE; - while(val < val2) { - val *= (double)BASE; - --ne; - } + if (val >= 1.0) { + while (val >= 1.0) { + val /= (double)BASE; + ++ne; + } + } + else { + val2 = 1.0 / (double)BASE; + while (val < val2) { + val *= (double)BASE; + --ne; + } } /* Now val = 0.xxxxx*BASE**ne */ mm = m->MaxPrec; memset(m->frac, 0, mm * sizeof(BDIGIT)); - for(ind_m = 0;val > 0.0 && ind_m < mm;ind_m++) { - val *= (double)BASE; - i = (BDIGIT)val; - val -= (double)i; - m->frac[ind_m] = i; + for (ind_m = 0; val > 0.0 && ind_m < mm; ind_m++) { + val *= (double)BASE; + i = (BDIGIT)val; + val -= (double)i; + m->frac[ind_m] = i; } - if(ind_m >= mm) ind_m = mm - 1; + if (ind_m >= mm) ind_m = mm - 1; VpSetSign(m, (d > 0.0) ? 1 : -1); m->Prec = ind_m + 1; m->exponent = ne; VpInternalRound(m, 0, (m->Prec > 0) ? m->frac[m->Prec-1] : 0, - (BDIGIT)(val*(double)BASE)); + (BDIGIT)(val*(double)BASE)); Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - printf("VpDtoV d=%30.30e\n", d); - VPrint(stdout, " m=%\n", m); + if (gfDebug) { + printf("VpDtoV d=%30.30e\n", d); + VPrint(stdout, " m=%\n", m); } #endif /* BIGDECIMAL_DEBUG */ return; @@ -5477,51 +5528,52 @@ VpItoV(Real *m, SIGNED_VALUE ival) int isign; SIGNED_VALUE ne; - if(ival == 0) { - VpSetZero(m,1); - goto Exit; + if (ival == 0) { + VpSetZero(m, 1); + goto Exit; } isign = 1; val = ival; - if(ival < 0) { - isign = -1; - val =(size_t)(-ival); + if (ival < 0) { + isign = -1; + val =(size_t)(-ival); } ne = 0; ind_m = 0; mm = m->MaxPrec; - while(ind_m < mm) { - m->frac[ind_m] = 0; - ++ind_m; + while (ind_m < mm) { + m->frac[ind_m] = 0; + ++ind_m; } ind_m = 0; - while(val > 0) { - if(val) { - v1 = val; - v2 = 1; - while(v1 >= BASE) { - v1 /= BASE; - v2 *= BASE; - } - val = val - v2 * v1; - v = v1; - } else { - v = 0; - } - m->frac[ind_m] = v; - ++ind_m; - ++ne; + while (val > 0) { + if (val) { + v1 = val; + v2 = 1; + while (v1 >= BASE) { + v1 /= BASE; + v2 *= BASE; + } + val = val - v2 * v1; + v = v1; + } + else { + v = 0; + } + m->frac[ind_m] = v; + ++ind_m; + ++ne; } m->Prec = ind_m - 1; m->exponent = ne; - VpSetSign(m,isign); + VpSetSign(m, isign); VpNmlz(m); Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - printf(" VpItoV i=%d\n", ival); - VPrint(stdout, " m=%\n", m); + if (gfDebug) { + printf(" VpItoV i=%d\n", ival); + VPrint(stdout, " m=%\n", m); } #endif /* BIGDECIMAL_DEBUG */ return; @@ -5543,26 +5595,26 @@ VpSqrt(Real *y, Real *x) double val; /* Zero, NaN or Infinity ? */ - if(!VpHasVal(x)) { - if(VpIsZero(x)||VpGetSign(x)>0) { - VpAsgn(y,x,1); - goto Exit; - } - VpSetNaN(y); - return VpException(VP_EXCEPTION_OP,"(VpSqrt) SQRT(NaN or negative value)",0); - goto Exit; + if (!VpHasVal(x)) { + if (VpIsZero(x) || VpGetSign(x) > 0) { + VpAsgn(y,x,1); + goto Exit; + } + VpSetNaN(y); + return VpException(VP_EXCEPTION_OP, "(VpSqrt) SQRT(NaN or negative value)", 0); + goto Exit; } - /* Negative ? */ - if(VpGetSign(x) < 0) { - VpSetNaN(y); - return VpException(VP_EXCEPTION_OP,"(VpSqrt) SQRT(negative value)",0); + /* Negative ? */ + if (VpGetSign(x) < 0) { + VpSetNaN(y); + return VpException(VP_EXCEPTION_OP, "(VpSqrt) SQRT(negative value)", 0); } /* One ? */ - if(VpIsOne(x)) { - VpSetOne(y); - goto Exit; + if (VpIsOne(x)) { + VpSetOne(y); + goto Exit; } n = (SIGNED_VALUE)y->MaxPrec; @@ -5584,8 +5636,8 @@ VpSqrt(Real *y, Real *x) e /= (SIGNED_VALUE)BASE_FIG; n = e / 2; if (e - n * 2 != 0) { - val /= BASE; - n = (e + 1) / 2; + val /= BASE; + n = (e + 1) / 2; } VpDtoV(y, sqrt(val)); /* y <- sqrt(val) */ y->exponent += n; @@ -5595,22 +5647,21 @@ VpSqrt(Real *y, Real *x) n = (SIGNED_VALUE)(y_prec * BASE_FIG); if (n < (SIGNED_VALUE)maxnr) n = (SIGNED_VALUE)maxnr; do { - y->MaxPrec *= 2; - if (y->MaxPrec > y_prec) y->MaxPrec = y_prec; - f->MaxPrec = y->MaxPrec; - VpDivd(f, r, x, y); /* f = x/y */ - VpAddSub(r, f, y, -1); /* r = f - y */ - VpMult(f, VpPt5, r); /* f = 0.5*r */ - if(VpIsZero(f)) goto converge; - VpAddSub(r, f, y, 1); /* r = y + f */ - VpAsgn(y, r, 1); /* y = r */ - if(f->exponent <= prec) goto converge; + y->MaxPrec *= 2; + if (y->MaxPrec > y_prec) y->MaxPrec = y_prec; + f->MaxPrec = y->MaxPrec; + VpDivd(f, r, x, y); /* f = x/y */ + VpAddSub(r, f, y, -1); /* r = f - y */ + VpMult(f, VpPt5, r); /* f = 0.5*r */ + if (VpIsZero(f)) goto converge; + VpAddSub(r, f, y, 1); /* r = y + f */ + VpAsgn(y, r, 1); /* y = r */ + if (f->exponent <= prec) goto converge; } while(++nr < n); - /* */ + #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - printf("ERROR(VpSqrt): did not converge within %ld iterations.\n", - nr); + if (gfDebug) { + printf("ERROR(VpSqrt): did not converge within %ld iterations.\n", nr); } #endif /* BIGDECIMAL_DEBUG */ y->MaxPrec = y_prec; @@ -5618,13 +5669,13 @@ VpSqrt(Real *y, Real *x) converge: VpChangeSign(y, 1); #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VpMult(r, y, y); - VpAddSub(f, x, r, -1); - printf("VpSqrt: iterations = %"PRIdSIZE"\n", nr); - VPrint(stdout, " y =% \n", y); - VPrint(stdout, " x =% \n", x); - VPrint(stdout, " x-y*y = % \n", f); + if (gfDebug) { + VpMult(r, y, y); + VpAddSub(f, x, r, -1); + printf("VpSqrt: iterations = %"PRIdSIZE"\n", nr); + VPrint(stdout, " y =% \n", y); + VPrint(stdout, " x =% \n", x); + VPrint(stdout, " x-y*y = % \n", f); } #endif /* BIGDECIMAL_DEBUG */ y->MaxPrec = y_prec; @@ -5660,8 +5711,8 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) exptoadd=0; if (nf < 0) { /* rounding position too left(large). */ - if((f!=VP_ROUND_CEIL) && (f!=VP_ROUND_FLOOR)) { - VpSetZero(y,VpGetSign(y)); /* truncate everything */ + if (f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) { + VpSetZero(y, VpGetSign(y)); /* truncate everything */ return 0; } exptoadd = -nf; @@ -5674,7 +5725,7 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) ioffset = nf - ix*(ssize_t)BASE_FIG; n = (ssize_t)BASE_FIG - ioffset - 1; - for (shifter=1,i=0; ifrac) is an array of BDIGIT, where each BDIGIT contains a value between 0 and BASE-1, consisting of BASE_FIG @@ -5683,20 +5734,25 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) (that numbers of decimal places are typed as ssize_t is somewhat confusing) nf is now position (in decimal places) of the digit from the start of - the array. + the array. + ix is the position (in BDIGITS) of the BDIGIT containing the decimal digit, - from the start of the array. + from the start of the array. + v is the value of this BDIGIT + ioffset is the number of extra decimal places along of this decimal digit - within v. + within v. + n is the number of decimal digits remaining within v after this decimal digit shifter is 10**n, + v % shifter are the remaining digits within v v % (shifter * 10) are the digit together with the remaining digits within v v / shifter are the digit's predecessors together with the digit div = v / shifter / 10 is just the digit's precessors (v / shifter) - div*10 is just the digit, which is what v ends up being reassigned to. - */ + */ fracf = (v % (shifter * 10) > 0); fracf_1further = ((v % shifter) > 0); @@ -5707,7 +5763,7 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) /* now v is just the digit required. now fracf is whether the digit or any of the remaining digits within v are non-zero now fracf_1further is whether any of the remaining digits within v are non-zero - */ + */ /* now check all the remaining BDIGITS for zero-ness a whole BDIGIT at a time. if we spot any non-zeroness, that means that we foudn a positive digit under @@ -5715,7 +5771,7 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) the rounding position, so both searches (to see if any such non-zero digit exists) can stop */ - for (i=ix+1; (size_t)i < y->Prec; i++) { + for (i = ix + 1; (size_t)i < y->Prec; i++) { if (y->frac[i] % BASE) { fracf = fracf_1further = 1; break; @@ -5728,31 +5784,31 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) now v = the first digit under the rounding position */ /* drop digits after pointed digit */ - memset(y->frac+ix+1, 0, (y->Prec - (ix+1)) * sizeof(BDIGIT)); + memset(y->frac + ix + 1, 0, (y->Prec - (ix + 1)) * sizeof(BDIGIT)); - switch(f) { - case VP_ROUND_DOWN: /* Truncate */ - break; - case VP_ROUND_UP: /* Roundup */ - if (fracf) ++div; + switch (f) { + case VP_ROUND_DOWN: /* Truncate */ + break; + case VP_ROUND_UP: /* Roundup */ + if (fracf) ++div; break; - case VP_ROUND_HALF_UP: - if (v>=5) ++div; - break; - case VP_ROUND_HALF_DOWN: + case VP_ROUND_HALF_UP: + if (v>=5) ++div; + break; + case VP_ROUND_HALF_DOWN: if (v > 5 || (v == 5 && fracf_1further)) ++div; - break; - case VP_ROUND_CEIL: - if (fracf && (VpGetSign(y)>0)) ++div; - break; - case VP_ROUND_FLOOR: - if (fracf && (VpGetSign(y)<0)) ++div; - break; - case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + break; + case VP_ROUND_CEIL: + if (fracf && (VpGetSign(y) > 0)) ++div; + break; + case VP_ROUND_FLOOR: + if (fracf && (VpGetSign(y) < 0)) ++div; + break; + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ if (v > 5) ++div; else if (v == 5) { if (fracf_1further) { - ++div; + ++div; } else { if (ioffset == 0) { @@ -5770,32 +5826,34 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf) } break; } - for (i=0; i<=n; ++i) div *= 10; - if (div>=BASE) { - if(ix) { - y->frac[ix] = 0; - VpRdup(y,ix); - } else { - short s = VpGetSign(y); - SIGNED_VALUE e = y->exponent; - VpSetOne(y); - VpSetSign(y, s); - y->exponent = e+1; - } - } else { - y->frac[ix] = div; - VpNmlz(y); + for (i = 0; i <= n; ++i) div *= 10; + if (div >= BASE) { + if (ix) { + y->frac[ix] = 0; + VpRdup(y, ix); + } + else { + short s = VpGetSign(y); + SIGNED_VALUE e = y->exponent; + VpSetOne(y); + VpSetSign(y, s); + y->exponent = e + 1; + } + } + else { + y->frac[ix] = div; + VpNmlz(y); } if (exptoadd > 0) { - y->exponent += (SIGNED_VALUE)(exptoadd/BASE_FIG); - exptoadd %= (ssize_t)BASE_FIG; - for(i=0;ifrac[0] *= 10; - if (y->frac[0] >= BASE) { - y->frac[0] /= BASE; - y->exponent++; - } - } + y->exponent += (SIGNED_VALUE)(exptoadd / BASE_FIG); + exptoadd %= (ssize_t)BASE_FIG; + for (i = 0; i < exptoadd; i++) { + y->frac[0] *= 10; + if (y->frac[0] >= BASE) { + y->frac[0] /= BASE; + y->exponent++; + } + } } return 1; } @@ -5809,10 +5867,10 @@ VpLeftRound(Real *y, unsigned short f, ssize_t nf) BDIGIT v; if (!VpHasVal(y)) return 0; /* Unable to round */ v = y->frac[0]; - nf -= VpExponent(y)*(ssize_t)BASE_FIG; + nf -= VpExponent(y) * (ssize_t)BASE_FIG; while ((v /= 10) != 0) nf--; nf += (ssize_t)BASE_FIG-1; - return VpMidRound(y,f,nf); + return VpMidRound(y, f, nf); } VP_EXPORT int @@ -5820,17 +5878,17 @@ VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf) { /* First,assign whole value in truncation mode */ if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */ - return VpMidRound(y,f,nf); + return VpMidRound(y, f, nf); } static int VpLimitRound(Real *c, size_t ixDigit) { size_t ix = VpGetPrecLimit(); - if(!VpNmlz(c)) return -1; - if(!ix) return 0; - if(!ixDigit) ixDigit = c->Prec-1; - if((ix+BASE_FIG-1)/BASE_FIG > ixDigit+1) return 0; + if (!VpNmlz(c)) return -1; + if (!ix) return 0; + if (!ixDigit) ixDigit = c->Prec-1; + if ((ix + BASE_FIG - 1) / BASE_FIG > ixDigit + 1) return 0; return VpLeftRound(c, VpGetRoundMode(), (ssize_t)ix); } @@ -5848,27 +5906,27 @@ VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v) v /= BASE1; switch (rounding_mode) { - case VP_ROUND_DOWN: + case VP_ROUND_DOWN: break; - case VP_ROUND_UP: + case VP_ROUND_UP: if (v) f = 1; break; - case VP_ROUND_HALF_UP: + case VP_ROUND_HALF_UP: if (v >= 5) f = 1; break; - case VP_ROUND_HALF_DOWN: + case VP_ROUND_HALF_DOWN: /* this is ok - because this is the last digit of precision, the case where v == 5 and some further digits are nonzero will never occur */ if (v >= 6) f = 1; break; - case VP_ROUND_CEIL: + case VP_ROUND_CEIL: if (v && (VpGetSign(c) > 0)) f = 1; break; - case VP_ROUND_FLOOR: + case VP_ROUND_FLOOR: if (v && (VpGetSign(c) < 0)) f = 1; break; - case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ /* as per VP_ROUND_HALF_DOWN, because this is the last digit of precision, there is no case to worry about where v == 5 and some further digits are nonzero */ if (v > 5) f = 1; @@ -5892,16 +5950,17 @@ VpRdup(Real *m, size_t ind_m) if (!ind_m) ind_m = m->Prec; carry = 1; - while (carry > 0 && (ind_m--)) { - m->frac[ind_m] += carry; - if (m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE; - else carry = 0; - } - if(carry > 0) { /* Overflow,count exponent and set fraction part be 1 */ - if (!AddExponent(m, 1)) return 0; - m->Prec = m->frac[0] = 1; - } else { - VpNmlz(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; + } + if (carry > 0) { /* Overflow,count exponent and set fraction part be 1 */ + if (!AddExponent(m, 1)) return 0; + m->Prec = m->frac[0] = 1; + } + else { + VpNmlz(m); } return 1; } @@ -5914,18 +5973,18 @@ VpFrac(Real *y, Real *x) { size_t my, ind_y, ind_x; - if(!VpHasVal(x)) { - VpAsgn(y,x,1); - goto Exit; + if (!VpHasVal(x)) { + VpAsgn(y, x, 1); + goto Exit; } if (x->exponent > 0 && (size_t)x->exponent >= x->Prec) { - VpSetZero(y,VpGetSign(x)); - goto Exit; + VpSetZero(y, VpGetSign(x)); + goto Exit; } - else if(x->exponent <= 0) { - VpAsgn(y, x, 1); - goto Exit; + else if (x->exponent <= 0) { + VpAsgn(y, x, 1); + goto Exit; } /* satisfy: x->exponent > 0 */ @@ -5933,22 +5992,22 @@ VpFrac(Real *y, Real *x) y->Prec = x->Prec - (size_t)x->exponent; y->Prec = Min(y->Prec, y->MaxPrec); y->exponent = 0; - VpSetSign(y,VpGetSign(x)); + VpSetSign(y, VpGetSign(x)); ind_y = 0; my = y->Prec; ind_x = x->exponent; - while(ind_y < my) { - y->frac[ind_y] = x->frac[ind_x]; - ++ind_y; - ++ind_x; + while (ind_y < my) { + y->frac[ind_y] = x->frac[ind_x]; + ++ind_y; + ++ind_x; } VpNmlz(y); Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpFrac y=%\n", y); - VPrint(stdout, " x=%\n", x); + if (gfDebug) { + VPrint(stdout, "VpFrac y=%\n", y); + VPrint(stdout, " x=%\n", x); } #endif /* BIGDECIMAL_DEBUG */ return; @@ -5965,55 +6024,57 @@ VpPower(Real *y, Real *x, SIGNED_VALUE n) Real *w1 = NULL; Real *w2 = NULL; - if(VpIsZero(x)) { - if(n==0) { - VpSetOne(y); - goto Exit; - } - sign = VpGetSign(x); - if(n<0) { - n = -n; - if(sign<0) sign = (n%2)?(-1):(1); - VpSetInf (y,sign); - } else { - if(sign<0) sign = (n%2)?(-1):(1); - VpSetZero(y,sign); - } - goto Exit; + if (VpIsZero(x)) { + if (n == 0) { + VpSetOne(y); + goto Exit; + } + sign = VpGetSign(x); + if (n < 0) { + n = -n; + if (sign < 0) sign = (n % 2) ? -1 : 1; + VpSetInf(y, sign); + } + else { + if (sign < 0) sign = (n % 2) ? -1 : 1; + VpSetZero(y,sign); + } + goto Exit; } - if(VpIsNaN(x)) { - VpSetNaN(y); - goto Exit; + if (VpIsNaN(x)) { + VpSetNaN(y); + goto Exit; } - if(VpIsInf(x)) { - if(n==0) { - VpSetOne(y); - goto Exit; - } - if(n>0) { - VpSetInf(y, (n%2==0 || VpIsPosInf(x)) ? 1 : -1); - goto Exit; - } - VpSetZero(y, (n%2==0 || VpIsPosInf(x)) ? 1 : -1); - goto Exit; + if (VpIsInf(x)) { + if (n == 0) { + VpSetOne(y); + goto Exit; + } + if (n > 0) { + VpSetInf(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1); + goto Exit; + } + VpSetZero(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1); + goto Exit; } - if((x->exponent == 1) &&(x->Prec == 1) &&(x->frac[0] == 1)) { - /* abs(x) = 1 */ - VpSetOne(y); - if(VpGetSign(x) > 0) goto Exit; - if((n % 2) == 0) goto Exit; - VpSetSign(y, -1); - goto Exit; + if (x->exponent == 1 && x->Prec == 1 && x->frac[0] == 1) { + /* abs(x) = 1 */ + VpSetOne(y); + if (VpGetSign(x) > 0) goto Exit; + if ((n % 2) == 0) goto Exit; + VpSetSign(y, -1); + goto Exit; } - if(n > 0) sign = 1; - else if(n < 0) { - sign = -1; - n = -n; - } else { - VpSetOne(y); - goto Exit; + if (n > 0) sign = 1; + else if (n < 0) { + sign = -1; + n = -n; + } + else { + VpSetOne(y); + goto Exit; } /* Allocate working variables */ @@ -6024,28 +6085,28 @@ VpPower(Real *y, Real *x, SIGNED_VALUE n) VpAsgn(y, x, 1); --n; - while(n > 0) { - VpAsgn(w1, x, 1); - s = 1; + while (n > 0) { + VpAsgn(w1, x, 1); + s = 1; while (ss = s, (s += s) <= (size_t)n) { VpMult(w2, w1, w1); VpAsgn(w1, w2, 1); } - n -= (SIGNED_VALUE)ss; - VpMult(w2, y, w1); - VpAsgn(y, w2, 1); + n -= (SIGNED_VALUE)ss; + VpMult(w2, y, w1); + VpAsgn(y, w2, 1); } - if(sign < 0) { - VpDivd(w1, w2, VpConstOne, y); - VpAsgn(y, w1, 1); + if (sign < 0) { + VpDivd(w1, w2, VpConstOne, y); + VpAsgn(y, w1, 1); } Exit: #ifdef BIGDECIMAL_DEBUG - if(gfDebug) { - VPrint(stdout, "VpPower y=%\n", y); - VPrint(stdout, "VpPower x=%\n", x); - printf(" n=%d\n", n); + if (gfDebug) { + VPrint(stdout, "VpPower y=%\n", y); + VPrint(stdout, "VpPower x=%\n", x); + printf(" n=%d\n", n); } #endif /* BIGDECIMAL_DEBUG */ VpFree(w2); @@ -6067,25 +6128,25 @@ VpVarCheck(Real * v) { size_t i; - if(v->MaxPrec <= 0) { - printf("ERROR(VpVarCheck): Illegal Max. Precision(=%"PRIuSIZE")\n", - v->MaxPrec); - return 1; - } - if((v->Prec <= 0) ||((v->Prec) >(v->MaxPrec))) { - printf("ERROR(VpVarCheck): Illegal Precision(=%"PRIuSIZE")\n", v->Prec); - printf(" Max. Prec.=%"PRIuSIZE"\n", v->MaxPrec); - return 2; - } - for(i = 0; i < v->Prec; ++i) { - if((v->frac[i] >= BASE)) { - printf("ERROR(VpVarCheck): Illegal fraction\n"); - printf(" Frac[%"PRIuSIZE"]=%lu\n", i, v->frac[i]); - printf(" Prec. =%"PRIuSIZE"\n", v->Prec); - printf(" Exp. =%"PRIdVALUE"\n", v->exponent); - printf(" BASE =%lu\n", BASE); - return 3; - } + if (v->MaxPrec <= 0) { + printf("ERROR(VpVarCheck): Illegal Max. Precision(=%"PRIuSIZE")\n", + v->MaxPrec); + return 1; + } + if (v->Prec <= 0 || v->Prec > v->MaxPrec) { + printf("ERROR(VpVarCheck): Illegal Precision(=%"PRIuSIZE")\n", v->Prec); + printf(" Max. Prec.=%"PRIuSIZE"\n", v->MaxPrec); + return 2; + } + for (i = 0; i < v->Prec; ++i) { + if (v->frac[i] >= BASE) { + printf("ERROR(VpVarCheck): Illegal fraction\n"); + printf(" Frac[%"PRIuSIZE"]=%lu\n", i, v->frac[i]); + printf(" Prec. =%"PRIuSIZE"\n", v->Prec); + printf(" Exp. =%"PRIdVALUE"\n", v->exponent); + printf(" BASE =%lu\n", BASE); + return 3; + } } return 0; } -- cgit v1.2.3