From b10272dc371a03844f685dc6db765c2bea11d29b Mon Sep 17 00:00:00 2001 From: shigek Date: Fri, 18 Jul 2003 15:23:23 +0000 Subject: More pathes from Tadasi Saito. As discussed in ruby-dev ML: E,PI, etc are disabled. BigDecimal op String disabled. to_f changed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4091 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/bigdecimal/MANIFEST | 8 +- ext/bigdecimal/bigdecimal.c | 225 +++++++++++++++++++++++--------------- ext/bigdecimal/bigdecimal.h | 2 +- ext/bigdecimal/bigdecimal_en.html | 89 +++++++++------ ext/bigdecimal/bigdecimal_ja.html | 113 +++++++++++-------- 5 files changed, 263 insertions(+), 174 deletions(-) (limited to 'ext') diff --git a/ext/bigdecimal/MANIFEST b/ext/bigdecimal/MANIFEST index 7408e05284..8e9415eeea 100644 --- a/ext/bigdecimal/MANIFEST +++ b/ext/bigdecimal/MANIFEST @@ -7,10 +7,10 @@ depend extconf.rb bigdecimal_en.html bigdecimal_ja.html -lib/jacobian.rb -lib/newton.rb -lib/ludcmp.rb -lib/bigdecimal-rational.rb +lib/bigdecimal/jacobian.rb +lib/bigdecimal/newton.rb +lib/bigdecimal/ludcmp.rb +lib/bigdecimal/util.rb sample/linear.rb sample/nlsolve.rb sample/pi.rb diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 4a04d2a94a..8f86108e4f 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -9,6 +9,7 @@ * of this BigDecimal distribution. * * NOTES: + * For the notes other than listed bellow,see ruby CVS log. * 2003-04-17 * Bug in negative.exp(n) reported by Hitoshi Miyazaki fixed. * 2003-03-28 @@ -34,11 +35,16 @@ #include #include #include +#include +#include +#include #include "ruby.h" #include "math.h" #include "version.h" - -/* #define USE_MUTABLE_METHOD */ + +/* #define ENABLE_NUMERIC_STRING */ +/* #define ENABLE_TRIAL_METHOD */ +/* #define ENABLE_BANG_METHOD */ VALUE rb_cBigDecimal; @@ -96,7 +102,6 @@ do_coerce(VALUE *x, VALUE *y) { VALUE ary; VALUE a[2]; - a[0] = *x; a[1] = *y; ary = rb_rescue(coerce_body, (VALUE)a, coerce_rescue, (VALUE)a); if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) { @@ -135,7 +140,6 @@ ToValue(Real *p) static Real * GetVpValue(VALUE v, int must) { - double dv; Real *pv; VALUE bg; char szD[128]; @@ -153,40 +157,14 @@ GetVpValue(VALUE v, int must) case T_FIXNUM: sprintf(szD, "%d", FIX2INT(v)); return VpCreateRbObject(VpBaseFig() * 2 + 1, szD); - case T_FLOAT: - pv = VpCreateRbObject(VpDblFig()*2,"0"); - dv = RFLOAT(v)->value; - /* From float */ - if (isinf(dv)) { - VpException(VP_EXCEPTION_INFINITY,"Computation including infinity",0); - if(dv==VpGetDoublePosInf()) { - VpSetPosInf(pv); - } else { - VpSetNegInf(pv); - } - } else - if (isnan(dv)) { - VpException(VP_EXCEPTION_NaN,"Computation including NaN(Not a number)",0); - VpSetNaN(pv); - } else { - if (VpIsNegDoubleZero(dv)) { - VpSetNegZero(pv); - } else if(dv==0.0) { - VpSetPosZero(pv); - } else if(dv==1.0) { - VpSetOne(pv); - } else if(dv==-1.0) { - VpSetOne(pv); - pv->sign = -pv->sign; - } else { - VpDtoV(pv,dv); - } - } - return pv; + +#ifdef ENABLE_NUMERIC_STRING case T_STRING: SafeStringValue(v); return VpCreateRbObject(strlen(RSTRING(v)->ptr) + VpBaseFig() + 1, RSTRING(v)->ptr); +#endif /* ENABLE_NUMERIC_STRING */ + case T_BIGNUM: bg = rb_big2str(v, 10); return VpCreateRbObject(strlen(RSTRING(bg)->ptr) + VpBaseFig() + 1, @@ -448,16 +426,44 @@ BigDecimal_induced_from(VALUE self, VALUE x) return p->obj; } +static VALUE +BigDecimal_to_f(VALUE self) +{ + ENTER(1); + Real *p; + double d, d2, da; + 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); + } + return rb_float_new(d*d2); +} + static VALUE BigDecimal_coerce(VALUE self, VALUE other) { ENTER(2); VALUE obj; Real *b; - GUARD_OBJ(b,GetVpValue(other,1)); - obj = rb_ary_new(); - obj = rb_ary_push(obj, b->obj); - obj = rb_ary_push(obj, self); + if(TYPE(other) == T_FLOAT) { + obj = rb_ary_new(); + obj = rb_ary_push(obj,other); + obj = rb_ary_push(obj,BigDecimal_to_f(self)); + } else { + GUARD_OBJ(b,GetVpValue(other,1)); + obj = rb_ary_new(); + obj = rb_ary_push(obj, b->obj); + obj = rb_ary_push(obj, self); + } return obj; } @@ -677,14 +683,14 @@ BigDecimal_div(VALUE self, VALUE r) ENTER(5); Real *c=NULL, *res=NULL, *div = NULL; r = BigDecimal_divide(&c, &res, &div, self, r); - SAVE(c);SAVE(res);SAVE(div); if(r!=(VALUE)0) return r; /* coerced by other */ + SAVE(c);SAVE(res);SAVE(div); /* a/b = c + r/b */ /* c xxxxx r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE */ /* Round */ - if(VpIsDef(c)) { + if(VpIsDef(c) && (!VpIsZero(c))) { VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]); } return ToValue(c); @@ -731,8 +737,8 @@ BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ Real *div=NULL, *mod=NULL; obj = BigDecimal_DoDivmod(self,r,&div,&mod); - SAVE(div);SAVE(mod); if(obj!=(VALUE)0) return obj; + SAVE(div);SAVE(mod); return ToValue(mod); } @@ -866,19 +872,6 @@ BigDecimal_mult2(VALUE self, VALUE b, VALUE n) return ToValue(cv); } -static VALUE -BigDecimal_dup(VALUE self) -{ - ENTER(5); - Real *c, *a; - U_LONG mx; - GUARD_OBJ(a,GetVpValue(self,1)); - mx = a->Prec *(VpBaseFig() + 1); - GUARD_OBJ(c,VpCreateRbObject(mx, "0")); - VpAsgn(c, a, 1); - return ToValue(c); -} - static VALUE BigDecimal_abs(VALUE self) { @@ -967,7 +960,6 @@ BigDecimal_truncate(int argc, VALUE *argv, VALUE self) ENTER(5); Real *c, *a; int iLoc; - int sw; U_LONG mx; VALUE vLoc; @@ -1081,9 +1073,7 @@ BigDecimal_split(VALUE self) VpSzMantissa(vp,psz1); s = 1; if(psz1[0]=='-') { - int i=0; - s = -1; - while(psz1[i]=psz1[i+1]) i++ ; + s = -1; ++psz1; } if(psz1[0]=='N') s=0; /* NaN */ e = VpExponent10(vp); @@ -1150,6 +1140,25 @@ BigDecimal_power(VALUE self, VALUE p) return ToValue(y); } +static VALUE +BigDecimal_global_new(int argc, VALUE *argv, VALUE self) +{ + ENTER(5); + Real *pv; + S_LONG mf; + VALUE nFig; + VALUE iniValue; + + if(rb_scan_args(argc,argv,"11",&iniValue,&nFig)==1) { + mf = 0; + } else { + mf = GetPositiveInt(nFig); + } + SafeStringValue(iniValue); + GUARD_OBJ(pv,VpCreateRbObject(mf, RSTRING(iniValue)->ptr)); + return ToValue(pv); +} + static VALUE BigDecimal_new(int argc, VALUE *argv, VALUE self) { @@ -1182,6 +1191,14 @@ BigDecimal_limit(int argc, VALUE *argv, VALUE self) return nCur; } +static VALUE +BigDecimal_sign(VALUE self) +{ /* sign */ + int s = GetVpValue(self,1)->sign; + return INT2FIX(s); +} + +#ifdef ENABLE_TRIAL_METHOD static VALUE BigDecimal_e(VALUE self, VALUE nFig) { @@ -1222,13 +1239,6 @@ BigDecimal_exp(VALUE self, VALUE nFig) return ToValue(c); } -static VALUE -BigDecimal_sign(VALUE self) -{ /* sign */ - int s = GetVpValue(self,1)->sign; - return INT2FIX(s); -} - static VALUE BigDecimal_sincos(VALUE self, VALUE nFig) { @@ -1252,9 +1262,9 @@ BigDecimal_sincos(VALUE self, VALUE nFig) rb_ary_push(obj, objCos); return obj; } +#endif /* ENABLE_TRIAL_METHOD */ - -#ifdef USE_MUTABLE_METHOD +#ifdef ENABLE_BANG_METHOD /**** Following methods are all MUTABLE and not currently activated. ****/ static void CheckAssign(VALUE x, VALUE y) @@ -1348,7 +1358,7 @@ BigDecimal_mult3(VALUE self, VALUE c, VALUE a, VALUE b) f = VpMult(cv,av,bv); return INT2NUM(f); } -#endif /* USE_MUTABLE_METHOD */ +#endif /* ENABLE_BANG_METHOD */ void Init_bigdecimal(void) @@ -1359,13 +1369,14 @@ Init_bigdecimal(void) /* Class and method registration */ rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric); + /* Global function */ + rb_define_global_function("BigDecimal", BigDecimal_global_new, -1); + /* Class methods */ rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, 2); rb_define_singleton_method(rb_cBigDecimal, "new", BigDecimal_new, -1); rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1); - rb_define_singleton_method(rb_cBigDecimal, "E", BigDecimal_e, 1); rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0); - rb_define_singleton_method(rb_cBigDecimal, "PI", BigDecimal_pi, 1); rb_define_singleton_method(rb_cBigDecimal, "induced_from",BigDecimal_induced_from, 1); rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1); @@ -1417,8 +1428,8 @@ Init_bigdecimal(void) rb_define_method(rb_cBigDecimal, "modulo", BigDecimal_mod, 1); rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1); rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1); - rb_define_method(rb_cBigDecimal, "dup", BigDecimal_dup, 0); - rb_define_method(rb_cBigDecimal, "to_f", BigDecimal_dup, 0); /* to_f === dup */ + /* rb_define_method(rb_cBigDecimal, "dup", BigDecimal_dup, 0); */ + rb_define_method(rb_cBigDecimal, "to_f", BigDecimal_to_f, 0); rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0); rb_define_method(rb_cBigDecimal, "sqrt", BigDecimal_sqrt, 1); rb_define_method(rb_cBigDecimal, "fix", BigDecimal_fix, 0); @@ -1428,8 +1439,6 @@ Init_bigdecimal(void) rb_define_method(rb_cBigDecimal, "ceil", BigDecimal_ceil, -1); rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, 1); rb_define_method(rb_cBigDecimal, "**", BigDecimal_power, 1); - rb_define_method(rb_cBigDecimal, "exp", BigDecimal_exp, 1); - rb_define_method(rb_cBigDecimal, "sincos", BigDecimal_sincos, 1); rb_define_method(rb_cBigDecimal, "<=>", BigDecimal_comp, 1); rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 1); rb_define_method(rb_cBigDecimal, "===", BigDecimal_eq, 1); @@ -1451,20 +1460,27 @@ Init_bigdecimal(void) rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1); rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1); -#ifdef USE_MUTABLE_METHOD +#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 */ + +#ifdef ENABLE_BANG_METHOD rb_define_singleton_method(rb_cBigDecimal, "assign!", BigDecimal_assign, 3); rb_define_singleton_method(rb_cBigDecimal, "add!", BigDecimal_add3, 3); rb_define_singleton_method(rb_cBigDecimal, "sub!", BigDecimal_sub3, 3); rb_define_singleton_method(rb_cBigDecimal, "mult!", BigDecimal_mult3, 3); rb_define_singleton_method(rb_cBigDecimal, "div!",BigDecimal_divmod4, 4); -#endif /* USE_MUTABLE_METHOD */ +#endif /* ENABLE_BANG_METHOD */ } /* * * ============================================================================ * - * vp_ routines begins here + * vp_ routines begin from here. * * ============================================================================ * @@ -2064,7 +2080,7 @@ VpAlloc(U_LONG mx, char *szVal) VP_EXPORT int VpAsgn(Real *c, Real *a, int isw) { - U_LONG j, n; + U_LONG n; if(VpIsNaN(a)) { VpSetNaN(c); return 0; @@ -2080,7 +2096,7 @@ VpAsgn(Real *c, Real *a, int isw) VpSetSign(c,(isw*VpGetSign(a))); /* set sign */ n =(a->Prec < c->MaxPrec) ?(a->Prec) :(c->MaxPrec); c->Prec = n; - for(j=0;j < n; ++j) c->frac[j] = a->frac[j]; + memcpy(c->frac, a->frac, n * sizeof(U_LONG)); /* Needs round ? */ if(c->Prec < a->Prec) { VpInternalRound(c,n,(n>0)?a->frac[n-1]:0,a->frac[n]); @@ -2093,7 +2109,6 @@ VpAsgn(Real *c, Real *a, int isw) return c->Prec*BASE_FIG; } - /* * c = a + b when operation = 1 or 2 * = a - b when operation = -1 or -2. @@ -2602,7 +2617,7 @@ VpMult(Real *c, Real *a, Real *b) VpSetSign(c,VpGetSign(a)*VpGetSign(b)); /* set sign */ Carry = 0; nc = ind_c = MxIndAB; - for(i = 0; i <= nc; i++) c->frac[i] = 0; /* Initialize c */ + memset(c->frac, 0, (nc + 1) * sizeof(U_LONG)); /* 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. */ @@ -3113,7 +3128,7 @@ static void VpFormatSt(char *psz,S_INT fFmt) { U_LONG ie; - U_LONG i, j; + U_LONG i; S_INT nf = 0; char ch; int fDot = 0; @@ -3131,8 +3146,7 @@ VpFormatSt(char *psz,S_INT fFmt) if(ch == 'E') break; nf++; if(nf > fFmt) { - for(j = ie; j >= i; --j) - psz[j + 1] = psz[j]; + memmove(psz + i + 1, psz + i, ie - i + 1); ++ie; nf = 0; psz[i] = ' '; @@ -3283,7 +3297,7 @@ VpCtoV(Real *a, char *int_chr, U_LONG ni, char *frac, U_LONG nf, char *exp_chr, mi = ni; me = ne; signe = 1; - for(i=0;i < ma;++i) a->frac[i] = 0; + memset(a->frac, 0, ma * sizeof(U_LONG)); if(ne > 0) { i = 0; if(exp_chr[0] == '-') { @@ -3398,24 +3412,51 @@ Final: * DBLE_FIG ... Number of digits in a double variable. * * m -> d*10**e, 0Prec)); *d = 0.0; @@ -3435,7 +3476,7 @@ Exit: printf(" DBLE_FIG = %ld\n", DBLE_FIG); } #endif /*_DEBUG */ - return; + return f; } /* @@ -3479,7 +3520,7 @@ VpDtoV(Real *m, double d) /* Now val = 0.xxxxx*BASE**ne */ mm = m->MaxPrec; - for(ind_m = 0;ind_m < mm;ind_m++) m->frac[ind_m] = 0; + memset(m->frac, 0, mm * sizeof(U_LONG)); for(ind_m = 0;val > 0.0 && ind_m < mm;ind_m++) { val *=(double)((S_INT)BASE); i =(U_LONG) val; @@ -3684,7 +3725,7 @@ Exit: VP_EXPORT void VpActiveRound(Real *y, Real *x, int f, int nf) { - int n,i,j,ix,ioffset; + int n,i,ix,ioffset; U_LONG v; U_LONG div; @@ -3700,7 +3741,7 @@ VpActiveRound(Real *y, Real *x, int f, int nf) ix = (nf + ((int)BASE_FIG))/((int)BASE_FIG)-1; if(ix<0 || ((U_LONG)ix)>=y->Prec) goto Exit; /* Unable to round */ ioffset = nf - ix*((int)BASE_FIG); - for(j=ix+1;j<(int)y->Prec;++j) y->frac[j] = 0; + memset(y->frac+ix+1, 0, (y->Prec - (ix+1)) * sizeof(U_LONG)); /* VpNmlz(y); */ v = y->frac[ix]; /* drop digits after pointed digit */ @@ -3929,6 +3970,7 @@ Exit: return 1; } +#ifdef ENABLE_TRIAL_METHOD /* * Calculates pi(=3.141592653589793238462........). */ @@ -4216,6 +4258,7 @@ Exit: VpFree(r); VpFree(z); } +#endif /* ENABLE_TRIAL_METHOD */ #ifdef _DEBUG int diff --git a/ext/bigdecimal/bigdecimal.h b/ext/bigdecimal/bigdecimal.h index 3debb52826..940647b446 100644 --- a/ext/bigdecimal/bigdecimal.h +++ b/ext/bigdecimal/bigdecimal.h @@ -131,7 +131,7 @@ VP_EXPORT S_LONG VpExponent10(Real *a); VP_EXPORT void VpSzMantissa(Real *a,char *psz); VP_EXPORT void VpToString(Real *a,char *psz,int fFmt); 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 void 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 VpItoV(Real *m,S_INT ival); VP_EXPORT int VpSqrt(Real *y,Real *x); diff --git a/ext/bigdecimal/bigdecimal_en.html b/ext/bigdecimal/bigdecimal_en.html index 04dd83a429..5344720adc 100644 --- a/ext/bigdecimal/bigdecimal_en.html +++ b/ext/bigdecimal/bigdecimal_en.html @@ -81,21 +81,29 @@ to create BigDecimal objects,the program would like:
    require 'bigdecimal'
    a=BigDecimal::new("0.123456789123456789")
-   b=BigDecimal::new("123456.78912345678",40)
+   b=BigDecimal("123456.78912345678",40)
    c=a+b
 

List of methods

-In the following explanations,n specifies the minimum number of resulting significant digits, -not exactly but slightly excess memories will be allocated to newly created object. In 32 bits integer system,every 4 digits(in decimal) are computed simultaneously. This means the number of significant digits in BigDecimal is always a multiple of 4. +

+Some more methods are available in Ruby code (not C code). +To use them,just require util.rb as: +


+require "bigdecimal/util.rb"
+
+String to BigDecimal conversion, BigDecimal to String conversion +(in "nnnnnn.mmmm" form not in "0.xxxxxEn" form) etc are defined. +For details,see the util.rb code.

Class methods

  • new
  • "new" method creates a new BigDecimal object.
    -a=BigDecimal::new(s[,n])
    +a=BigDecimal::new(s[,n]) or
    +a=BigDecimal(s[,n]) or
    where:
    s: Initial value string.
    n: Maximum number of significant digits of a. n must be a Fixnum object. @@ -187,18 +195,6 @@ Base value used in the BigDecimal calculation. On 32 bits integer system,the value of BASE is 10000.
    b = BigDecimal::BASE
    - -
  • E
  • -e = BigDecimal::E(n)
    -where e(=2.718281828....) is the base value of natural logarithm.
    -n specifies the length of significant digits of e. - -
    -
  • PI
  • -e = BigDecimal::PI(n)
    -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.
    -

Instance methods

@@ -394,14 +390,15 @@ means a = 0.xxxxxxx*10**n.
  • to_f
  • -same as dup method. -creates a new BigDecimal object having same value. +Creates a new Float object having (nearly) the same value. +Use split method if you want to convert by yourself.
  • sign
  • -returns the 'attribute' of a. n = a.sign
    +returns positive value if a > 0,negative value if a < 0, +otherwise zero if a == 0.
    where the value of n means that a is:
    n = BigDecimal::SIGN_NaN(0) : a is NaN
    n = BigDecimal::SIGN_POSITIVE_ZERO(1) : a is +0
    @@ -455,28 +452,13 @@ where "0x112344" is the address, '0.314E1' is the value,4 is the number of the significant digits, and 12 is the maximum number of the significant digits the object can hold. -
    -
  • dup
  • -creates a new BigDecimal object having same value. -
  • sqrt
  • c = a.sqrt(n)
    computes square root value of a with significant digit number n at least.
    - -
    -
  • sincos
  • -computes and returns sine and cosine value of a with significant digit number n at least.
    -sin,cos = a.sincos(n)
    -Computation may return bad results unless |a|<2*3.1415.....
    -
  • exp
  • -c = a.exp(n)
    -computes the base of natural logarithm value(e=2.718281828....) powered by a -with significant digit number n at least.
    -
  • **
  • c = a ** n
    returns the value of a powered by n. @@ -507,6 +489,41 @@ same as ==,used in case statement.
  • >
  • >=
  • + +

    Class methods(trial version)

    +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. +
      +
    • E
    • +e = BigDecimal::E(n)
      +where e(=2.718281828....) is the base value of natural logarithm.
      +n specifies the length of significant digits of e. + +
      +
    • PI
    • +e = BigDecimal::PI(n)
      +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.
      +
      +
    + +

    Instance methods(trial version)

    +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. +
      +
    • sincos
    • +computes and returns sine and cosine value of a with significant digit number n at least.
      +sin,cos = a.sincos(n)
      +Computation may return bad results unless |a|<2*3.1415..... +
      +
    • exp
    • +c = a.exp(n)
      +computes the base of natural logarithm value(e=2.718281828....) powered by a +with significant digit number n at least.
      +
      +

    About 'coerce'

    @@ -521,7 +538,9 @@ same as ==,used in case statement. BigDecimal object and the operation is performed,otherwise an error occures. -Attention must be paid when a String is to be translated to BigDecimal. +String is not translated to BigDecimal in default. +Uncomment /* #define ENABLE_NUMERIC_STRING */ in bigdecimal.c, compile and install +again if you want to enable string to BigDecimal conversion. Translation stops without error at the character representing non digit. For instance,"10XX" is translated to 10,"XXXX" is translated to 0.
    String representing zero or infinity such as "Infinity","+Infinity","-Infinity",and "NaN" can also be translated to BigDecimal unless false is specified by mode method.
    diff --git a/ext/bigdecimal/bigdecimal_ja.html b/ext/bigdecimal/bigdecimal_ja.html index 56bebaa863..caa1326c92 100644 --- a/ext/bigdecimal/bigdecimal_ja.html +++ b/ext/bigdecimal/bigdecimal_ja.html @@ -84,7 +84,7 @@ bigdecimal.c,bigdecimal.h
     require 'bigdecimal'
     a=BigDecimal::new("0.123456789123456789")
    -b=BigDecimal::new("123456.78912345678",40)
    +b=BigDecimal("123456.78912345678",40)
     c=a+b
     
    @@ -92,18 +92,27 @@ c=a+b というような感じで使用します。

    メソッド一覧

    -以下のようなメソッドが利用可能です。
    -記述上、BigDecimal オブジェクトを a,b,c,rで、String(文字列)オブジェクトを - s、整数を n で表記します。また、「有効桁数」とは BigDecimal が精度を保証する -桁数です。ぴったりではありません、若干の余裕を持って計算されます。また、 +以下のメソッドが利用可能です。 +「有効桁数」とは BigDecimal が精度を保証する桁数です。 +ぴったりではありません、若干の余裕を持って計算されます。また、 例えば32ビットのシステムでは10進で4桁毎に計算します。従って、現状では、 内部の「有効桁数」は4の倍数となっています。 +

    +以下のメソッド以外にも、(C ではない) Ruby ソースの形で +提供されているものもあります。例えば、文字列から BigDecimal への +変換や、"0.xxxxxEn" という形式ではなく "nnnnn.mmmm" の形式の文字列 +へ変換するメソッド等があります。利用するには +

    
    +require "bigdecimal/util.rb"
    +
    +のようにします。詳細は util.rb の内容を参照して下さい。

    クラスメソッド

    • new
    • 新しい BigDecimal オブジェクトを生成します。
      -a=BigDecimal::new(s[,n])
      +a=BigDecimal::new(s[,n]) または
      +a=BigDecimal(s[,n])
      s は初期値を文字列で指定します. n は必要な有効桁数(a の最大有効桁数)を整数で指定します。 n が 0 または省略されたときは、n の値は s の有効桁数とみなされます。 @@ -195,17 +204,6 @@ double_fig 内部で使用される基数の値です。整数が 32 ビットの処理系では10000です。
      b = BigDecimal::BASE
      - -
    • E
    • -自然対数の底e(=2.718281828....)を計算します(正直にテイラー展開で)。
      -e = BigDecimal::E(n)
      -nは必要な有効桁数を整数で指定します。 -
      -
    • PI
    • -円周率(=3.14159265358979....)を計算します(J.Machinの公式を用います)。
      -e = BigDecimal::PI(n)
      -n は必要な有効桁数を整数で指定します。 -

    インスタンスメソッド

    @@ -374,8 +372,9 @@ i a が Infinity や NaN のとき、i は nil になります。
  • to_f
  • -dup と全く同じです。 -同じ値の BigDecimal オブジェクトを生成します。 +Float オブジェクトに変換します。 +よりきめ細かい値が必要ならば split メソッドを利用して +ください。
  • to_s[(n)]
  • 文字列に変換します("0.xxxxxEn"の形になります)。
    @@ -391,7 +390,7 @@ n = a.exponent
  • sign
  • -値の属性を返します。 +値が正(sign > 0)、負(sign < 0)、その他(sigh==0)であるかの情報を返します。 n = a.sign
    としたとき n の値は a が以下のときを意味します。
    () の中の数字は、実際の値です(「内部構造」を参照)。
    @@ -443,28 +442,6 @@ p a=BigDecimal::new("3.14",10)
    最初の16進数はオブジェクトのアドレス、次の '0.314E1' は値、 次の4は現在の有効桁数(表示より若干大きいことがあります)、 最後はオブジェクトが取り得る最大桁数になります。 - -
    -
  • dup
  • -同じ値の BigDecimal オブジェクトを生成します。 -
    -
  • sqrt
  • -aの有効桁 n 桁の平方根(n の平方根ではありません)。 -これまた、正直にニュートン法で計算します。
    -c = a.sqrt(n)
    -
    -
  • sincos
  • -a の有効桁 n 桁の sin と cos を同時に(テイラー展開で)計算して、 - sin と cos の配列を返します。 -n は必要な有効桁数です( n の sin や cos を計算するわけではありません)。 -
    -sin,cos = a.sincos(n)
    -|a|<2*3.1415....でないと正しい答えを計算できないこともあります。 -
    -
  • exp
  • -自然対数の底e(=2.718281828....)の a 乗を計算します。
    -c = a.exp(n)
    -n は必要な有効桁数です。
  • **
  • a の n 乗を計算します。nは整数。
    @@ -476,6 +453,11 @@ c = a ** n
    c = a.power(n)
    結果として c の有効桁は a の n 倍以上になるので注意。
    +
  • sqrt
  • +aの有効桁 n 桁の平方根(n の平方根ではありません)を +ニュートン法で計算します。
    +c = a.sqrt(n)
    +
  • <=>
  • a==b なら 0、a > b なら 1、a < b なら -1 になります。
    @@ -493,11 +475,56 @@ c = a <=> b
  • >
  • >=
  • + +

    (評価段階の)クラスメソッド

    +以下のクラスメソッドは、まだ評価段階ですので、通常では +使用できません。使用するには bigdecimal.c の +「/* #define ENABLE_TRIAL_METHOD */」 +のコメントを外し、再コンパイル・再インストールが必要です。 + +
      +
    • E
    • +自然対数の底e(=2.718281828....)を計算します(正直にテイラー展開で)。
      +e = BigDecimal::E(n)
      +nは必要な有効桁数を整数で指定します。 +
      +
    • PI
    • +円周率(=3.14159265358979....)を計算します(J.Machinの公式を用います)。
      +e = BigDecimal::PI(n)
      +n は必要な有効桁数を整数で指定します。 +
      +
    + +

    (評価段階の)インスタンスメソッド

    +以下のインスタンスメソッドは、まだ評価段階ですので、通常では +使用できません。使用するには bigdecimal.c の +「/* #define ENABLE_TRIAL_METHOD */」 +のコメントを外して、再コンパイル・再インストールが必要です。 +
      +
    • sincos
    • +a の有効桁 n 桁の sin と cos を同時に(テイラー展開で)計算して、 + sin と cos の配列を返します。 +n は必要な有効桁数です( n の sin や cos を計算するわけではありません)。 +
      +sin,cos = a.sincos(n)
      +|a| < 2*3.1415....でないと正しい答えを計算できないこともあります。 +
      +
    • exp
    • +自然対数の底e(=2.718281828....)の a 乗を計算します。
      +c = a.exp(n)
      +n は必要な有効桁数です。 +
      +
    +

    coerceについて

    BigDecimal オブジェクトが算術演算子の左にあるときは、BigDecimal オブジェクトが 右にあるオブジェクトを(必要なら) BigDecimal に変換してから計算します。 従って、BigDecimal オブジェクト以外でも数値を意味するものなら右に置けば -演算は可能です。

    +演算は可能です。
    +ただし、文字列は(通常)数値に自動変換することはできません。 +文字列を数値に自動変換に自動変換したい場合は bigfloat.c の +「/* #define ENABLE_NUMERIC_STRING */」のコメントを外してから、 +再コンパイル、再インストールする必要があります。 文字列で数値を与える場合は注意が必要です。数値に変換できない文字があると、 単に変換を止めるだけでエラーにはなりません。"10XX"なら10、"XXXX"は0 と扱われます。
    -- cgit v1.2.3