From 15c3df744f228f3d967ca624533d17f491555e93 Mon Sep 17 00:00:00 2001 From: shigek Date: Mon, 21 Jul 2003 14:49:25 +0000 Subject: patches from T.Saito etc. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4108 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/bigdecimal/bigdecimal.c | 43 +++++++++++++++++++++++---------------- ext/bigdecimal/bigdecimal_en.html | 1 + ext/bigdecimal/bigdecimal_ja.html | 1 + 3 files changed, 28 insertions(+), 17 deletions(-) (limited to 'ext/bigdecimal') diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 8f86108e4f..62078b9e53 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -254,7 +254,7 @@ BigDecimal_load(VALUE self, VALUE str) pch = RSTRING(str)->ptr; /* First get max prec */ while((*pch)!=(unsigned char)'\0' && (ch=*pch++)!=(unsigned char)':') { - if(ch<'0' || ch>'9') { + if(!ISDIGIT(ch)) { rb_raise(rb_eTypeError, "Load failed: invalid character in the marshaled string"); } m = m*10 + (unsigned long)(ch-'0'); @@ -325,7 +325,7 @@ GetPositiveInt(VALUE v) Check_Type(v, T_FIXNUM); n = FIX2INT(v); if(n <= 0) { - rb_fatal("Zero or negative argument not permitted."); + rb_raise(rb_eArgError, "argument must be positive"); } return n; } @@ -384,7 +384,17 @@ BigDecimal_to_i(VALUE self) GUARD_OBJ(p,GetVpValue(self,1)); - if(!VpIsDef(p)) return Qnil; /* Infinity or NaN not converted. */ + /* Infinity or NaN not converted. */ + if(VpIsNaN(p)) { + VpException(VP_EXCEPTION_NaN,"Computation results to 'NaN'(Not a Number)",0); + return Qnil; + } else if(VpIsPosInf(p)) { + VpException(VP_EXCEPTION_INFINITY,"Computation results to 'Infinity'",0); + return Qnil; + } else if(VpIsNegInf(p)) { + VpException(VP_EXCEPTION_INFINITY,"Computation results to '-Infinity'",0); + return Qnil; + } e = VpExponent10(p); if(e<=0) return INT2FIX(0); @@ -431,19 +441,17 @@ BigDecimal_to_f(VALUE self) { ENTER(1); Real *p; - double d, d2, da; + double d, d2; S_LONG e; GUARD_OBJ(p,GetVpValue(self,1)); if(VpVtoD(&d, &e, p)!=1) return rb_float_new(d); errno = 0; d2 = pow(10.0,(double)e); - da = fabs(d); - if(errno == ERANGE || da > (DBL_MAX / d2) || da < (DBL_MIN / d2)) { - U_LONG nc = VpNumOfChars(p)+1; - char *psz = ALLOCA_N(char, nc); - VpToString(p, psz, 0); - rb_raise(rb_eRangeError, "BigDecimal %s out of Float range", psz); + if((errno == ERANGE && e>0) || (d2>1.0 && (fabs(d) > (DBL_MAX / d2)))) { + VpException(VP_EXCEPTION_OVERFLOW,"BigDecimal to Float conversion.",0); + if(d>0.0) return rb_float_new(DBL_MAX); + else return rb_float_new(-DBL_MAX); } return rb_float_new(d*d2); } @@ -1955,7 +1963,7 @@ overflow: VP_EXPORT Real * VpAlloc(U_LONG mx, char *szVal) { - U_LONG i, ni, ipf, nf, ipe, ne, nalloc; + U_LONG i, ni, ipn, ipf, nf, ipe, ne, nalloc; char v; int sign=1; Real *vp = NULL; @@ -2007,12 +2015,13 @@ VpAlloc(U_LONG mx, char *szVal) /* check on number szVal[] */ i = SkipWhiteChar(szVal); - if (szVal[i] == '-') {sign=-1;++i;} - else if(szVal[i] == '+') ++i; + ipn = i; + if (szVal[i] == '-') {sign=-1;++i;} + else if(szVal[i] == '+') ++i; /* Skip digits */ ni = 0; /* digits in mantissa */ while(v = szVal[i]) { - if((v > '9') ||(v < '0')) break; + if(!ISDIGIT(v)) break; ++i; ++ni; } @@ -2026,7 +2035,7 @@ VpAlloc(U_LONG mx, char *szVal) ++i; ipf = i; while(v = szVal[i]) { /* get fraction part. */ - if((v > '9') ||(v < '0')) break; + if(!ISDIGIT(v)) break; ++i; ++nf; } @@ -2061,7 +2070,7 @@ VpAlloc(U_LONG mx, char *szVal) /* xmalloc() alway returns(or throw interruption) */ vp->MaxPrec = mx; /* set max precision */ VpSetZero(vp,sign); - VpCtoV(vp, szVal, ni, &(szVal[ipf]), nf, &(szVal[ipe]), ne); + VpCtoV(vp, &(szVal[ipn]), ni, &(szVal[ipf]), nf, &(szVal[ipe]), ne); return vp; } @@ -2868,7 +2877,6 @@ out_side: goto Exit; space_error: - rb_fatal("ERROR(VpDivd): space for remainder too small.\n"); #ifdef _DEBUG if(gfDebug) { printf(" word_a=%lu\n", word_a); @@ -2878,6 +2886,7 @@ space_error: printf(" ind_r =%lu\n", ind_r); } #endif /* _DEBUG */ + rb_bug("ERROR(VpDivd): space for remainder too small."); Exit: #ifdef _DEBUG diff --git a/ext/bigdecimal/bigdecimal_en.html b/ext/bigdecimal/bigdecimal_en.html index 5344720adc..5b157101a1 100644 --- a/ext/bigdecimal/bigdecimal_en.html +++ b/ext/bigdecimal/bigdecimal_en.html @@ -108,6 +108,7 @@ where:
s: Initial value string.
n: Maximum number of significant digits of a. n must be a Fixnum object. If n is omitted or is equal to 0,then the maximum number of significant digits of a is determined from the length of s. +Currently, n has no actual meaning(reserved for future use).
  • mode
  • diff --git a/ext/bigdecimal/bigdecimal_ja.html b/ext/bigdecimal/bigdecimal_ja.html index caa1326c92..cd77def397 100644 --- a/ext/bigdecimal/bigdecimal_ja.html +++ b/ext/bigdecimal/bigdecimal_ja.html @@ -118,6 +118,7 @@ n n が 0 または省略されたときは、n の値は s の有効桁数とみなされます。 s の有効桁数より n が小さいときも n=0 のときと同じです。 a の最大有効桁数は n より若干大い値が採用されます。 +現時点では n を指定しても余り意味がありません(予約)。
  • mode
  • -- cgit v1.2.3