1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

to_s("+") implemented.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4412 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shigek 2003-08-19 14:21:13 +00:00
parent caf213d9ad
commit 62acad914e
5 changed files with 103 additions and 497 deletions

View file

@ -1,3 +1,9 @@
Tue Aug 19 23:20:00 2003 Shigeo Kobayashi <shigek@ruby-lang.org>
* ext/bigdecimal/bigdecimal.c .h .html: to_s("+") implemented.
* ext/bigdecimal/lib/bigdecimal/math.rb: E implemented.
Tue Aug 19 07:47:09 2003 GOTOU Yuuzou <gotoyuzo@notwork.org> Tue Aug 19 07:47:09 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* lib/webrick/ssl.rb: new file; SSL/TLS enhancement for GenericServer. * lib/webrick/ssl.rb: new file; SSL/TLS enhancement for GenericServer.

View file

@ -25,7 +25,6 @@
#include "version.h" #include "version.h"
/* #define ENABLE_NUMERIC_STRING */ /* #define ENABLE_NUMERIC_STRING */
/* #define ENABLE_TRIAL_METHOD */
VALUE rb_cBigDecimal; VALUE rb_cBigDecimal;
@ -182,7 +181,7 @@ BigDecimal_dump(int argc, VALUE *argv, VALUE self)
sprintf(sz,"%lu:",VpMaxPrec(vp)*VpBaseFig()); sprintf(sz,"%lu:",VpMaxPrec(vp)*VpBaseFig());
psz = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E")+strlen(sz)); psz = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E")+strlen(sz));
sprintf(psz,"%s",sz); sprintf(psz,"%s",sz);
VpToString(vp, psz+strlen(psz), 0); VpToString(vp, psz+strlen(psz), 0, 0);
return rb_str_new2(psz); return rb_str_new2(psz);
} }
@ -1042,9 +1041,11 @@ static VALUE
BigDecimal_to_s(int argc, VALUE *argv, VALUE self) BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
{ {
ENTER(5); ENTER(5);
int fmt=0; /* 0:E format */ int fmt=0; /* 0:E format */
int fPlus=0; /* =0:default,=1: set ' ' before digits ,set '+' before digits. */
Real *vp; Real *vp;
char *psz; char *psz;
char *psz2;
char ch; char ch;
U_LONG nc; U_LONG nc;
S_INT mc = 0; S_INT mc = 0;
@ -1056,7 +1057,13 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
if(TYPE(f)==T_STRING) { if(TYPE(f)==T_STRING) {
SafeStringValue(f); SafeStringValue(f);
psz = RSTRING(f)->ptr; psz = RSTRING(f)->ptr;
if(*psz==' ') {
fPlus = 1; psz++;
} else if(*psz=='+') {
fPlus = 2; psz++;
}
while(ch=*psz++) { while(ch=*psz++) {
if(ISSPACE(ch)) continue;
if(!ISDIGIT(ch)) { if(!ISDIGIT(ch)) {
if(ch=='F' || ch=='f') fmt = 1; /* F format */ if(ch=='F' || ch=='f') fmt = 1; /* F format */
break; break;
@ -1066,20 +1073,20 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
} else { } else {
mc = GetPositiveInt(f); mc = GetPositiveInt(f);
} }
if(fmt) {
nc = VpNumOfChars(vp,"F");
} else {
nc = VpNumOfChars(vp,"E");
}
if(mc>0) nc += (nc + mc - 1) / mc + 1;
} }
if(fmt) {
nc = VpNumOfChars(vp,"F");
} else {
nc = VpNumOfChars(vp,"E");
}
if(mc>0) nc += (nc + mc - 1) / mc + 1;
psz = ALLOCA_N(char,(unsigned int)nc); psz = ALLOCA_N(char,(unsigned int)nc);
if(fmt) { if(fmt) {
VpToFString(vp, psz, mc); VpToFString(vp, psz, mc, fPlus);
} else { } else {
VpToString (vp, psz, mc); VpToString (vp, psz, mc, fPlus);
} }
return rb_str_new2(psz); return rb_str_new2(psz);
} }
@ -1135,7 +1142,7 @@ BigDecimal_inspect(VALUE self)
psz1 = ALLOCA_N(char,nc); psz1 = ALLOCA_N(char,nc);
pszAll = ALLOCA_N(char,nc+256); pszAll = ALLOCA_N(char,nc+256);
VpToString(vp, psz1, 10); VpToString(vp, psz1, 10, 0);
sprintf(pszAll,"#<BigDecimal:%lx,'%s',%lu(%lu)>",self,psz1,VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig()); sprintf(pszAll,"#<BigDecimal:%lx,'%s',%lu(%lu)>",self,psz1,VpPrec(vp)*VpBaseFig(),VpMaxPrec(vp)*VpBaseFig());
obj = rb_str_new2(pszAll); obj = rb_str_new2(pszAll);
return obj; return obj;
@ -1229,72 +1236,6 @@ BigDecimal_sign(VALUE self)
return INT2FIX(s); return INT2FIX(s);
} }
#ifdef ENABLE_TRIAL_METHOD
static VALUE
BigDecimal_e(VALUE self, VALUE nFig)
{
ENTER(5);
Real *pv;
S_LONG mf;
mf = GetPositiveInt(nFig);
GUARD_OBJ(pv,VpCreateRbObject(mf, "0"));
VpExp1(pv);
return ToValue(pv);
}
static VALUE
BigDecimal_pi(VALUE self, VALUE nFig)
{
ENTER(5);
Real *pv;
S_LONG mf;
mf = GetPositiveInt(nFig)+VpBaseFig()-1;
GUARD_OBJ(pv,VpCreateRbObject(mf, "0"));
VpPi(pv);
return ToValue(pv);
}
static VALUE
BigDecimal_exp(VALUE self, VALUE nFig)
{
ENTER(5);
Real *c, *y;
S_LONG mf;
GUARD_OBJ(y,GetVpValue(self,1));
mf = GetPositiveInt(nFig);
GUARD_OBJ(c,VpCreateRbObject(mf, "0"));
VpExp(c, y);
return ToValue(c);
}
static VALUE
BigDecimal_sincos(VALUE self, VALUE nFig)
{
ENTER(5);
VALUE obj;
VALUE objSin;
VALUE objCos;
Real *pcos, *psin, *y;
S_LONG mf;
obj = rb_ary_new();
GUARD_OBJ(y,GetVpValue(self,1));
mf = GetPositiveInt(nFig);
GUARD_OBJ(pcos,VpCreateRbObject(mf, "0"));
GUARD_OBJ(psin,VpCreateRbObject(mf, "0"));
VpSinCos(psin, pcos, y);
objSin = ToValue(psin);
objCos = ToValue(pcos);
rb_ary_push(obj, objSin);
rb_ary_push(obj, objCos);
return obj;
}
#endif /* ENABLE_TRIAL_METHOD */
void void
Init_bigdecimal(void) Init_bigdecimal(void)
{ {
@ -1399,13 +1340,6 @@ Init_bigdecimal(void)
rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0); rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0);
rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1); rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1);
rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1); rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1);
#ifdef ENABLE_TRIAL_METHOD
rb_define_singleton_method(rb_cBigDecimal, "E", BigDecimal_e, 1);
rb_define_singleton_method(rb_cBigDecimal, "PI", BigDecimal_pi, 1);
rb_define_method(rb_cBigDecimal, "exp", BigDecimal_exp, 1);
rb_define_method(rb_cBigDecimal, "sincos", BigDecimal_sincos, 1);
#endif /* ENABLE_TRIAL_METHOD */
} }
/* /*
@ -1450,7 +1384,6 @@ static U_LONG VpSetPTR(Real *a,Real *b,Real *c,U_LONG *a_pos,U_LONG *b_pos,U_LON
static int VpNmlz(Real *a); static int VpNmlz(Real *a);
static void VpFormatSt(char *psz,S_INT fFmt); static void VpFormatSt(char *psz,S_INT fFmt);
static int VpRdup(Real *m,U_LONG ind_m); static int VpRdup(Real *m,U_LONG ind_m);
static U_LONG SkipWhiteChar(char *szVal);
#ifdef _DEBUG #ifdef _DEBUG
static int gnAlloc=0; /* Memory allocation counter */ static int gnAlloc=0; /* Memory allocation counter */
@ -1937,12 +1870,14 @@ VP_EXPORT Real *
VpAlloc(U_LONG mx, char *szVal) VpAlloc(U_LONG mx, char *szVal)
{ {
U_LONG i, ni, ipn, ipf, nf, ipe, ne, nalloc; U_LONG i, ni, ipn, ipf, nf, ipe, ne, nalloc;
char v; char v,*psz;
int sign=1; int sign=1;
Real *vp = NULL; Real *vp = NULL;
U_LONG mf = VpGetPrecLimit(); U_LONG mf = VpGetPrecLimit();
mx = (mx + BASE_FIG - 1) / BASE_FIG + 1; /* Determine allocation unit. */ mx = (mx + BASE_FIG - 1) / BASE_FIG + 1; /* Determine allocation unit. */
if(szVal) { if(szVal) {
while(ISSPACE(*szVal)) szVal++;
if(*szVal!='#') { if(*szVal!='#') {
if(mf) { if(mf) {
mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */ mf = (mf + BASE_FIG - 1) / BASE_FIG + 2; /* Needs 1 more for div */
@ -1953,18 +1888,27 @@ VpAlloc(U_LONG mx, char *szVal)
} else { } else {
++szVal; ++szVal;
} }
} else {
/* necessary to be able to store */
/* at least mx digits. */
/* szVal==NULL ==> allocate zero value. */
vp = (Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(U_LONG));
/* 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 */ /* Skip all spaces */
/* at least mx digits. */ psz = ALLOCA_N(char,strlen(szVal)+1);
if(szVal == NULL) { i = 0;
/* szVal==NULL ==> allocate zero value. */ ipn = 0;
vp = (Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(U_LONG)); while(psz[i]=szVal[ipn]) {
/* xmalloc() alway returns(or throw interruption) */ if(ISSPACE(szVal[ipn])) {ipn++;continue;}
vp->MaxPrec = mx; /* set max precision */ ++i; ++ipn;
VpSetZero(vp,1); /* initialize vp to zero. */
return vp;
} }
szVal = psz;
/* Check on Inf & NaN */ /* Check on Inf & NaN */
if(StrCmp(szVal,SZ_PINF)==0 || if(StrCmp(szVal,SZ_PINF)==0 ||
StrCmp(szVal,SZ_INF)==0 ) { StrCmp(szVal,SZ_INF)==0 ) {
@ -1987,8 +1931,7 @@ VpAlloc(U_LONG mx, char *szVal)
} }
/* check on number szVal[] */ /* check on number szVal[] */
i = SkipWhiteChar(szVal); ipn = i = 0;
ipn = i;
if (szVal[i] == '-') {sign=-1;++i;} if (szVal[i] == '-') {sign=-1;++i;}
else if(szVal[i] == '+') ++i; else if(szVal[i] == '+') ++i;
/* Skip digits */ /* Skip digits */
@ -2025,7 +1968,8 @@ VpAlloc(U_LONG mx, char *szVal)
ipe = i; ipe = i;
v = szVal[i]; v = szVal[i];
if((v == '-') ||(v == '+')) ++i; if((v == '-') ||(v == '+')) ++i;
while(szVal[i]) { while(v=szVal[i]) {
if(!ISDIGIT(v)) break;
++i; ++i;
++ne; ++ne;
} }
@ -3129,8 +3073,8 @@ VpFormatSt(char *psz,S_INT fFmt)
for(i = 0; i < ie; ++i) { for(i = 0; i < ie; ++i) {
ch = psz[i]; ch = psz[i];
if(!ch) break; if(!ch) break;
if(ch=='-' || ch=='+') continue; if(ISSPACE(ch) || ch=='-' || ch=='+') continue;
if(ch == '.') { nf = 0;continue;} if(ch == '.') { nf = 0;continue;}
if(ch == 'E') break; if(ch == 'E') break;
nf++; nf++;
if(nf > fFmt) { if(nf > fFmt) {
@ -3206,13 +3150,20 @@ VpSzMantissa(Real *a,char *psz)
} }
VP_EXPORT int VP_EXPORT int
VpToSpecialString(Real *a,char *psz) VpToSpecialString(Real *a,char *psz,int fPlus)
/* fPlus =0:default, =1: set ' ' before digits , =2: set '+' before digits. */
{ {
if(VpIsNaN(a)) { if(VpIsNaN(a)) {
sprintf(psz,SZ_NaN); sprintf(psz,SZ_NaN);
return 1; return 1;
} }
if(VpIsPosInf(a)) { if(VpIsPosInf(a)) {
if(fPlus==1) {
*psz++ = ' ';
} else if(fPlus==2) {
*psz++ = '+';
}
sprintf(psz,SZ_INF); sprintf(psz,SZ_INF);
return 1; return 1;
} }
@ -3221,26 +3172,33 @@ VpToSpecialString(Real *a,char *psz)
return 1; return 1;
} }
if(VpIsZero(a)) { if(VpIsZero(a)) {
if(VpIsPosZero(a)) sprintf(psz, "0.0"); if(VpIsPosZero(a)) {
else sprintf(psz, "-0.0"); 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 1;
} }
return 0; return 0;
} }
VP_EXPORT void VP_EXPORT void
VpToString(Real *a,char *psz,int fFmt) VpToString(Real *a,char *psz,int fFmt,int fPlus)
/* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */
{ {
U_LONG i, ZeroSup; U_LONG i, ZeroSup;
U_LONG n, m, e, nn; U_LONG n, m, e, nn;
char *pszSav = psz; char *pszSav = psz;
S_LONG ex; S_LONG ex;
if(VpToSpecialString(a,psz)) return; if(VpToSpecialString(a,psz,fPlus)) return;
ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
if(VpGetSign(a) < 0) *psz++ = '-'; if(VpGetSign(a) < 0) *psz++ = '-';
else if(fPlus==1) *psz++ = ' ';
else if(fPlus==2) *psz++ = '+';
*psz++ = '0'; *psz++ = '0';
*psz++ = '.'; *psz++ = '.';
n = a->Prec; n = a->Prec;
@ -3271,16 +3229,20 @@ VpToString(Real *a,char *psz,int fFmt)
} }
VP_EXPORT void VP_EXPORT void
VpToFString(Real *a,char *psz,int fFmt) VpToFString(Real *a,char *psz,int fFmt,int fPlus)
/* fPlus =0:default,=1: set ' ' before digits ,set '+' before digits. */
{ {
U_LONG i; U_LONG i;
U_LONG n, m, e, nn; U_LONG n, m, e, nn;
char *pszSav = psz; char *pszSav = psz;
S_LONG ex; S_LONG ex;
if(VpToSpecialString(a,psz)) return; if(VpToSpecialString(a,psz,fPlus)) return;
if(VpGetSign(a) < 0) *psz++ = '-'; if(VpGetSign(a) < 0) *psz++ = '-';
else if(fPlus==1) *psz++ = ' ';
else if(fPlus==2) *psz++ = '+';
n = a->Prec; n = a->Prec;
ex = a->exponent; ex = a->exponent;
if(ex<=0) { if(ex<=0) {
@ -4068,296 +4030,6 @@ Exit:
return 1; return 1;
} }
#ifdef ENABLE_TRIAL_METHOD
/*
* Calculates pi(=3.141592653589793238462........).
*/
VP_EXPORT void
VpPi(Real *y)
{
Real *n, *n25, *n956, *n57121;
Real *r, *f, *t;
U_LONG p;
U_LONG nc;
U_LONG i1,i2;
p = y->MaxPrec *(BASE_FIG + 2) + 2;
if(p<maxnr) nc = maxnr;
else nc = p;
/* allocate temporally variables */
r = VpAlloc(p * 2, "#0");
f = VpAlloc(p, "#0");
t = VpAlloc(p, "#-80");
n = VpAlloc((U_LONG)10, "1");
n25 = VpAlloc((U_LONG)2, "-0.04"); /*-25");*/
n956 = VpAlloc((U_LONG)3, "956");
n57121 = VpAlloc((U_LONG)5, "-57121");
VpSetZero(y,1); /* y = 0 */
i1 = 0;
do {
++i1;
/* VpDivd(f, r, t, n25); */ /* f = t/(-25) */
VpMult(f,t,n25);
VpAsgn(t, f, 1); /* t = f */
VpDivd(f, r, t, n); /* f = t/n */
VpAddSub(r, y, f, 1); /* r = y + f */
VpAsgn(y, r, 1); /* y = r */
VpRdup(n,0); /* n = n + 1 */
VpRdup(n,0); /* n = n + 1 */
if(VpIsZero(f)) break;
} while((f->exponent > 0 || ((U_LONG)(-(f->exponent)) < y->MaxPrec)) &&
i1<nc
);
VpSetOne(n);
VpAsgn(t, n956,1);
i2 = 0;
do {
++i2;
VpDivd(f, r, t, n57121); /* f = t/(-57121) */
VpAsgn(t, f, 1); /* t = f */
VpDivd(f, r, t, n); /* f = t/n */
VpAddSub(r, y, f, 1); /* r = y + f */
VpAsgn(y, r, 1); /* y = r */
VpRdup(n,0); /* n = n + 1 */
VpRdup(n,0); /* n = n + 1 */
if(VpIsZero(f)) break;
} while((f->exponent > 0 || ((U_LONG)(-(f->exponent)) < y->MaxPrec)) &&
i2<nc
);
VpFree(n);
VpFree(n25);
VpFree(n956);
VpFree(n57121);
VpFree(t);
VpFree(f);
VpFree(r);
#ifdef _DEBUG
printf("VpPi: # of iterations=%lu+%lu\n",i1,i2);
#endif /* _DEBUG */
}
/*
* Calculates the value of e(=2.18281828459........).
* [Output] *y ... Real , the value of e.
*
* y = e
*/
VP_EXPORT void
VpExp1(Real *y)
{
Real *n, *r, *f, *add;
U_LONG p;
U_LONG nc;
U_LONG i;
p = y->MaxPrec*(BASE_FIG + 2) + 2;
if(p<maxnr) nc = maxnr;
else nc = p;
/* allocate temporally variables */
r = VpAlloc(p *(BASE_FIG + 2), "#0");
f = VpAlloc(p, "#1");
n = VpAlloc(p, "#1"); /* n = 1 */
add = VpAlloc(p, "#1"); /* add = 1 */
VpSetOne(y); /* y = 1 */
VpRdup(y,0); /* y = y + 1 */
i = 0;
do {
++i;
VpRdup(n,0); /* n = n + 1 */
VpDivd(f, r, add, n); /* f = add/n(=1/n!) */
VpAsgn(add, f, 1); /* add = 1/n! */
VpAddSub(r, y, f, 1);
VpAsgn(y, r, 1); /* y = y + 1/n! */
} while((f->exponent > 0 || ((U_LONG)(-(f->exponent)) <= y->MaxPrec)) &&
i<nc
);
#ifdef _DEBUG
if(gfDebug) {
VPrint(stdout, "vpexp e=%\n", y);
printf(" r=%d\n", f[3]);
}
#endif /* _DEBUG */
VpFree(add);
VpFree(n);
VpFree(f);
VpFree(r);
}
/*
* Calculates y=e**x where e(=2.18281828459........).
*/
VP_EXPORT void
VpExp(Real *y, Real *x)
{
Real *z=NULL, *div=NULL, *n=NULL, *r=NULL, *c=NULL;
U_LONG p;
U_LONG nc;
U_LONG i;
short fNeg=0;
if(!VpIsDef(x)) {
VpSetNaN(y); /* Not sure */
goto Exit;
}
if(VpIsZero(x)) {
VpSetOne(y);
goto Exit;
}
p = y->MaxPrec;
if(p < x->Prec) p = x->Prec;
p = p *(BASE_FIG + 2) + 2;
if(p<maxnr) nc = maxnr;
else nc = p;
fNeg = x->sign;
if(fNeg<0) x->sign = -fNeg;
/* allocate temporally variables */
z = VpAlloc(p, "#1");
div = VpAlloc(p, "#1");
r = VpAlloc(p * 2, "#0");
c = VpAlloc(p, "#0");
n = VpAlloc(p, "#1"); /* n = 1 */
VpSetOne(r); /* y = 1 */
VpAddSub(y, r, x, 1); /* y = 1 + x/1 */
VpAsgn(z, x, 1); /* z = x/1 */
i = 0;
do {
++i;
VpRdup(n,0); /* n = n + 1 */
VpDivd(div, r, x, n); /* div = x/n */
VpMult(c, z, div); /* c = x/(n-1)! * x/n */
VpAsgn(z, c, 1); /* z = x*n/n! */
VpAsgn(r, y, 1); /* Save previous val. */
VpAddSub(div, y, z, 1); /* */
VpAddSub(c, div, r, -1); /* y = y(new) - y(prev) */
VpAsgn(y, div, 1); /* y = y(new) */
} while(((!VpIsZero(c)) &&(c->exponent >= 0 ||((U_LONG)(-c->exponent)) <= y->MaxPrec)) &&
i<nc
);
if(fNeg < 0) {
x->sign = fNeg;
VpDivd(div, r, VpConstOne, y);
VpAsgn(y, div, 1);
}
Exit:
#ifdef _DEBUG
if(gfDebug) {
VPrint(stdout, "vpexp e=%\n", y);
}
#endif /* _DEBUG */
VpFree(div);
VpFree(n);
VpFree(c);
VpFree(r);
VpFree(z);
}
VP_EXPORT void
VpSinCos(Real *psin,Real *pcos,Real *x)
/*
* Calculates sin(x) & cos(x)
*(Assumes psin->MaxPrec==pcos->MaxPrec)
*/
{
Real *z=NULL, *div=NULL, *n=NULL, *r=NULL, *c=NULL;
U_LONG p;
int fcos;
int fsin;
int which;
U_LONG nc;
U_LONG i;
if(!VpIsDef(x)) {
VpSetNaN(psin);
VpSetNaN(pcos);
goto Exit;
}
p = pcos->MaxPrec;
if(p < x->Prec) p = x->Prec;
p = p *(BASE_FIG + 2) + 2;
if(p<maxnr) nc = maxnr;
else nc = p;
/* allocate temporally variables */
z = VpAlloc(p, "#1");
div = VpAlloc(p, "#1");
r = VpAlloc(p * 2, "#0");
c = VpAlloc(p , "#0");
n = VpAlloc(p, "#1"); /* n = 1 */
VpSetOne(pcos); /* cos = 1 */
VpAsgn(psin, x, 1); /* sin = x/1 */
VpAsgn(z, x, 1); /* z = x/1 */
fcos = 1;
fsin = 1;
which = 1;
i = 0;
do {
++i;
VpRdup(n,0); /* n = n + 1 */
VpDivd(div, r, x, n); /* div = x/n */
VpMult(c, z, div); /* c = x/(n-1)! * x/n */
VpAsgn(z, c, 1); /* z = x*n/n! */
if(which) {
/* COS */
which = 0;
fcos *= -1;
VpAsgn(r, pcos, 1); /* Save previous val. */
VpAddSub(div, pcos, z, fcos); /* */
VpAddSub(c, div, r, -1); /* cos = cos(new) - cos(prev) */
VpAsgn(pcos, div, 1); /* cos = cos(new) */
} else {
/* SIN */
which = 1;
fsin *= -1;
VpAsgn(r, psin, 1); /* Save previous val. */
VpAddSub(div, psin, z, fsin); /* */
VpAddSub(c, div, r, -1); /* sin = sin(new) - sin(prev) */
VpAsgn(psin, div, 1); /* sin = sin(new) */
}
} while(((!VpIsZero(c)) &&(c->exponent >= 0 || ((U_LONG)(-c->exponent)) <= pcos->MaxPrec)) &&
i<nc
);
Exit:
#ifdef _DEBUG
if(gfDebug) {
VPrint(stdout, "cos=%\n", pcos);
VPrint(stdout, "sin=%\n", psin);
}
#endif /* _DEBUG */
VpFree(div);
VpFree(n);
VpFree(c);
VpFree(r);
VpFree(z);
}
#endif /* ENABLE_TRIAL_METHOD */
#ifdef _DEBUG #ifdef _DEBUG
int int
VpVarCheck(Real * v) VpVarCheck(Real * v)
@ -4395,15 +4067,3 @@ VpVarCheck(Real * v)
return 0; return 0;
} }
#endif /* _DEBUG */ #endif /* _DEBUG */
static U_LONG
SkipWhiteChar(char *szVal)
{
char ch;
U_LONG i = 0;
while(ch = szVal[i++]) {
if(ISSPACE(ch)) continue;
break;
}
return i - 1;
}

View file

@ -26,7 +26,7 @@ extern "C" {
#define SZ_NaN "NaN" #define SZ_NaN "NaN"
#define SZ_INF "Infinity" #define SZ_INF "Infinity"
#define SZ_PINF "+Infinity" #define SZ_PINF "+Infinity"
#define SZ_NINF "+Infinity" #define SZ_NINF "-Infinity"
/* /*
* #define VP_EXPORT other than static to let VP_ routines * #define VP_EXPORT other than static to let VP_ routines
@ -140,9 +140,9 @@ VP_EXPORT int VpDivd(Real *c,Real *r,Real *a,Real *b);
VP_EXPORT int VpComp(Real *a,Real *b); VP_EXPORT int VpComp(Real *a,Real *b);
VP_EXPORT S_LONG VpExponent10(Real *a); VP_EXPORT S_LONG VpExponent10(Real *a);
VP_EXPORT void VpSzMantissa(Real *a,char *psz); VP_EXPORT void VpSzMantissa(Real *a,char *psz);
VP_EXPORT int VpToSpecialString(Real *a,char *psz); VP_EXPORT int VpToSpecialString(Real *a,char *psz,int fPlus);
VP_EXPORT void VpToString(Real *a,char *psz,int fFmt); VP_EXPORT void VpToString(Real *a,char *psz,int fFmt,int fPlus);
VP_EXPORT void VpToFString(Real *a,char *psz,int fFmt); VP_EXPORT void VpToFString(Real *a,char *psz,int fFmt,int fPlus);
VP_EXPORT int VpCtoV(Real *a,char *int_chr,U_LONG ni,char *frac,U_LONG nf,char *exp_chr,U_LONG ne); VP_EXPORT int VpCtoV(Real *a,char *int_chr,U_LONG ni,char *frac,U_LONG nf,char *exp_chr,U_LONG ne);
VP_EXPORT int VpVtoD(double *d,S_LONG *e,Real *m); VP_EXPORT int VpVtoD(double *d,S_LONG *e,Real *m);
VP_EXPORT void VpDtoV(Real *m,double d); VP_EXPORT void VpDtoV(Real *m,double d);
@ -157,12 +157,6 @@ VP_EXPORT int VpPower(Real *y,Real *x,S_INT n);
/* VP constants */ /* VP constants */
VP_EXPORT Real *VpOne(); VP_EXPORT Real *VpOne();
#ifdef ENABLE_TRIAL_METHOD
VP_EXPORT void VpPi(Real *y);
VP_EXPORT void VpExp1(Real *y);
VP_EXPORT void VpExp(Real *y,Real *x);
VP_EXPORT void VpSinCos(Real *psin,Real *pcos,Real *x);
#endif /* ENABLE_TRIAL_METHOD */
/* /*
* ------------------ * ------------------
* MACRO definitions. * MACRO definitions.

View file

@ -1,3 +1,4 @@
<!-- saved from url=(0022)http://internet.e-mail -->
<HTML> <HTML>
<HEAD> <HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html">
@ -105,7 +106,8 @@ For details,see the util.rb code.
a=BigDecimal::new(s[,n]) or<BR> a=BigDecimal::new(s[,n]) or<BR>
a=BigDecimal(s[,n]) or<BR> a=BigDecimal(s[,n]) or<BR>
where:<BR> where:<BR>
s: Initial value string.<BR> s: Initial value string. Spaces will be ignored. Any unrecognizable character for
representing initial value terminates the string.<BR>
n: Maximum number of significant digits of a. n must be a Fixnum object. 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. 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.
Actual number of digits handled in computations are usually gretaer than n.<BR> Actual number of digits handled in computations are usually gretaer than n.<BR>
@ -373,6 +375,14 @@ n can be an string representing a positive integer number.
<CODE><PRE> <CODE><PRE>
BigDecimal("0.1234567890123456789").to_s("10") # ==> "0.1234567890 123456789E0" BigDecimal("0.1234567890123456789").to_s("10") # ==> "0.1234567890 123456789E0"
</PRE></CODE> </PRE></CODE>
If the first character is '+'(or ' '),then '+'(or ' ') will be set before value string
when the value is positive.
<CODE><PRE>
BigDecimal("0.1234567890123456789").to_s(" 10") # ==> " 0.1234567890 123456789E0"
BigDecimal("0.1234567890123456789").to_s("+10") # ==> "+0.1234567890 123456789E0"
BigDecimal("-0.1234567890123456789").to_s("10") # ==> "-0.1234567890 123456789E0"
</PRE></CODE>
At the end of the string,'E'(or 'e') or 'F'(or 'f') can be specified to change At the end of the string,'E'(or 'e') or 'F'(or 'f') can be specified to change
number representation. number representation.
<CODE><PRE> <CODE><PRE>
@ -501,42 +511,7 @@ same as ==,used in case statement.
<LI>&gt;=</LI> <LI>&gt;=</LI>
</UL> </UL>
<H4><U>Class methods(trial version)</U></H4>
Following class methods are in trial stage, and not usable in default.
Uncomment /* #define ENABLE_TRIAL_METHOD */ in bigdecimal.c, compile and install
again if you want to use.
<UL>
<LI><B>E</B></LI><BLOCKQUOTE>
e = BigDecimal::E(n)<BR>
where e(=2.718281828....) is the base value of natural logarithm.<BR>
n specifies the length of significant digits of e.
</BLOCKQUOTE>
<LI><B>PI</B></LI><BLOCKQUOTE>
e = BigDecimal::PI(n)<BR>
returns at least n digits of the ratio of the circumference of a circle to its diameter
(pi=3.14159265358979....) using J.Machin's formula.<BR>
</BLOCKQUOTE>
</UL>
<H4><U>Instance methods(trial version)</U></H4>
Following instance methods are in trial stage, and not usable in default.
Uncomment /* #define ENABLE_TRIAL_METHOD */ in bigdecimal.c, compile and install
again if you want to use.
<UL>
<LI><B>sincos</B></LI><BLOCKQUOTE>
computes and returns sine and cosine value of a with significant digit number n at least.<BR>
sin,cos = a.sincos(n)<BR>
Computation may return bad results unless |a|<2*3.1415.....
</BLOCKQUOTE>
<LI><B>exp</B></LI><BLOCKQUOTE>
c = a.exp(n)<BR>
computes the base of natural logarithm value(e=2.718281828....) powered by a
with significant digit number n at least.<BR>
</BLOCKQUOTE>
</UL>
<HR> <HR>
<H3>About 'coerce'</H3> <H3>About 'coerce'</H3>
<B>For the binary operation like A op B:</B> <B>For the binary operation like A op B:</B>
<DL> <DL>

View file

@ -1,3 +1,4 @@
<!-- saved from url=(0022)http://internet.e-mail -->
<HTML> <HTML>
<HEAD> <HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">
@ -111,7 +112,9 @@ require "bigdecimal/util.rb"
新しい BigDecimal オブジェクトを生成します。<BR> 新しい BigDecimal オブジェクトを生成します。<BR>
a=BigDecimal::new(s[,n]) または<BR> a=BigDecimal::new(s[,n]) または<BR>
a=BigDecimal(s[,n])<BR> a=BigDecimal(s[,n])<BR>
s は初期値を文字列で指定します. s は数字を表現する初期値を文字列で指定します。
スペースは無視されます。また、判断できない文字が出現した時点で
文字列は終了したものとみなされます。
n は必要な有効桁数a の最大有効桁数)を整数で指定します。 n は必要な有効桁数a の最大有効桁数)を整数で指定します。
n が 0 または省略されたときは、n の値は s の有効桁数とみなされます。 n が 0 または省略されたときは、n の値は s の有効桁数とみなされます。
s の有効桁数より n が小さいときも n=0 のときと同じです。 s の有効桁数より n が小さいときも n=0 のときと同じです。
@ -387,6 +390,14 @@ BigDecimal("0.1234567890123456789").to_s(10) # ==> "0.1234567890 123456789E0"
<CODE><PRE> <CODE><PRE>
BigDecimal("0.1234567890123456789").to_s("10") # ==> "0.1234567890 123456789E0" BigDecimal("0.1234567890123456789").to_s("10") # ==> "0.1234567890 123456789E0"
</PRE></CODE> </PRE></CODE>
文字列の最初に '+'(または ' ')を付けると、値が正の場合、先頭に '+'(または ' ')が付きます
(負の場合は、常に '-' が付きます。)。
<CODE><PRE>
BigDecimal("0.1234567890123456789").to_s(" 10") # ==> " 0.1234567890 123456789E0"
BigDecimal("0.1234567890123456789").to_s("+10") # ==> "+0.1234567890 123456789E0"
BigDecimal("-0.1234567890123456789").to_s("10") # ==> "-0.1234567890 123456789E0"
</PRE></CODE>
さらに文字列の最後に E(または e) か F(または f) を指定することで、以下のように さらに文字列の最後に E(または e) か F(または f) を指定することで、以下のように
表示形式を変更することができます。 表示形式を変更することができます。
<CODE><PRE> <CODE><PRE>
@ -500,46 +511,6 @@ c = a &lt=&gt b
<LI><B>&gt=</B></LI> <LI><B>&gt=</B></LI>
</UL> </UL>
<H4><U>(評価段階の)クラスメソッド</U></H4>
以下のクラスメソッドは、まだ評価段階ですので、通常では
使用できません。使用するには bigdecimal.c の
「/* #define ENABLE_TRIAL_METHOD */」
のコメントを外し、再コンパイル・再インストールが必要です。
<UL>
<LI><B>E</B></LI><BLOCKQUOTE>
自然対数の底e(=2.718281828....)を計算します(正直にテイラー展開で)。<BR>
e = BigDecimal::E(n)<BR>
nは必要な有効桁数を整数で指定します。
</BLOCKQUOTE>
<LI><B>PI</B></LI><BLOCKQUOTE>
円周率(=3.14159265358979....)を計算しますJMachinの公式を用います<BR>
e = BigDecimal::PI(n)<BR>
n は必要な有効桁数を整数で指定します。
</BLOCKQUOTE>
</UL>
<H4><U>(評価段階の)インスタンスメソッド</U></H4>
以下のインスタンスメソッドは、まだ評価段階ですので、通常では
使用できません。使用するには bigdecimal.c の
「/* #define ENABLE_TRIAL_METHOD */」
のコメントを外して、再コンパイル・再インストールが必要です。
<UL>
<LI><B>sincos</B></LI><BLOCKQUOTE>
a の有効桁 n 桁の sin と cos を同時に(テイラー展開で)計算して、
sin と cos の配列を返します。
n は必要な有効桁数です( n の sin や cos を計算するわけではありません)。
<BR>
sin,cos = a.sincos(n)<BR>
|a| &lt; 2*3.1415....でないと正しい答えを計算できないこともあります。
</BLOCKQUOTE>
<LI><B>exp</B></LI><BLOCKQUOTE>
自然対数の底e(=2.718281828....)の a 乗を計算します。<BR>
c = a.exp(n)<BR>
n は必要な有効桁数です。
</BLOCKQUOTE>
</UL>
<H3>coerceについて</H3> <H3>coerceについて</H3>
BigDecimal オブジェクトが算術演算子の左にあるときは、BigDecimal オブジェクトが BigDecimal オブジェクトが算術演算子の左にあるときは、BigDecimal オブジェクトが
右にあるオブジェクトを(必要なら) BigDecimal に変換してから計算します。 右にあるオブジェクトを(必要なら) BigDecimal に変換してから計算します。