зеркало из https://github.com/github/ruby.git
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
This commit is contained in:
Родитель
b31bca1b45
Коммит
b10272dc37
|
@ -7,10 +7,10 @@ depend
|
||||||
extconf.rb
|
extconf.rb
|
||||||
bigdecimal_en.html
|
bigdecimal_en.html
|
||||||
bigdecimal_ja.html
|
bigdecimal_ja.html
|
||||||
lib/jacobian.rb
|
lib/bigdecimal/jacobian.rb
|
||||||
lib/newton.rb
|
lib/bigdecimal/newton.rb
|
||||||
lib/ludcmp.rb
|
lib/bigdecimal/ludcmp.rb
|
||||||
lib/bigdecimal-rational.rb
|
lib/bigdecimal/util.rb
|
||||||
sample/linear.rb
|
sample/linear.rb
|
||||||
sample/nlsolve.rb
|
sample/nlsolve.rb
|
||||||
sample/pi.rb
|
sample/pi.rb
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* of this BigDecimal distribution.
|
* of this BigDecimal distribution.
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTES:
|
||||||
|
* For the notes other than listed bellow,see ruby CVS log.
|
||||||
* 2003-04-17
|
* 2003-04-17
|
||||||
* Bug in negative.exp(n) reported by Hitoshi Miyazaki fixed.
|
* Bug in negative.exp(n) reported by Hitoshi Miyazaki fixed.
|
||||||
* 2003-03-28
|
* 2003-03-28
|
||||||
|
@ -34,11 +35,16 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <math.h>
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
/* #define USE_MUTABLE_METHOD */
|
/* #define ENABLE_NUMERIC_STRING */
|
||||||
|
/* #define ENABLE_TRIAL_METHOD */
|
||||||
|
/* #define ENABLE_BANG_METHOD */
|
||||||
|
|
||||||
VALUE rb_cBigDecimal;
|
VALUE rb_cBigDecimal;
|
||||||
|
|
||||||
|
@ -96,7 +102,6 @@ do_coerce(VALUE *x, VALUE *y)
|
||||||
{
|
{
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
VALUE a[2];
|
VALUE a[2];
|
||||||
|
|
||||||
a[0] = *x; a[1] = *y;
|
a[0] = *x; a[1] = *y;
|
||||||
ary = rb_rescue(coerce_body, (VALUE)a, coerce_rescue, (VALUE)a);
|
ary = rb_rescue(coerce_body, (VALUE)a, coerce_rescue, (VALUE)a);
|
||||||
if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {
|
if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {
|
||||||
|
@ -135,7 +140,6 @@ ToValue(Real *p)
|
||||||
static Real *
|
static Real *
|
||||||
GetVpValue(VALUE v, int must)
|
GetVpValue(VALUE v, int must)
|
||||||
{
|
{
|
||||||
double dv;
|
|
||||||
Real *pv;
|
Real *pv;
|
||||||
VALUE bg;
|
VALUE bg;
|
||||||
char szD[128];
|
char szD[128];
|
||||||
|
@ -153,40 +157,14 @@ GetVpValue(VALUE v, int must)
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
sprintf(szD, "%d", FIX2INT(v));
|
sprintf(szD, "%d", FIX2INT(v));
|
||||||
return VpCreateRbObject(VpBaseFig() * 2 + 1, szD);
|
return VpCreateRbObject(VpBaseFig() * 2 + 1, szD);
|
||||||
case T_FLOAT:
|
|
||||||
pv = VpCreateRbObject(VpDblFig()*2,"0");
|
#ifdef ENABLE_NUMERIC_STRING
|
||||||
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;
|
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
SafeStringValue(v);
|
SafeStringValue(v);
|
||||||
return VpCreateRbObject(strlen(RSTRING(v)->ptr) + VpBaseFig() + 1,
|
return VpCreateRbObject(strlen(RSTRING(v)->ptr) + VpBaseFig() + 1,
|
||||||
RSTRING(v)->ptr);
|
RSTRING(v)->ptr);
|
||||||
|
#endif /* ENABLE_NUMERIC_STRING */
|
||||||
|
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
bg = rb_big2str(v, 10);
|
bg = rb_big2str(v, 10);
|
||||||
return VpCreateRbObject(strlen(RSTRING(bg)->ptr) + VpBaseFig() + 1,
|
return VpCreateRbObject(strlen(RSTRING(bg)->ptr) + VpBaseFig() + 1,
|
||||||
|
@ -448,16 +426,44 @@ BigDecimal_induced_from(VALUE self, VALUE x)
|
||||||
return p->obj;
|
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
|
static VALUE
|
||||||
BigDecimal_coerce(VALUE self, VALUE other)
|
BigDecimal_coerce(VALUE self, VALUE other)
|
||||||
{
|
{
|
||||||
ENTER(2);
|
ENTER(2);
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
Real *b;
|
Real *b;
|
||||||
|
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));
|
GUARD_OBJ(b,GetVpValue(other,1));
|
||||||
obj = rb_ary_new();
|
obj = rb_ary_new();
|
||||||
obj = rb_ary_push(obj, b->obj);
|
obj = rb_ary_push(obj, b->obj);
|
||||||
obj = rb_ary_push(obj, self);
|
obj = rb_ary_push(obj, self);
|
||||||
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,14 +683,14 @@ BigDecimal_div(VALUE self, VALUE r)
|
||||||
ENTER(5);
|
ENTER(5);
|
||||||
Real *c=NULL, *res=NULL, *div = NULL;
|
Real *c=NULL, *res=NULL, *div = NULL;
|
||||||
r = BigDecimal_divide(&c, &res, &div, self, r);
|
r = BigDecimal_divide(&c, &res, &div, self, r);
|
||||||
SAVE(c);SAVE(res);SAVE(div);
|
|
||||||
if(r!=(VALUE)0) return r; /* coerced by other */
|
if(r!=(VALUE)0) return r; /* coerced by other */
|
||||||
|
SAVE(c);SAVE(res);SAVE(div);
|
||||||
/* a/b = c + r/b */
|
/* a/b = c + r/b */
|
||||||
/* c xxxxx
|
/* c xxxxx
|
||||||
r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
|
r 00000yyyyy ==> (y/b)*BASE >= HALF_BASE
|
||||||
*/
|
*/
|
||||||
/* Round */
|
/* Round */
|
||||||
if(VpIsDef(c)) {
|
if(VpIsDef(c) && (!VpIsZero(c))) {
|
||||||
VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]);
|
VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]);
|
||||||
}
|
}
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
|
@ -731,8 +737,8 @@ BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */
|
||||||
Real *div=NULL, *mod=NULL;
|
Real *div=NULL, *mod=NULL;
|
||||||
|
|
||||||
obj = BigDecimal_DoDivmod(self,r,&div,&mod);
|
obj = BigDecimal_DoDivmod(self,r,&div,&mod);
|
||||||
SAVE(div);SAVE(mod);
|
|
||||||
if(obj!=(VALUE)0) return obj;
|
if(obj!=(VALUE)0) return obj;
|
||||||
|
SAVE(div);SAVE(mod);
|
||||||
return ToValue(mod);
|
return ToValue(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,19 +872,6 @@ BigDecimal_mult2(VALUE self, VALUE b, VALUE n)
|
||||||
return ToValue(cv);
|
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
|
static VALUE
|
||||||
BigDecimal_abs(VALUE self)
|
BigDecimal_abs(VALUE self)
|
||||||
{
|
{
|
||||||
|
@ -967,7 +960,6 @@ BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
|
||||||
ENTER(5);
|
ENTER(5);
|
||||||
Real *c, *a;
|
Real *c, *a;
|
||||||
int iLoc;
|
int iLoc;
|
||||||
int sw;
|
|
||||||
U_LONG mx;
|
U_LONG mx;
|
||||||
VALUE vLoc;
|
VALUE vLoc;
|
||||||
|
|
||||||
|
@ -1081,9 +1073,7 @@ BigDecimal_split(VALUE self)
|
||||||
VpSzMantissa(vp,psz1);
|
VpSzMantissa(vp,psz1);
|
||||||
s = 1;
|
s = 1;
|
||||||
if(psz1[0]=='-') {
|
if(psz1[0]=='-') {
|
||||||
int i=0;
|
s = -1; ++psz1;
|
||||||
s = -1;
|
|
||||||
while(psz1[i]=psz1[i+1]) i++ ;
|
|
||||||
}
|
}
|
||||||
if(psz1[0]=='N') s=0; /* NaN */
|
if(psz1[0]=='N') s=0; /* NaN */
|
||||||
e = VpExponent10(vp);
|
e = VpExponent10(vp);
|
||||||
|
@ -1150,6 +1140,25 @@ BigDecimal_power(VALUE self, VALUE p)
|
||||||
return ToValue(y);
|
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
|
static VALUE
|
||||||
BigDecimal_new(int argc, VALUE *argv, VALUE self)
|
BigDecimal_new(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
|
@ -1182,6 +1191,14 @@ BigDecimal_limit(int argc, VALUE *argv, VALUE self)
|
||||||
return nCur;
|
return nCur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
BigDecimal_sign(VALUE self)
|
||||||
|
{ /* sign */
|
||||||
|
int s = GetVpValue(self,1)->sign;
|
||||||
|
return INT2FIX(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_TRIAL_METHOD
|
||||||
static VALUE
|
static VALUE
|
||||||
BigDecimal_e(VALUE self, VALUE nFig)
|
BigDecimal_e(VALUE self, VALUE nFig)
|
||||||
{
|
{
|
||||||
|
@ -1222,13 +1239,6 @@ BigDecimal_exp(VALUE self, VALUE nFig)
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
|
||||||
BigDecimal_sign(VALUE self)
|
|
||||||
{ /* sign */
|
|
||||||
int s = GetVpValue(self,1)->sign;
|
|
||||||
return INT2FIX(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
BigDecimal_sincos(VALUE self, VALUE nFig)
|
BigDecimal_sincos(VALUE self, VALUE nFig)
|
||||||
{
|
{
|
||||||
|
@ -1252,9 +1262,9 @@ BigDecimal_sincos(VALUE self, VALUE nFig)
|
||||||
rb_ary_push(obj, objCos);
|
rb_ary_push(obj, objCos);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
#endif /* ENABLE_TRIAL_METHOD */
|
||||||
|
|
||||||
|
#ifdef ENABLE_BANG_METHOD
|
||||||
#ifdef USE_MUTABLE_METHOD
|
|
||||||
/**** Following methods are all MUTABLE and not currently activated. ****/
|
/**** Following methods are all MUTABLE and not currently activated. ****/
|
||||||
static void
|
static void
|
||||||
CheckAssign(VALUE x, VALUE y)
|
CheckAssign(VALUE x, VALUE y)
|
||||||
|
@ -1348,7 +1358,7 @@ BigDecimal_mult3(VALUE self, VALUE c, VALUE a, VALUE b)
|
||||||
f = VpMult(cv,av,bv);
|
f = VpMult(cv,av,bv);
|
||||||
return INT2NUM(f);
|
return INT2NUM(f);
|
||||||
}
|
}
|
||||||
#endif /* USE_MUTABLE_METHOD */
|
#endif /* ENABLE_BANG_METHOD */
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_bigdecimal(void)
|
Init_bigdecimal(void)
|
||||||
|
@ -1359,13 +1369,14 @@ Init_bigdecimal(void)
|
||||||
/* Class and method registration */
|
/* Class and method registration */
|
||||||
rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric);
|
rb_cBigDecimal = rb_define_class("BigDecimal",rb_cNumeric);
|
||||||
|
|
||||||
|
/* Global function */
|
||||||
|
rb_define_global_function("BigDecimal", BigDecimal_global_new, -1);
|
||||||
|
|
||||||
/* Class methods */
|
/* Class methods */
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, 2);
|
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, "new", BigDecimal_new, -1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "E", BigDecimal_e, 1);
|
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "PI", BigDecimal_pi, 1);
|
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "induced_from",BigDecimal_induced_from, 1);
|
rb_define_singleton_method(rb_cBigDecimal, "induced_from",BigDecimal_induced_from, 1);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 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, "modulo", BigDecimal_mod, 1);
|
||||||
rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1);
|
rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1);
|
||||||
rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1);
|
rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1);
|
||||||
rb_define_method(rb_cBigDecimal, "dup", BigDecimal_dup, 0);
|
/* 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, "to_f", BigDecimal_to_f, 0);
|
||||||
rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0);
|
rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0);
|
||||||
rb_define_method(rb_cBigDecimal, "sqrt", BigDecimal_sqrt, 1);
|
rb_define_method(rb_cBigDecimal, "sqrt", BigDecimal_sqrt, 1);
|
||||||
rb_define_method(rb_cBigDecimal, "fix", BigDecimal_fix, 0);
|
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, "ceil", BigDecimal_ceil, -1);
|
||||||
rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, 1);
|
rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, 1);
|
||||||
rb_define_method(rb_cBigDecimal, "**", 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_comp, 1);
|
||||||
rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 1);
|
rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 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, "truncate", BigDecimal_truncate, -1);
|
||||||
rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -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, "assign!", BigDecimal_assign, 3);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "add!", BigDecimal_add3, 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, "sub!", BigDecimal_sub3, 3);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "mult!", BigDecimal_mult3, 3);
|
rb_define_singleton_method(rb_cBigDecimal, "mult!", BigDecimal_mult3, 3);
|
||||||
rb_define_singleton_method(rb_cBigDecimal, "div!",BigDecimal_divmod4, 4);
|
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
|
VP_EXPORT int
|
||||||
VpAsgn(Real *c, Real *a, int isw)
|
VpAsgn(Real *c, Real *a, int isw)
|
||||||
{
|
{
|
||||||
U_LONG j, n;
|
U_LONG n;
|
||||||
if(VpIsNaN(a)) {
|
if(VpIsNaN(a)) {
|
||||||
VpSetNaN(c);
|
VpSetNaN(c);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2080,7 +2096,7 @@ VpAsgn(Real *c, Real *a, int isw)
|
||||||
VpSetSign(c,(isw*VpGetSign(a))); /* set sign */
|
VpSetSign(c,(isw*VpGetSign(a))); /* set sign */
|
||||||
n =(a->Prec < c->MaxPrec) ?(a->Prec) :(c->MaxPrec);
|
n =(a->Prec < c->MaxPrec) ?(a->Prec) :(c->MaxPrec);
|
||||||
c->Prec = n;
|
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 ? */
|
/* Needs round ? */
|
||||||
if(c->Prec < a->Prec) {
|
if(c->Prec < a->Prec) {
|
||||||
VpInternalRound(c,n,(n>0)?a->frac[n-1]:0,a->frac[n]);
|
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;
|
return c->Prec*BASE_FIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* c = a + b when operation = 1 or 2
|
* c = a + b when operation = 1 or 2
|
||||||
* = 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 */
|
VpSetSign(c,VpGetSign(a)*VpGetSign(b)); /* set sign */
|
||||||
Carry = 0;
|
Carry = 0;
|
||||||
nc = ind_c = MxIndAB;
|
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 */
|
c->Prec = nc + 1; /* set precision */
|
||||||
for(nc = 0; nc < MxIndAB; ++nc, --ind_c) {
|
for(nc = 0; nc < MxIndAB; ++nc, --ind_c) {
|
||||||
if(nc < MxIndB) { /* The left triangle of the Fig. */
|
if(nc < MxIndB) { /* The left triangle of the Fig. */
|
||||||
|
@ -3113,7 +3128,7 @@ static void
|
||||||
VpFormatSt(char *psz,S_INT fFmt)
|
VpFormatSt(char *psz,S_INT fFmt)
|
||||||
{
|
{
|
||||||
U_LONG ie;
|
U_LONG ie;
|
||||||
U_LONG i, j;
|
U_LONG i;
|
||||||
S_INT nf = 0;
|
S_INT nf = 0;
|
||||||
char ch;
|
char ch;
|
||||||
int fDot = 0;
|
int fDot = 0;
|
||||||
|
@ -3131,8 +3146,7 @@ VpFormatSt(char *psz,S_INT fFmt)
|
||||||
if(ch == 'E') break;
|
if(ch == 'E') break;
|
||||||
nf++;
|
nf++;
|
||||||
if(nf > fFmt) {
|
if(nf > fFmt) {
|
||||||
for(j = ie; j >= i; --j)
|
memmove(psz + i + 1, psz + i, ie - i + 1);
|
||||||
psz[j + 1] = psz[j];
|
|
||||||
++ie;
|
++ie;
|
||||||
nf = 0;
|
nf = 0;
|
||||||
psz[i] = ' ';
|
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;
|
mi = ni;
|
||||||
me = ne;
|
me = ne;
|
||||||
signe = 1;
|
signe = 1;
|
||||||
for(i=0;i < ma;++i) a->frac[i] = 0;
|
memset(a->frac, 0, ma * sizeof(U_LONG));
|
||||||
if(ne > 0) {
|
if(ne > 0) {
|
||||||
i = 0;
|
i = 0;
|
||||||
if(exp_chr[0] == '-') {
|
if(exp_chr[0] == '-') {
|
||||||
|
@ -3398,24 +3412,51 @@ Final:
|
||||||
* DBLE_FIG ... Number of digits in a double variable.
|
* DBLE_FIG ... Number of digits in a double variable.
|
||||||
*
|
*
|
||||||
* m -> d*10**e, 0<d<BASE
|
* m -> d*10**e, 0<d<BASE
|
||||||
|
* [Returns]
|
||||||
|
* 0 ... Zero
|
||||||
|
* 1 ... Normal
|
||||||
|
* 2 ... Infinity
|
||||||
|
* -1 ... NaN
|
||||||
*/
|
*/
|
||||||
VP_EXPORT void
|
VP_EXPORT int
|
||||||
VpVtoD(double *d, S_LONG *e, Real *m)
|
VpVtoD(double *d, S_LONG *e, Real *m)
|
||||||
{
|
{
|
||||||
U_LONG ind_m, mm, fig;
|
U_LONG ind_m, mm, fig;
|
||||||
double div;
|
double div;
|
||||||
|
int f = 1;
|
||||||
|
|
||||||
fig =(DBLE_FIG + BASE_FIG - 1) / BASE_FIG;
|
if(VpIsNaN(m)) {
|
||||||
|
*d = VpGetDoubleNaN();
|
||||||
|
*e = 0;
|
||||||
|
f = -1; /* NaN */
|
||||||
|
goto Exit;
|
||||||
|
} else
|
||||||
if(VpIsPosZero(m)) {
|
if(VpIsPosZero(m)) {
|
||||||
*d = 0.0;
|
*d = 0.0;
|
||||||
*e = 0;
|
*e = 0;
|
||||||
|
f = 0;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
} else
|
} else
|
||||||
if(VpIsNegZero(m)) {
|
if(VpIsNegZero(m)) {
|
||||||
*d = VpGetDoubleNegZero();
|
*d = VpGetDoubleNegZero();
|
||||||
*e = 0;
|
*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;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
/* Normal number */
|
||||||
|
fig =(DBLE_FIG + BASE_FIG - 1) / BASE_FIG;
|
||||||
ind_m = 0;
|
ind_m = 0;
|
||||||
mm = Min(fig,(m->Prec));
|
mm = Min(fig,(m->Prec));
|
||||||
*d = 0.0;
|
*d = 0.0;
|
||||||
|
@ -3435,7 +3476,7 @@ Exit:
|
||||||
printf(" DBLE_FIG = %ld\n", DBLE_FIG);
|
printf(" DBLE_FIG = %ld\n", DBLE_FIG);
|
||||||
}
|
}
|
||||||
#endif /*_DEBUG */
|
#endif /*_DEBUG */
|
||||||
return;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3479,7 +3520,7 @@ VpDtoV(Real *m, double d)
|
||||||
/* Now val = 0.xxxxx*BASE**ne */
|
/* Now val = 0.xxxxx*BASE**ne */
|
||||||
|
|
||||||
mm = m->MaxPrec;
|
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++) {
|
for(ind_m = 0;val > 0.0 && ind_m < mm;ind_m++) {
|
||||||
val *=(double)((S_INT)BASE);
|
val *=(double)((S_INT)BASE);
|
||||||
i =(U_LONG) val;
|
i =(U_LONG) val;
|
||||||
|
@ -3684,7 +3725,7 @@ Exit:
|
||||||
VP_EXPORT void
|
VP_EXPORT void
|
||||||
VpActiveRound(Real *y, Real *x, int f, int nf)
|
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 v;
|
||||||
U_LONG div;
|
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;
|
ix = (nf + ((int)BASE_FIG))/((int)BASE_FIG)-1;
|
||||||
if(ix<0 || ((U_LONG)ix)>=y->Prec) goto Exit; /* Unable to round */
|
if(ix<0 || ((U_LONG)ix)>=y->Prec) goto Exit; /* Unable to round */
|
||||||
ioffset = nf - ix*((int)BASE_FIG);
|
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); */
|
/* VpNmlz(y); */
|
||||||
v = y->frac[ix];
|
v = y->frac[ix];
|
||||||
/* drop digits after pointed digit */
|
/* drop digits after pointed digit */
|
||||||
|
@ -3929,6 +3970,7 @@ Exit:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_TRIAL_METHOD
|
||||||
/*
|
/*
|
||||||
* Calculates pi(=3.141592653589793238462........).
|
* Calculates pi(=3.141592653589793238462........).
|
||||||
*/
|
*/
|
||||||
|
@ -4216,6 +4258,7 @@ Exit:
|
||||||
VpFree(r);
|
VpFree(r);
|
||||||
VpFree(z);
|
VpFree(z);
|
||||||
}
|
}
|
||||||
|
#endif /* ENABLE_TRIAL_METHOD */
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
int
|
int
|
||||||
|
|
|
@ -131,7 +131,7 @@ 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 void VpToString(Real *a,char *psz,int fFmt);
|
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 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 VpDtoV(Real *m,double d);
|
||||||
VP_EXPORT void VpItoV(Real *m,S_INT ival);
|
VP_EXPORT void VpItoV(Real *m,S_INT ival);
|
||||||
VP_EXPORT int VpSqrt(Real *y,Real *x);
|
VP_EXPORT int VpSqrt(Real *y,Real *x);
|
||||||
|
|
|
@ -81,21 +81,29 @@ to create BigDecimal objects,the program would like:<BR>
|
||||||
<CODE><PRE>
|
<CODE><PRE>
|
||||||
require 'bigdecimal'
|
require 'bigdecimal'
|
||||||
a=BigDecimal::new("0.123456789123456789")
|
a=BigDecimal::new("0.123456789123456789")
|
||||||
b=BigDecimal::new("123456.78912345678",40)
|
b=BigDecimal("123456.78912345678",40)
|
||||||
c=a+b
|
c=a+b
|
||||||
</PRE></CODE>
|
</PRE></CODE>
|
||||||
|
|
||||||
<H3>List of methods</H3>
|
<H3>List of methods</H3>
|
||||||
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.
|
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.
|
This means the number of significant digits in BigDecimal is always a multiple of 4.
|
||||||
|
<P>
|
||||||
|
Some more methods are available in Ruby code (not C code).
|
||||||
|
To use them,just require util.rb as:
|
||||||
|
<PRE><CODE>
|
||||||
|
require "bigdecimal/util.rb"
|
||||||
|
</CODE></PRE>
|
||||||
|
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.
|
||||||
|
|
||||||
<H4><U>Class methods</U></H4>
|
<H4><U>Class methods</U></H4>
|
||||||
<UL>
|
<UL>
|
||||||
<LI><B>new</B></LI><BLOCKQUOTE>
|
<LI><B>new</B></LI><BLOCKQUOTE>
|
||||||
"new" method creates a new BigDecimal object.<BR>
|
"new" method creates a new BigDecimal object.<BR>
|
||||||
a=BigDecimal::new(s[,n])<BR>
|
a=BigDecimal::new(s[,n]) or<BR>
|
||||||
|
a=BigDecimal(s[,n]) or<BR>
|
||||||
where:<BR>
|
where:<BR>
|
||||||
s: Initial value string.<BR>
|
s: Initial value 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.
|
||||||
|
@ -187,18 +195,6 @@ Base value used in the BigDecimal calculation.
|
||||||
On 32 bits integer system,the value of BASE is 10000.<BR>
|
On 32 bits integer system,the value of BASE is 10000.<BR>
|
||||||
b = BigDecimal::BASE<BR>
|
b = BigDecimal::BASE<BR>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<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>
|
</UL>
|
||||||
|
|
||||||
<H4><U>Instance methods</U></H4>
|
<H4><U>Instance methods</U></H4>
|
||||||
|
@ -394,14 +390,15 @@ means a = 0.xxxxxxx*10**n.
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>to_f</B></LI><BLOCKQUOTE>
|
<LI><B>to_f</B></LI><BLOCKQUOTE>
|
||||||
same as dup method.
|
Creates a new Float object having (nearly) the same value.
|
||||||
creates a new BigDecimal object having same value.
|
Use split method if you want to convert by yourself.
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>sign</B></LI><BLOCKQUOTE>
|
<LI><B>sign</B></LI><BLOCKQUOTE>
|
||||||
returns the 'attribute' of a.
|
|
||||||
n = a.sign <BR>
|
n = a.sign <BR>
|
||||||
|
returns positive value if a > 0,negative value if a < 0,
|
||||||
|
otherwise zero if a == 0.<BR>
|
||||||
where the value of n means that a is:<BR>
|
where the value of n means that a is:<BR>
|
||||||
n = BigDecimal::SIGN_NaN(0) : a is NaN<BR>
|
n = BigDecimal::SIGN_NaN(0) : a is NaN<BR>
|
||||||
n = BigDecimal::SIGN_POSITIVE_ZERO(1) : a is +0<BR>
|
n = BigDecimal::SIGN_POSITIVE_ZERO(1) : a is +0<BR>
|
||||||
|
@ -455,28 +452,13 @@ where "0x112344" is the address,
|
||||||
'0.314E1' is the value,4 is the number of the significant digits,
|
'0.314E1' is the value,4 is the number of the significant digits,
|
||||||
and 12 is the maximum number of the significant digits
|
and 12 is the maximum number of the significant digits
|
||||||
the object can hold.
|
the object can hold.
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>dup</B></LI><BLOCKQUOTE>
|
|
||||||
creates a new BigDecimal object having same value.
|
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
<LI><B>sqrt</B></LI><BLOCKQUOTE>
|
<LI><B>sqrt</B></LI><BLOCKQUOTE>
|
||||||
c = a.sqrt(n)<BR>
|
c = a.sqrt(n)<BR>
|
||||||
computes square root value of a with significant digit number n at least.<BR>
|
computes square root value of a with significant digit number n at least.<BR>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
<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>
|
|
||||||
<LI><B>**</B></LI><BLOCKQUOTE>
|
<LI><B>**</B></LI><BLOCKQUOTE>
|
||||||
c = a ** n<BR>
|
c = a ** n<BR>
|
||||||
returns the value of a powered by n.
|
returns the value of a powered by n.
|
||||||
|
@ -507,6 +489,41 @@ same as ==,used in case statement.
|
||||||
<LI>></LI>
|
<LI>></LI>
|
||||||
<LI>>=</LI>
|
<LI>>=</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>
|
||||||
|
@ -521,7 +538,9 @@ same as ==,used in case statement.
|
||||||
BigDecimal object and the operation is performed,otherwise an error occures.</DD>
|
BigDecimal object and the operation is performed,otherwise an error occures.</DD>
|
||||||
</DL>
|
</DL>
|
||||||
|
|
||||||
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.
|
Translation stops without error at the character representing non digit.
|
||||||
For instance,"10XX" is translated to 10,"XXXX" is translated to 0.<BR>
|
For instance,"10XX" is translated to 10,"XXXX" is translated to 0.<BR>
|
||||||
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.<BR>
|
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.<BR>
|
||||||
|
|
|
@ -84,7 +84,7 @@ bigdecimal.c,bigdecimal.h
|
||||||
<PRE>
|
<PRE>
|
||||||
require 'bigdecimal'
|
require 'bigdecimal'
|
||||||
a=BigDecimal::new("0.123456789123456789")
|
a=BigDecimal::new("0.123456789123456789")
|
||||||
b=BigDecimal::new("123456.78912345678",40)
|
b=BigDecimal("123456.78912345678",40)
|
||||||
c=a+b
|
c=a+b
|
||||||
</PRE>
|
</PRE>
|
||||||
</CODE>
|
</CODE>
|
||||||
|
@ -92,18 +92,27 @@ c=a+b
|
||||||
というような感じで使用します。
|
というような感じで使用します。
|
||||||
|
|
||||||
<H3>メソッド一覧</H3>
|
<H3>メソッド一覧</H3>
|
||||||
以下のようなメソッドが利用可能です。<BR>
|
以下のメソッドが利用可能です。
|
||||||
記述上、BigDecimal オブジェクトを a,b,c,rで、String(文字列)オブジェクトを
|
「有効桁数」とは BigDecimal が精度を保証する桁数です。
|
||||||
s、整数を n で表記します。また、「有効桁数」とは BigDecimal が精度を保証する
|
ぴったりではありません、若干の余裕を持って計算されます。また、
|
||||||
桁数です。ぴったりではありません、若干の余裕を持って計算されます。また、
|
|
||||||
例えば32ビットのシステムでは10進で4桁毎に計算します。従って、現状では、
|
例えば32ビットのシステムでは10進で4桁毎に計算します。従って、現状では、
|
||||||
内部の「有効桁数」は4の倍数となっています。
|
内部の「有効桁数」は4の倍数となっています。
|
||||||
|
<P>
|
||||||
|
以下のメソッド以外にも、(C ではない) Ruby ソースの形で
|
||||||
|
提供されているものもあります。例えば、文字列から BigDecimal への
|
||||||
|
変換や、"0.xxxxxEn" という形式ではなく "nnnnn.mmmm" の形式の文字列
|
||||||
|
へ変換するメソッド等があります。利用するには
|
||||||
|
<PRE><CODE>
|
||||||
|
require "bigdecimal/util.rb"
|
||||||
|
</CODE></PRE>
|
||||||
|
のようにします。詳細は util.rb の内容を参照して下さい。
|
||||||
|
|
||||||
<H4><U>クラスメソッド</U></H4>
|
<H4><U>クラスメソッド</U></H4>
|
||||||
<UL>
|
<UL>
|
||||||
<LI><B>new</B></LI><BLOCKQUOTE>
|
<LI><B>new</B></LI><BLOCKQUOTE>
|
||||||
新しい BigDecimal オブジェクトを生成します。<BR>
|
新しい BigDecimal オブジェクトを生成します。<BR>
|
||||||
a=BigDecimal::new(s[,n])<BR>
|
a=BigDecimal::new(s[,n]) または<BR>
|
||||||
|
a=BigDecimal(s[,n])<BR>
|
||||||
s は初期値を文字列で指定します.
|
s は初期値を文字列で指定します.
|
||||||
n は必要な有効桁数(a の最大有効桁数)を整数で指定します。
|
n は必要な有効桁数(a の最大有効桁数)を整数で指定します。
|
||||||
n が 0 または省略されたときは、n の値は s の有効桁数とみなされます。
|
n が 0 または省略されたときは、n の値は s の有効桁数とみなされます。
|
||||||
|
@ -195,17 +204,6 @@ double_fig
|
||||||
内部で使用される基数の値です。整数が 32 ビットの処理系では10000です。<BR>
|
内部で使用される基数の値です。整数が 32 ビットの処理系では10000です。<BR>
|
||||||
b = BigDecimal::BASE<BR>
|
b = BigDecimal::BASE<BR>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<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....)を計算します(J.Machinの公式を用います)。<BR>
|
|
||||||
e = BigDecimal::PI(n)<BR>
|
|
||||||
n は必要な有効桁数を整数で指定します。
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
<H4><U>インスタンスメソッド</U></H4>
|
<H4><U>インスタンスメソッド</U></H4>
|
||||||
|
@ -374,8 +372,9 @@ i
|
||||||
a が Infinity や NaN のとき、i は nil になります。
|
a が Infinity や NaN のとき、i は nil になります。
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>to_f</B></LI><BLOCKQUOTE>
|
<LI><B>to_f</B></LI><BLOCKQUOTE>
|
||||||
dup と全く同じです。
|
Float オブジェクトに変換します。
|
||||||
同じ値の BigDecimal オブジェクトを生成します。
|
よりきめ細かい値が必要ならば split メソッドを利用して
|
||||||
|
ください。
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
|
<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
|
||||||
文字列に変換します("0.xxxxxEn"の形になります)。<BR>
|
文字列に変換します("0.xxxxxEn"の形になります)。<BR>
|
||||||
|
@ -391,7 +390,7 @@ n = a.exponent <BR>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<LI><B>sign</B></LI><BLOCKQUOTE>
|
<LI><B>sign</B></LI><BLOCKQUOTE>
|
||||||
値の属性を返します。
|
値が正(sign > 0)、負(sign < 0)、その他(sigh==0)であるかの情報を返します。
|
||||||
n = a.sign <BR>
|
n = a.sign <BR>
|
||||||
としたとき n の値は a が以下のときを意味します。<BR>
|
としたとき n の値は a が以下のときを意味します。<BR>
|
||||||
() の中の数字は、実際の値です(<A HREF="#STRUCT">「内部構造」</A>を参照)。<BR>
|
() の中の数字は、実際の値です(<A HREF="#STRUCT">「内部構造」</A>を参照)。<BR>
|
||||||
|
@ -443,28 +442,6 @@ p a=BigDecimal::new("3.14",10)<BR>
|
||||||
最初の16進数はオブジェクトのアドレス、次の '0.314E1' は値、
|
最初の16進数はオブジェクトのアドレス、次の '0.314E1' は値、
|
||||||
次の4は現在の有効桁数(表示より若干大きいことがあります)、
|
次の4は現在の有効桁数(表示より若干大きいことがあります)、
|
||||||
最後はオブジェクトが取り得る最大桁数になります。
|
最後はオブジェクトが取り得る最大桁数になります。
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
<LI><B>dup</B></LI><BLOCKQUOTE>
|
|
||||||
同じ値の BigDecimal オブジェクトを生成します。
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
<LI><B>sqrt</B></LI><BLOCKQUOTE>
|
|
||||||
aの有効桁 n 桁の平方根(n の平方根ではありません)。
|
|
||||||
これまた、正直にニュートン法で計算します。<BR>
|
|
||||||
c = a.sqrt(n)<BR>
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
<LI><B>sincos</B></LI><BLOCKQUOTE>
|
|
||||||
a の有効桁 n 桁の sin と cos を同時に(テイラー展開で)計算して、
|
|
||||||
sin と cos の配列を返します。
|
|
||||||
n は必要な有効桁数です( n の sin や cos を計算するわけではありません)。
|
|
||||||
<BR>
|
|
||||||
sin,cos = a.sincos(n)<BR>
|
|
||||||
|a|<2*3.1415....でないと正しい答えを計算できないこともあります。
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
<LI><B>exp</B></LI><BLOCKQUOTE>
|
|
||||||
自然対数の底e(=2.718281828....)の a 乗を計算します。<BR>
|
|
||||||
c = a.exp(n)<BR>
|
|
||||||
n は必要な有効桁数です。
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>**</B></LI><BLOCKQUOTE>
|
<LI><B>**</B></LI><BLOCKQUOTE>
|
||||||
a の n 乗を計算します。nは整数。<BR>
|
a の n 乗を計算します。nは整数。<BR>
|
||||||
|
@ -476,6 +453,11 @@ c = a ** n<BR>
|
||||||
c = a.power(n)<BR>
|
c = a.power(n)<BR>
|
||||||
結果として c の有効桁は a の n 倍以上になるので注意。
|
結果として c の有効桁は a の n 倍以上になるので注意。
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
<LI><B>sqrt</B></LI><BLOCKQUOTE>
|
||||||
|
aの有効桁 n 桁の平方根(n の平方根ではありません)を
|
||||||
|
ニュートン法で計算します。<BR>
|
||||||
|
c = a.sqrt(n)<BR>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<LI><B><=></B></LI><BLOCKQUOTE>
|
<LI><B><=></B></LI><BLOCKQUOTE>
|
||||||
a==b なら 0、a > b なら 1、a < b なら -1 になります。<BR>
|
a==b なら 0、a > b なら 1、a < b なら -1 になります。<BR>
|
||||||
|
@ -493,11 +475,56 @@ c = a <=> b
|
||||||
<LI><B>></B></LI>
|
<LI><B>></B></LI>
|
||||||
<LI><B>>=</B></LI>
|
<LI><B>>=</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....)を計算します(J.Machinの公式を用います)。<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| < 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 に変換してから計算します。
|
||||||
従って、BigDecimal オブジェクト以外でも数値を意味するものなら右に置けば
|
従って、BigDecimal オブジェクト以外でも数値を意味するものなら右に置けば
|
||||||
演算は可能です。<BR><BR>
|
演算は可能です。<BR>
|
||||||
|
ただし、文字列は(通常)数値に自動変換することはできません。
|
||||||
|
文字列を数値に自動変換に自動変換したい場合は bigfloat.c の
|
||||||
|
「/* #define ENABLE_NUMERIC_STRING */」のコメントを外してから、
|
||||||
|
再コンパイル、再インストールする必要があります。
|
||||||
文字列で数値を与える場合は注意が必要です。数値に変換できない文字があると、
|
文字列で数値を与える場合は注意が必要です。数値に変換できない文字があると、
|
||||||
単に変換を止めるだけでエラーにはなりません。"10XX"なら10、"XXXX"は0
|
単に変換を止めるだけでエラーにはなりません。"10XX"なら10、"XXXX"は0
|
||||||
と扱われます。<BR>
|
と扱われます。<BR>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче