mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/bigdecimal/bigdecimal.c, ext/bigdecimal/bigdecimal.h, ext/bigdecimal/extconf.rb: BASE and BASE_FIG are defined based on the size of BDIGIT and renamed.
* ext/bigdecimal/bigdecimal.c, ext/bigdecimal/bigdecimal.h: use BDIGIT for Real#frac. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@28947 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
678af70ce8
commit
7694956ef7
4 changed files with 285 additions and 298 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
Tue Aug 10 15:24:30 2010 Kenta Murata <mrkn@mrkn.jp>
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c, ext/bigdecimal/bigdecimal.h,
|
||||||
|
ext/bigdecimal/extconf.rb: BASE and BASE_FIG are defined
|
||||||
|
based on the size of BDIGIT.
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c, ext/bigdecimal/bigdecimal.h:
|
||||||
|
use BDIGIT for Real#frac.
|
||||||
|
|
||||||
Tue Aug 10 15:19:45 2010 Kenta Murata <mrkn@mrkn.jp>
|
Tue Aug 10 15:19:45 2010 Kenta Murata <mrkn@mrkn.jp>
|
||||||
|
|
||||||
* ext/bigdecimal/bigdecimal.h, ext/bigdecimal/bigdecimal.c:
|
* ext/bigdecimal/bigdecimal.h, ext/bigdecimal/bigdecimal.c:
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//#define BIGDECIMAL_DEBUG 1
|
||||||
#include "bigdecimal.h"
|
#include "bigdecimal.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -20,7 +21,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <float.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
|
@ -38,20 +38,12 @@ VALUE rb_cBigDecimal;
|
||||||
#define SAVE(p) PUSH(p->obj);
|
#define SAVE(p) PUSH(p->obj);
|
||||||
#define GUARD_OBJ(p,y) {p=y;SAVE(p);}
|
#define GUARD_OBJ(p,y) {p=y;SAVE(p);}
|
||||||
|
|
||||||
#ifndef BASE_FIG
|
#define BASE_FIG RMPD_COMPONENT_FIGURES
|
||||||
static U_LONG BASE_FIG = 4; /* =log10(BASE) */
|
#define BASE RMPD_BASE
|
||||||
static U_LONG BASE = 10000L; /* Base value(value must be 10**BASE_FIG) */
|
|
||||||
/* The value of BASE**2 + BASE must be represented */
|
|
||||||
/* within one U_LONG. */
|
|
||||||
static U_LONG HALF_BASE = 5000L;/* =BASE/2 */
|
|
||||||
static U_LONG BASE1 = 1000L; /* =BASE/10 */
|
|
||||||
#else
|
|
||||||
#ifndef BASE
|
|
||||||
#error BASE_FIG is defined but BASE is not
|
|
||||||
#endif
|
|
||||||
#define HALF_BASE (BASE/2)
|
#define HALF_BASE (BASE/2)
|
||||||
#define BASE1 (BASE/10)
|
#define BASE1 (BASE/10)
|
||||||
#endif
|
|
||||||
#ifndef DBLE_FIG
|
#ifndef DBLE_FIG
|
||||||
#define DBLE_FIG (DBL_DIG+1) /* figure of double */
|
#define DBLE_FIG (DBL_DIG+1) /* figure of double */
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,7 +74,7 @@ BigDecimal_version(VALUE self)
|
||||||
*/
|
*/
|
||||||
static unsigned short VpGetException(void);
|
static unsigned short VpGetException(void);
|
||||||
static void VpSetException(unsigned short f);
|
static void VpSetException(unsigned short f);
|
||||||
static void VpInternalRound(Real *c,U_LONG ixDigit,U_LONG vPrev,U_LONG v);
|
static void VpInternalRound(Real *c, U_LONG ixDigit, BDIGIT vPrev, BDIGIT v);
|
||||||
static int VpLimitRound(Real *c, U_LONG ixDigit);
|
static int VpLimitRound(Real *c, U_LONG ixDigit);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -99,7 +91,7 @@ static size_t
|
||||||
BigDecimal_memsize(const void *ptr)
|
BigDecimal_memsize(const void *ptr)
|
||||||
{
|
{
|
||||||
const Real *pv = ptr;
|
const Real *pv = ptr;
|
||||||
return pv ? (sizeof(*pv) + pv->MaxPrec * sizeof(U_LONG)) : 0;
|
return pv ? (sizeof(*pv) + pv->MaxPrec * sizeof(BDIGIT)) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const rb_data_type_t BigDecimal_data_type = {
|
static const rb_data_type_t BigDecimal_data_type = {
|
||||||
|
@ -225,10 +217,10 @@ BigDecimal_hash(VALUE self)
|
||||||
st_index_t hash;
|
st_index_t hash;
|
||||||
|
|
||||||
GUARD_OBJ(p,GetVpValue(self,1));
|
GUARD_OBJ(p,GetVpValue(self,1));
|
||||||
hash = (U_LONG)p->sign;
|
hash = (st_index_t)p->sign;
|
||||||
/* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */
|
/* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */
|
||||||
if(hash == 2 || hash == (st_index_t)-2) {
|
if(hash == 2 || hash == (st_index_t)-2) {
|
||||||
hash ^= rb_memhash(p->frac, sizeof(U_LONG)*p->Prec);
|
hash ^= rb_memhash(p->frac, sizeof(BDIGIT)*p->Prec);
|
||||||
hash += p->exponent;
|
hash += p->exponent;
|
||||||
}
|
}
|
||||||
return INT2FIX(hash);
|
return INT2FIX(hash);
|
||||||
|
@ -479,7 +471,8 @@ static VALUE
|
||||||
BigDecimal_to_i(VALUE self)
|
BigDecimal_to_i(VALUE self)
|
||||||
{
|
{
|
||||||
ENTER(5);
|
ENTER(5);
|
||||||
S_LONG e,nf;
|
S_LONG e;
|
||||||
|
S_LONG nf;
|
||||||
Real *p;
|
Real *p;
|
||||||
|
|
||||||
GUARD_OBJ(p,GetVpValue(self,1));
|
GUARD_OBJ(p,GetVpValue(self,1));
|
||||||
|
@ -489,8 +482,7 @@ BigDecimal_to_i(VALUE self)
|
||||||
if(e<=0) return INT2FIX(0);
|
if(e<=0) return INT2FIX(0);
|
||||||
nf = VpBaseFig();
|
nf = VpBaseFig();
|
||||||
if(e<=nf) {
|
if(e<=nf) {
|
||||||
e = VpGetSign(p)*p->frac[0];
|
return LONG2NUM(VpGetSign(p)*(BDIGIT_DBL_SIGNED)p->frac[0]);
|
||||||
return INT2FIX(e);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE a = BigDecimal_split(self);
|
VALUE a = BigDecimal_split(self);
|
||||||
|
@ -911,7 +903,7 @@ BigDecimal_div(VALUE self, VALUE r)
|
||||||
*/
|
*/
|
||||||
/* Round */
|
/* Round */
|
||||||
if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
|
if(VpHasVal(div)) { /* frac[0] must be zero for NaN,INF,Zero */
|
||||||
VpInternalRound(c,0,c->frac[c->Prec-1],(VpBaseVal()*res->frac[0])/div->frac[0]);
|
VpInternalRound(c, 0, c->frac[c->Prec-1], (BDIGIT)(VpBaseVal()*(BDIGIT_DBL)res->frac[0]/div->frac[0]));
|
||||||
}
|
}
|
||||||
return ToValue(c);
|
return ToValue(c);
|
||||||
}
|
}
|
||||||
|
@ -1413,6 +1405,9 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
|
||||||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||||
VpSetPrecLimit(pl);
|
VpSetPrecLimit(pl);
|
||||||
VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);
|
VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);
|
||||||
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
|
VPrint(stderr, "floor: c=%\n", c);
|
||||||
|
#endif
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
return BigDecimal_to_i(ToValue(c));
|
return BigDecimal_to_i(ToValue(c));
|
||||||
}
|
}
|
||||||
|
@ -2113,9 +2108,9 @@ static Real *VpPt5; /* constant 0.5 */
|
||||||
|
|
||||||
static int VpIsDefOP(Real *c,Real *a,Real *b,int sw);
|
static int VpIsDefOP(Real *c,Real *a,Real *b,int sw);
|
||||||
static int AddExponent(Real *a,S_INT n);
|
static int AddExponent(Real *a,S_INT n);
|
||||||
static U_LONG VpAddAbs(Real *a,Real *b,Real *c);
|
static BDIGIT VpAddAbs(Real *a,Real *b,Real *c);
|
||||||
static U_LONG VpSubAbs(Real *a,Real *b,Real *c);
|
static BDIGIT VpSubAbs(Real *a,Real *b,Real *c);
|
||||||
static U_LONG VpSetPTR(Real *a,Real *b,Real *c,U_LONG *a_pos,U_LONG *b_pos,U_LONG *c_pos,U_LONG *av,U_LONG *bv);
|
static U_LONG VpSetPTR(Real *a,Real *b,Real *c,U_LONG *a_pos,U_LONG *b_pos,U_LONG *c_pos, BDIGIT *av, BDIGIT *bv);
|
||||||
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);
|
||||||
|
@ -2235,24 +2230,6 @@ One(void)
|
||||||
return gOne_ABCED9B4_CE73__00400511F31D;
|
return gOne_ABCED9B4_CE73__00400511F31D;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT U_LONG
|
|
||||||
VpBaseFig(void)
|
|
||||||
{
|
|
||||||
return BASE_FIG;
|
|
||||||
}
|
|
||||||
|
|
||||||
VP_EXPORT U_LONG
|
|
||||||
VpDblFig(void)
|
|
||||||
{
|
|
||||||
return DBLE_FIG;
|
|
||||||
}
|
|
||||||
|
|
||||||
VP_EXPORT U_LONG
|
|
||||||
VpBaseVal(void)
|
|
||||||
{
|
|
||||||
return BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
Value of sign in Real structure is reserved for future use.
|
Value of sign in Real structure is reserved for future use.
|
||||||
|
@ -2485,10 +2462,10 @@ VpNumOfChars(Real *vp,const char *pszFmt)
|
||||||
* by one U_LONG word(LONG) in the computer used.
|
* by one U_LONG word(LONG) in the computer used.
|
||||||
*
|
*
|
||||||
* [Returns]
|
* [Returns]
|
||||||
* DBLE_FIG ... OK
|
* 1+DBL_DIG ... OK
|
||||||
*/
|
*/
|
||||||
VP_EXPORT U_LONG
|
VP_EXPORT size_t
|
||||||
VpInit(U_LONG BaseVal)
|
VpInit(BDIGIT BaseVal)
|
||||||
{
|
{
|
||||||
/* Setup +/- Inf NaN -0 */
|
/* Setup +/- Inf NaN -0 */
|
||||||
VpGetDoubleNaN();
|
VpGetDoubleNaN();
|
||||||
|
@ -2496,27 +2473,6 @@ VpInit(U_LONG BaseVal)
|
||||||
VpGetDoubleNegInf();
|
VpGetDoubleNegInf();
|
||||||
VpGetDoubleNegZero();
|
VpGetDoubleNegZero();
|
||||||
|
|
||||||
#ifndef BASE_FIG
|
|
||||||
if(BaseVal <= 0) {
|
|
||||||
U_LONG w;
|
|
||||||
/* Base <= 0, then determine Base by calcuration. */
|
|
||||||
BASE = 1;
|
|
||||||
while(
|
|
||||||
(BASE > 0) &&
|
|
||||||
((w = BASE *(BASE + 1)) > BASE) &&((w / BASE) ==(BASE + 1))
|
|
||||||
) {
|
|
||||||
BaseVal = BASE;
|
|
||||||
BASE = BaseVal * 10L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Set Base Values */
|
|
||||||
BASE = BaseVal;
|
|
||||||
HALF_BASE = BASE / 2;
|
|
||||||
BASE1 = BASE / 10;
|
|
||||||
BASE_FIG = 0;
|
|
||||||
while(BaseVal /= 10) ++BASE_FIG;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Allocates Vp constants. */
|
/* Allocates Vp constants. */
|
||||||
VpConstOne = VpAlloc((U_LONG)1, "1");
|
VpConstOne = VpAlloc((U_LONG)1, "1");
|
||||||
VpPt5 = VpAlloc((U_LONG)1, ".5");
|
VpPt5 = VpAlloc((U_LONG)1, ".5");
|
||||||
|
@ -2531,12 +2487,12 @@ VpInit(U_LONG BaseVal)
|
||||||
printf(" BASE = %lu\n", BASE);
|
printf(" BASE = %lu\n", BASE);
|
||||||
printf(" HALF_BASE = %lu\n", HALF_BASE);
|
printf(" HALF_BASE = %lu\n", HALF_BASE);
|
||||||
printf(" BASE1 = %lu\n", BASE1);
|
printf(" BASE1 = %lu\n", BASE1);
|
||||||
printf(" BASE_FIG = %d\n", BASE_FIG);
|
printf(" BASE_FIG = %u\n", BASE_FIG);
|
||||||
printf(" DBLE_FIG = %d\n", DBLE_FIG);
|
printf(" DBLE_FIG = %d\n", DBLE_FIG);
|
||||||
}
|
}
|
||||||
#endif /* BIGDECIMAL_DEBUG */
|
#endif /* BIGDECIMAL_DEBUG */
|
||||||
|
|
||||||
return DBLE_FIG;
|
return rmpd_double_figures();
|
||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT Real *
|
VP_EXPORT Real *
|
||||||
|
@ -2554,13 +2510,13 @@ AddExponent(Real *a,S_INT n)
|
||||||
S_INT eb,mb;
|
S_INT eb,mb;
|
||||||
if(e>0) {
|
if(e>0) {
|
||||||
if(n>0) {
|
if(n>0) {
|
||||||
mb = m*BASE_FIG;
|
mb = m*(S_INT)BASE_FIG;
|
||||||
eb = e*BASE_FIG;
|
eb = e*(S_INT)BASE_FIG;
|
||||||
if(mb<eb) goto overflow;
|
if(mb<eb) goto overflow;
|
||||||
}
|
}
|
||||||
} else if(n<0) {
|
} else if(n<0) {
|
||||||
mb = m*BASE_FIG;
|
mb = m*(S_INT)BASE_FIG;
|
||||||
eb = e*BASE_FIG;
|
eb = e*(S_INT)BASE_FIG;
|
||||||
if(mb>eb) goto underflow;
|
if(mb>eb) goto underflow;
|
||||||
}
|
}
|
||||||
a->exponent = m;
|
a->exponent = m;
|
||||||
|
@ -2609,14 +2565,16 @@ VpAlloc(U_LONG mx, const char *szVal)
|
||||||
mx = mf;
|
mx = mf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
++szVal;
|
++szVal;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
/* necessary to be able to store */
|
/* necessary to be able to store */
|
||||||
/* at least mx digits. */
|
/* at least mx digits. */
|
||||||
/* szVal==NULL ==> allocate zero value. */
|
/* szVal==NULL ==> allocate zero value. */
|
||||||
vp = (Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(U_LONG));
|
vp = (Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(BDIGIT));
|
||||||
/* xmalloc() alway returns(or throw interruption) */
|
/* xmalloc() alway returns(or throw interruption) */
|
||||||
vp->MaxPrec = mx; /* set max precision */
|
vp->MaxPrec = mx; /* set max precision */
|
||||||
VpSetZero(vp,1); /* initialize vp to zero. */
|
VpSetZero(vp,1); /* initialize vp to zero. */
|
||||||
|
@ -2636,10 +2594,11 @@ VpAlloc(U_LONG mx, const char *szVal)
|
||||||
psz[i] = 0;
|
psz[i] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++i; ++ipn;
|
++i;
|
||||||
|
++ipn;
|
||||||
}
|
}
|
||||||
/* Skip trailing spaces */
|
/* Skip trailing spaces */
|
||||||
while((--i)>0) {
|
while (--i > 0) {
|
||||||
if (ISSPACE(psz[i])) psz[i] = 0;
|
if (ISSPACE(psz[i])) psz[i] = 0;
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
|
@ -2648,19 +2607,19 @@ VpAlloc(U_LONG mx, const char *szVal)
|
||||||
/* 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 ) {
|
||||||
vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(U_LONG));
|
vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(BDIGIT));
|
||||||
vp->MaxPrec = 1; /* set max precision */
|
vp->MaxPrec = 1; /* set max precision */
|
||||||
VpSetPosInf(vp);
|
VpSetPosInf(vp);
|
||||||
return vp;
|
return vp;
|
||||||
}
|
}
|
||||||
if (StrCmp(szVal, SZ_NINF) == 0) {
|
if (StrCmp(szVal, SZ_NINF) == 0) {
|
||||||
vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(U_LONG));
|
vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(BDIGIT));
|
||||||
vp->MaxPrec = 1; /* set max precision */
|
vp->MaxPrec = 1; /* set max precision */
|
||||||
VpSetNegInf(vp);
|
VpSetNegInf(vp);
|
||||||
return vp;
|
return vp;
|
||||||
}
|
}
|
||||||
if (StrCmp(szVal, SZ_NaN) == 0) {
|
if (StrCmp(szVal, SZ_NaN) == 0) {
|
||||||
vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(U_LONG));
|
vp = (Real *) VpMemAlloc(sizeof(Real) + sizeof(BDIGIT));
|
||||||
vp->MaxPrec = 1; /* set max precision */
|
vp->MaxPrec = 1; /* set max precision */
|
||||||
VpSetNaN(vp);
|
VpSetNaN(vp);
|
||||||
return vp;
|
return vp;
|
||||||
|
@ -2695,11 +2654,10 @@ VpAlloc(U_LONG mx, const char *szVal)
|
||||||
ipe = 0; /* Exponent */
|
ipe = 0; /* Exponent */
|
||||||
|
|
||||||
switch (szVal[i]) {
|
switch (szVal[i]) {
|
||||||
case '\0': break;
|
case '\0':
|
||||||
case 'e':
|
break;
|
||||||
case 'E':
|
case 'e': case 'E':
|
||||||
case 'd':
|
case 'd': case 'D':
|
||||||
case 'D':
|
|
||||||
++i;
|
++i;
|
||||||
ipe = i;
|
ipe = i;
|
||||||
v = szVal[i];
|
v = szVal[i];
|
||||||
|
@ -2719,11 +2677,11 @@ VpAlloc(U_LONG mx, const char *szVal)
|
||||||
if (mx <= 0) mx = 1;
|
if (mx <= 0) mx = 1;
|
||||||
nalloc = Max(nalloc, mx);
|
nalloc = Max(nalloc, mx);
|
||||||
mx = nalloc;
|
mx = nalloc;
|
||||||
vp =(Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(U_LONG));
|
vp = (Real *) VpMemAlloc(sizeof(Real) + mx * sizeof(BDIGIT));
|
||||||
/* xmalloc() alway returns(or throw interruption) */
|
/* xmalloc() alway returns(or throw interruption) */
|
||||||
vp->MaxPrec = mx; /* set max precision */
|
vp->MaxPrec = mx; /* set max precision */
|
||||||
VpSetZero(vp, sign);
|
VpSetZero(vp, sign);
|
||||||
VpCtoV(vp, &(szVal[ipn]), ni, &(szVal[ipf]), nf, &(szVal[ipe]), ne);
|
VpCtoV(vp, &szVal[ipn], ni, &szVal[ipf], nf, &szVal[ipe], ne);
|
||||||
rb_str_resize(buf, 0);
|
rb_str_resize(buf, 0);
|
||||||
return vp;
|
return vp;
|
||||||
}
|
}
|
||||||
|
@ -2759,7 +2717,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;
|
||||||
memcpy(c->frac, a->frac, n * sizeof(U_LONG));
|
memcpy(c->frac, a->frac, n * sizeof(BDIGIT));
|
||||||
/* Needs round ? */
|
/* Needs round ? */
|
||||||
if(isw!=10) {
|
if(isw!=10) {
|
||||||
/* Not in ActiveRound */
|
/* Not in ActiveRound */
|
||||||
|
@ -2788,7 +2746,7 @@ VpAddSub(Real *c, Real *a, Real *b, int operation)
|
||||||
S_INT sw, isw;
|
S_INT sw, isw;
|
||||||
Real *a_ptr, *b_ptr;
|
Real *a_ptr, *b_ptr;
|
||||||
U_LONG n, na, nb, i;
|
U_LONG n, na, nb, i;
|
||||||
U_LONG mrv;
|
BDIGIT mrv;
|
||||||
|
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
if(gfDebug) {
|
if(gfDebug) {
|
||||||
|
@ -2910,18 +2868,17 @@ end_if:
|
||||||
* a and b assuming abs(a)>abs(b).
|
* a and b assuming abs(a)>abs(b).
|
||||||
* c = abs(a) + abs(b) ; where |a|>=|b|
|
* c = abs(a) + abs(b) ; where |a|>=|b|
|
||||||
*/
|
*/
|
||||||
static U_LONG
|
static BDIGIT
|
||||||
VpAddAbs(Real *a, Real *b, Real *c)
|
VpAddAbs(Real *a, Real *b, Real *c)
|
||||||
{
|
{
|
||||||
U_LONG word_shift;
|
U_LONG word_shift;
|
||||||
U_LONG carry;
|
|
||||||
U_LONG ap;
|
U_LONG ap;
|
||||||
U_LONG bp;
|
U_LONG bp;
|
||||||
U_LONG cp;
|
U_LONG cp;
|
||||||
U_LONG a_pos;
|
U_LONG a_pos;
|
||||||
U_LONG b_pos;
|
U_LONG b_pos, b_pos_with_word_shift;
|
||||||
U_LONG c_pos;
|
U_LONG c_pos;
|
||||||
U_LONG av, bv, mrv;
|
BDIGIT av, bv, carry, mrv;
|
||||||
|
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
if(gfDebug) {
|
if(gfDebug) {
|
||||||
|
@ -2953,8 +2910,8 @@ VpAddAbs(Real *a, Real *b, Real *c)
|
||||||
|
|
||||||
/* Just assign the last few digits of a to c because b has no */
|
/* Just assign the last few digits of a to c because b has no */
|
||||||
/* corresponding digits to be added. */
|
/* corresponding digits to be added. */
|
||||||
bv = b_pos + word_shift;
|
b_pos_with_word_shift = b_pos + word_shift;
|
||||||
while(a_pos > bv) {
|
while(a_pos > b_pos_with_word_shift) {
|
||||||
c->frac[--c_pos] = a->frac[--a_pos];
|
c->frac[--c_pos] = a->frac[--a_pos];
|
||||||
}
|
}
|
||||||
carry = 0; /* set first carry be zero */
|
carry = 0; /* set first carry be zero */
|
||||||
|
@ -3002,19 +2959,17 @@ Exit:
|
||||||
/*
|
/*
|
||||||
* c = abs(a) - abs(b)
|
* c = abs(a) - abs(b)
|
||||||
*/
|
*/
|
||||||
static U_LONG
|
static BDIGIT
|
||||||
VpSubAbs(Real *a, Real *b, Real *c)
|
VpSubAbs(Real *a, Real *b, Real *c)
|
||||||
{
|
{
|
||||||
U_LONG word_shift;
|
U_LONG word_shift;
|
||||||
U_LONG mrv;
|
|
||||||
U_LONG borrow;
|
|
||||||
U_LONG ap;
|
U_LONG ap;
|
||||||
U_LONG bp;
|
U_LONG bp;
|
||||||
U_LONG cp;
|
U_LONG cp;
|
||||||
U_LONG a_pos;
|
U_LONG a_pos;
|
||||||
U_LONG b_pos;
|
U_LONG b_pos, b_pos_with_word_shift;
|
||||||
U_LONG c_pos;
|
U_LONG c_pos;
|
||||||
U_LONG av, bv;
|
BDIGIT av, bv, borrow, mrv;
|
||||||
|
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
if(gfDebug) {
|
if(gfDebug) {
|
||||||
|
@ -3056,8 +3011,8 @@ VpSubAbs(Real *a, Real *b, Real *c)
|
||||||
/* Just assign the last few digits of a to c because b has no */
|
/* Just assign the last few digits of a to c because b has no */
|
||||||
/* corresponding digits to subtract. */
|
/* corresponding digits to subtract. */
|
||||||
|
|
||||||
bv = b_pos + word_shift;
|
b_pos_with_word_shift = b_pos + word_shift;
|
||||||
while(a_pos > bv) {
|
while(a_pos > b_pos_with_word_shift) {
|
||||||
c->frac[--c_pos] = a->frac[--a_pos];
|
c->frac[--c_pos] = a->frac[--a_pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3117,7 +3072,7 @@ Exit:
|
||||||
* c_pos = |
|
* c_pos = |
|
||||||
*/
|
*/
|
||||||
static U_LONG
|
static U_LONG
|
||||||
VpSetPTR(Real *a, Real *b, Real *c, U_LONG *a_pos, U_LONG *b_pos, U_LONG *c_pos, U_LONG *av, U_LONG *bv)
|
VpSetPTR(Real *a, Real *b, Real *c, U_LONG *a_pos, U_LONG *b_pos, U_LONG *c_pos, BDIGIT *av, BDIGIT *bv)
|
||||||
{
|
{
|
||||||
U_LONG left_word, right_word, word_shift;
|
U_LONG left_word, right_word, word_shift;
|
||||||
c->frac[0] = 0;
|
c->frac[0] = 0;
|
||||||
|
@ -3217,7 +3172,8 @@ VpMult(Real *c, Real *a, Real *b)
|
||||||
U_LONG MxIndA, MxIndB, MxIndAB, MxIndC;
|
U_LONG MxIndA, MxIndB, MxIndAB, MxIndC;
|
||||||
U_LONG ind_c, i, ii, nc;
|
U_LONG ind_c, i, ii, nc;
|
||||||
U_LONG ind_as, ind_ae, ind_bs, ind_be;
|
U_LONG ind_as, ind_ae, ind_bs, ind_be;
|
||||||
U_LONG Carry, s;
|
BDIGIT carry;
|
||||||
|
BDIGIT_DBL s;
|
||||||
Real *w;
|
Real *w;
|
||||||
|
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
|
@ -3269,9 +3225,9 @@ VpMult(Real *c, Real *a, Real *b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
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;
|
||||||
memset(c->frac, 0, (nc + 1) * sizeof(U_LONG)); /* Initialize c */
|
memset(c->frac, 0, (nc + 1) * sizeof(BDIGIT)); /* 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. */
|
||||||
|
@ -3292,22 +3248,22 @@ VpMult(Real *c, Real *a, Real *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = ind_as; i <= ind_ae; ++i) {
|
for(i = ind_as; i <= ind_ae; ++i) {
|
||||||
s =((a->frac[i]) *(b->frac[ind_bs--]));
|
s = (BDIGIT_DBL)a->frac[i] * b->frac[ind_bs--];
|
||||||
Carry = s / BASE;
|
carry = (BDIGIT)(s / BASE);
|
||||||
s = s -(Carry * BASE);
|
s -= (BDIGIT_DBL)carry * BASE;
|
||||||
c->frac[ind_c] += s;
|
c->frac[ind_c] += (BDIGIT)s;
|
||||||
if(c->frac[ind_c] >= BASE) {
|
if(c->frac[ind_c] >= BASE) {
|
||||||
s = c->frac[ind_c] / BASE;
|
s = c->frac[ind_c] / BASE;
|
||||||
Carry += s;
|
carry += (BDIGIT)s;
|
||||||
c->frac[ind_c] -= (s * BASE);
|
c->frac[ind_c] -= (BDIGIT)(s * BASE);
|
||||||
}
|
}
|
||||||
if(Carry) {
|
if(carry) {
|
||||||
ii = ind_c;
|
ii = ind_c;
|
||||||
while(ii-- > 0) {
|
while(ii-- > 0) {
|
||||||
c->frac[ii] += Carry;
|
c->frac[ii] += carry;
|
||||||
if(c->frac[ii] >= BASE) {
|
if(c->frac[ii] >= BASE) {
|
||||||
Carry = c->frac[ii] / BASE;
|
carry = c->frac[ii] / BASE;
|
||||||
c->frac[ii] -=(Carry * BASE);
|
c->frac[ii] -= (carry * BASE);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3344,8 +3300,9 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
|
||||||
U_LONG word_a, word_b, word_c, word_r;
|
U_LONG word_a, word_b, word_c, word_r;
|
||||||
U_LONG i, n, ind_a, ind_b, ind_c, ind_r;
|
U_LONG i, n, ind_a, ind_b, ind_c, ind_r;
|
||||||
U_LONG nLoop;
|
U_LONG nLoop;
|
||||||
U_LONG q, b1, b1p1, b1b2, b1b2p1, r1r2;
|
BDIGIT_DBL q, b1, b1p1, b1b2, b1b2p1, r1r2;
|
||||||
U_LONG borrow, borrow1, borrow2, qb;
|
BDIGIT borrow, borrow1, borrow2;
|
||||||
|
BDIGIT_DBL qb;
|
||||||
|
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
if(gfDebug) {
|
if(gfDebug) {
|
||||||
|
@ -3416,7 +3373,7 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
|
||||||
++ind_c;
|
++ind_c;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
r1r2 = r->frac[ind_c] * BASE + r->frac[ind_c + 1];
|
r1r2 = (BDIGIT_DBL)r->frac[ind_c] * BASE + r->frac[ind_c + 1];
|
||||||
if(r1r2 == b1b2) {
|
if(r1r2 == b1b2) {
|
||||||
/* The first two word digits is the same */
|
/* The first two word digits is the same */
|
||||||
ind_b = 2;
|
ind_b = 2;
|
||||||
|
@ -3446,22 +3403,22 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
|
||||||
--ind_r;
|
--ind_r;
|
||||||
--ind_b;
|
--ind_b;
|
||||||
}
|
}
|
||||||
++(c->frac[ind_c]);
|
++c->frac[ind_c];
|
||||||
goto carry;
|
goto carry;
|
||||||
}
|
}
|
||||||
/* The first two word digits is not the same, */
|
/* The first two word digits is not the same, */
|
||||||
/* then compare magnitude, and divide actually. */
|
/* then compare magnitude, and divide actually. */
|
||||||
if(r1r2 >= b1b2p1) {
|
if(r1r2 >= b1b2p1) {
|
||||||
q = r1r2 / b1b2p1;
|
q = r1r2 / b1b2p1; /* q == (BDIGIT)q */
|
||||||
c->frac[ind_c] += q;
|
c->frac[ind_c] += (BDIGIT)q;
|
||||||
ind_r = b->Prec + ind_c - 1;
|
ind_r = b->Prec + ind_c - 1;
|
||||||
goto sub_mult;
|
goto sub_mult;
|
||||||
}
|
}
|
||||||
|
|
||||||
div_b1p1:
|
div_b1p1:
|
||||||
if(ind_c + 1 >= word_c) goto out_side;
|
if(ind_c + 1 >= word_c) goto out_side;
|
||||||
q = r1r2 / b1p1;
|
q = r1r2 / b1p1; /* q == (BDIGIT)q */
|
||||||
c->frac[ind_c + 1] += q;
|
c->frac[ind_c + 1] += (BDIGIT)q;
|
||||||
ind_r = b->Prec + ind_c;
|
ind_r = b->Prec + ind_c;
|
||||||
|
|
||||||
sub_mult:
|
sub_mult:
|
||||||
|
@ -3471,17 +3428,17 @@ sub_mult:
|
||||||
n = ind_b;
|
n = ind_b;
|
||||||
for(i = 0; i <= n; ++i) {
|
for(i = 0; i <= n; ++i) {
|
||||||
/* now, perform r = r - q * b */
|
/* now, perform r = r - q * b */
|
||||||
qb = q *(b->frac[ind_b]);
|
qb = q * b->frac[ind_b];
|
||||||
if (qb < BASE) borrow1 = 0;
|
if (qb < BASE) borrow1 = 0;
|
||||||
else {
|
else {
|
||||||
borrow1 = qb / BASE;
|
borrow1 = (BDIGIT)(qb / BASE);
|
||||||
qb = qb - borrow1 * BASE;
|
qb -= (BDIGIT_DBL)borrow1 * BASE; /* get qb < BASE */
|
||||||
}
|
}
|
||||||
if(r->frac[ind_r] < qb) {
|
if(r->frac[ind_r] < qb) {
|
||||||
r->frac[ind_r] +=(BASE - qb);
|
r->frac[ind_r] += (BDIGIT)(BASE - qb);
|
||||||
borrow2 = borrow2 + borrow1 + 1;
|
borrow2 = borrow2 + borrow1 + 1;
|
||||||
} else {
|
} else {
|
||||||
r->frac[ind_r] -= qb;
|
r->frac[ind_r] -= (BDIGIT)qb;
|
||||||
borrow2 += borrow1;
|
borrow2 += borrow1;
|
||||||
}
|
}
|
||||||
if(borrow2) {
|
if(borrow2) {
|
||||||
|
@ -3503,7 +3460,7 @@ carry:
|
||||||
while(c->frac[ind_r] >= BASE) {
|
while(c->frac[ind_r] >= BASE) {
|
||||||
c->frac[ind_r] -= BASE;
|
c->frac[ind_r] -= BASE;
|
||||||
--ind_r;
|
--ind_r;
|
||||||
++(c->frac[ind_r]);
|
++c->frac[ind_r];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* End of operation, now final arrangement */
|
/* End of operation, now final arrangement */
|
||||||
|
@ -3564,8 +3521,8 @@ VpNmlz(Real *a)
|
||||||
while (a->frac[i] == 0) ++i; /* skip the first few zeros */
|
while (a->frac[i] == 0) ++i; /* skip the first few zeros */
|
||||||
if (i) {
|
if (i) {
|
||||||
a->Prec -= i;
|
a->Prec -= i;
|
||||||
if(!AddExponent(a,-((S_INT)i))) return 0;
|
if (!AddExponent(a, -(S_INT)i)) return 0;
|
||||||
memmove(&(a->frac[0]),&(a->frac[i]),(a->Prec)*sizeof(U_LONG));
|
memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(BDIGIT));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -3671,7 +3628,6 @@ Exit:
|
||||||
return (int)val;
|
return (int)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
|
||||||
/*
|
/*
|
||||||
* cntl_chr ... ASCIIZ Character, print control characters
|
* cntl_chr ... ASCIIZ Character, print control characters
|
||||||
* Available control codes:
|
* Available control codes:
|
||||||
|
@ -3686,7 +3642,7 @@ VP_EXPORT int
|
||||||
VPrint(FILE *fp, const char *cntl_chr, Real *a)
|
VPrint(FILE *fp, const char *cntl_chr, Real *a)
|
||||||
{
|
{
|
||||||
U_LONG i, j, nc, nd, ZeroSup;
|
U_LONG i, j, nc, nd, ZeroSup;
|
||||||
U_LONG n, m, e, nn;
|
BDIGIT n, m, e, nn;
|
||||||
|
|
||||||
/* Check if NaN & Inf. */
|
/* Check if NaN & Inf. */
|
||||||
if(VpIsNaN(a)) {
|
if(VpIsNaN(a)) {
|
||||||
|
@ -3727,7 +3683,7 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
|
||||||
while(m) {
|
while(m) {
|
||||||
nn = e / m;
|
nn = e / m;
|
||||||
if((!ZeroSup) || nn) {
|
if((!ZeroSup) || nn) {
|
||||||
nc += fprintf(fp, "%lu", nn); /* The leading zero(s) */
|
nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */
|
||||||
/* as 0.00xx will not */
|
/* as 0.00xx will not */
|
||||||
/* be printed. */
|
/* be printed. */
|
||||||
++nd;
|
++nd;
|
||||||
|
@ -3774,7 +3730,6 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
|
||||||
}
|
}
|
||||||
return (int)nc;
|
return (int)nc;
|
||||||
}
|
}
|
||||||
#endif /* BIGDECIMAL_DEBUG */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
VpFormatSt(char *psz,S_INT fFmt)
|
VpFormatSt(char *psz,S_INT fFmt)
|
||||||
|
@ -3811,7 +3766,7 @@ VpExponent10(Real *a)
|
||||||
|
|
||||||
if(!VpHasVal(a)) return 0;
|
if(!VpHasVal(a)) return 0;
|
||||||
|
|
||||||
ex =(a->exponent) * BASE_FIG;
|
ex = a->exponent * (S_LONG)BASE_FIG;
|
||||||
n = BASE1;
|
n = BASE1;
|
||||||
while((a->frac[0] / n) == 0) {
|
while((a->frac[0] / n) == 0) {
|
||||||
--ex;
|
--ex;
|
||||||
|
@ -3823,8 +3778,8 @@ VpExponent10(Real *a)
|
||||||
VP_EXPORT void
|
VP_EXPORT void
|
||||||
VpSzMantissa(Real *a,char *psz)
|
VpSzMantissa(Real *a,char *psz)
|
||||||
{
|
{
|
||||||
U_LONG i, ZeroSup;
|
U_LONG i, n, ZeroSup;
|
||||||
U_LONG n, m, e, nn;
|
BDIGIT_DBL m, e, nn;
|
||||||
|
|
||||||
if(VpIsNaN(a)) {
|
if(VpIsNaN(a)) {
|
||||||
sprintf(psz,SZ_NaN);
|
sprintf(psz,SZ_NaN);
|
||||||
|
@ -3849,7 +3804,7 @@ VpSzMantissa(Real *a,char *psz)
|
||||||
while (m) {
|
while (m) {
|
||||||
nn = e / m;
|
nn = e / m;
|
||||||
if((!ZeroSup) || nn) {
|
if((!ZeroSup) || nn) {
|
||||||
sprintf(psz, "%lu", nn); /* The leading zero(s) */
|
sprintf(psz, "%lu", (unsigned long)nn); /* The leading zero(s) */
|
||||||
psz += strlen(psz);
|
psz += strlen(psz);
|
||||||
/* as 0.00xx will be ignored. */
|
/* as 0.00xx will be ignored. */
|
||||||
ZeroSup = 0; /* Set to print succeeding zeros */
|
ZeroSup = 0; /* Set to print succeeding zeros */
|
||||||
|
@ -3903,8 +3858,8 @@ VP_EXPORT void
|
||||||
VpToString(Real *a,char *psz,int fFmt,int fPlus)
|
VpToString(Real *a,char *psz,int fFmt,int fPlus)
|
||||||
/* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */
|
/* fPlus =0:default, =1: set ' ' before digits , =2:set '+' before digits. */
|
||||||
{
|
{
|
||||||
U_LONG i, ZeroSup;
|
U_LONG i, n, ZeroSup;
|
||||||
U_LONG n, m, e, nn;
|
BDIGIT shift, m, e, nn;
|
||||||
char *pszSav = psz;
|
char *pszSav = psz;
|
||||||
S_LONG ex;
|
S_LONG ex;
|
||||||
|
|
||||||
|
@ -3925,7 +3880,7 @@ VpToString(Real *a,char *psz,int fFmt,int fPlus)
|
||||||
while(m) {
|
while(m) {
|
||||||
nn = e / m;
|
nn = e / m;
|
||||||
if((!ZeroSup) || nn) {
|
if((!ZeroSup) || nn) {
|
||||||
sprintf(psz, "%lu", nn); /* The reading zero(s) */
|
sprintf(psz, "%lu", (unsigned long)nn); /* The reading zero(s) */
|
||||||
psz += strlen(psz);
|
psz += strlen(psz);
|
||||||
/* as 0.00xx will be ignored. */
|
/* as 0.00xx will be ignored. */
|
||||||
ZeroSup = 0; /* Set to print succeeding zeros */
|
ZeroSup = 0; /* Set to print succeeding zeros */
|
||||||
|
@ -3934,11 +3889,11 @@ VpToString(Real *a,char *psz,int fFmt,int fPlus)
|
||||||
m /= 10;
|
m /= 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ex =(a->exponent) * BASE_FIG;
|
ex = a->exponent * (S_LONG)BASE_FIG;
|
||||||
n = BASE1;
|
shift = BASE1;
|
||||||
while((a->frac[0] / n) == 0) {
|
while(a->frac[0] / shift == 0) {
|
||||||
--ex;
|
--ex;
|
||||||
n /= 10;
|
shift /= 10;
|
||||||
}
|
}
|
||||||
while(psz[-1]=='0') *(--psz) = 0;
|
while(psz[-1]=='0') *(--psz) = 0;
|
||||||
sprintf(psz, "E%ld", ex);
|
sprintf(psz, "E%ld", ex);
|
||||||
|
@ -3949,8 +3904,8 @@ VP_EXPORT void
|
||||||
VpToFString(Real *a,char *psz,int fFmt,int fPlus)
|
VpToFString(Real *a,char *psz,int fFmt,int fPlus)
|
||||||
/* fPlus =0:default,=1: set ' ' before digits ,set '+' before digits. */
|
/* fPlus =0:default,=1: set ' ' before digits ,set '+' before digits. */
|
||||||
{
|
{
|
||||||
U_LONG i;
|
U_LONG i, n;
|
||||||
U_LONG n, m, e, nn;
|
BDIGIT m, e, nn;
|
||||||
char *pszSav = psz;
|
char *pszSav = psz;
|
||||||
S_LONG ex;
|
S_LONG ex;
|
||||||
|
|
||||||
|
@ -3974,7 +3929,7 @@ VpToFString(Real *a,char *psz,int fFmt,int fPlus)
|
||||||
for(i=0;i < n;++i) {
|
for(i=0;i < n;++i) {
|
||||||
--ex;
|
--ex;
|
||||||
if(i==0 && ex >= 0) {
|
if(i==0 && ex >= 0) {
|
||||||
sprintf(psz, "%lu", a->frac[i]);
|
sprintf(psz, "%lu", (unsigned long)a->frac[i]);
|
||||||
psz += strlen(psz);
|
psz += strlen(psz);
|
||||||
} else {
|
} else {
|
||||||
m = BASE1;
|
m = BASE1;
|
||||||
|
@ -4024,21 +3979,22 @@ VpCtoV(Real *a, const char *int_chr, U_LONG ni, const char *frac, U_LONG nf, con
|
||||||
me = ne;
|
me = ne;
|
||||||
signe = 1;
|
signe = 1;
|
||||||
exponent_overflow = 0;
|
exponent_overflow = 0;
|
||||||
memset(a->frac, 0, ma * sizeof(U_LONG));
|
memset(a->frac, 0, ma * sizeof(BDIGIT));
|
||||||
if (ne > 0) {
|
if (ne > 0) {
|
||||||
i = 0;
|
i = 0;
|
||||||
if (exp_chr[0] == '-') {
|
if (exp_chr[0] == '-') {
|
||||||
signe = -1;
|
signe = -1;
|
||||||
++i;
|
++i;
|
||||||
++me;
|
++me;
|
||||||
} else if(exp_chr[0] == '+') {
|
}
|
||||||
|
else if (exp_chr[0] == '+') {
|
||||||
++i;
|
++i;
|
||||||
++me;
|
++me;
|
||||||
}
|
}
|
||||||
while (i < me) {
|
while (i < me) {
|
||||||
es = e*((S_INT)BASE_FIG);
|
es = e * (S_LONG)BASE_FIG;
|
||||||
e = e * 10 + exp_chr[i] - '0';
|
e = e * 10 + exp_chr[i] - '0';
|
||||||
if(es > (S_INT)(e*BASE_FIG)) {
|
if (es > (S_INT)(e*(S_LONG)BASE_FIG)) {
|
||||||
exponent_overflow = 1;
|
exponent_overflow = 1;
|
||||||
e = es; /* keep sign */
|
e = es; /* keep sign */
|
||||||
break;
|
break;
|
||||||
|
@ -4073,15 +4029,15 @@ VpCtoV(Real *a, const char *int_chr, U_LONG ni, const char *frac, U_LONG nf, con
|
||||||
while (ef) {
|
while (ef) {
|
||||||
if (e >= 0) eb = e;
|
if (e >= 0) eb = e;
|
||||||
else eb = -e;
|
else eb = -e;
|
||||||
ef = eb / ((S_INT)BASE_FIG);
|
ef = eb / (S_LONG)BASE_FIG;
|
||||||
ef = eb - ef * ((S_INT)BASE_FIG);
|
ef = eb - ef * (S_LONG)BASE_FIG;
|
||||||
if (ef) {
|
if (ef) {
|
||||||
++j; /* Means to add one more preceeding zero */
|
++j; /* Means to add one more preceeding zero */
|
||||||
++e;
|
++e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eb = e / ((S_INT)BASE_FIG);
|
eb = e / (S_LONG)BASE_FIG;
|
||||||
|
|
||||||
if (exponent_overflow) {
|
if (exponent_overflow) {
|
||||||
int zero = 1;
|
int zero = 1;
|
||||||
|
@ -4098,7 +4054,7 @@ VpCtoV(Real *a, const char *int_chr, U_LONG ni, const char *frac, U_LONG nf, con
|
||||||
ind_a = 0;
|
ind_a = 0;
|
||||||
while (i < mi) {
|
while (i < mi) {
|
||||||
a->frac[ind_a] = 0;
|
a->frac[ind_a] = 0;
|
||||||
while((j < (U_LONG)BASE_FIG) &&(i < mi)) {
|
while ((j < BASE_FIG) && (i < mi)) {
|
||||||
a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0';
|
a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0';
|
||||||
++j;
|
++j;
|
||||||
++i;
|
++i;
|
||||||
|
@ -4115,7 +4071,7 @@ VpCtoV(Real *a, const char *int_chr, U_LONG ni, const char *frac, U_LONG nf, con
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while(i < nf) {
|
while(i < nf) {
|
||||||
while((j < (U_LONG)BASE_FIG) &&(i < nf)) {
|
while((j < BASE_FIG) && (i < nf)) {
|
||||||
a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0';
|
a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0';
|
||||||
++j;
|
++j;
|
||||||
++i;
|
++i;
|
||||||
|
@ -4133,7 +4089,7 @@ over_flow:
|
||||||
|
|
||||||
Final:
|
Final:
|
||||||
if (ind_a >= ma) ind_a = ma - 1;
|
if (ind_a >= ma) ind_a = ma - 1;
|
||||||
while(j < (U_LONG)BASE_FIG) {
|
while (j < BASE_FIG) {
|
||||||
a->frac[ind_a] = a->frac[ind_a] * 10;
|
a->frac[ind_a] = a->frac[ind_a] * 10;
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
|
@ -4206,7 +4162,7 @@ VpVtoD(double *d, S_LONG *e, Real *m)
|
||||||
div /=(double)((S_INT)BASE);
|
div /=(double)((S_INT)BASE);
|
||||||
*d = *d +((double) ((S_INT)m->frac[ind_m++])) * div;
|
*d = *d +((double) ((S_INT)m->frac[ind_m++])) * div;
|
||||||
}
|
}
|
||||||
*e = m->exponent * ((S_INT)BASE_FIG);
|
*e = m->exponent * (S_INT)BASE_FIG;
|
||||||
*d *= VpGetSign(m);
|
*d *= VpGetSign(m);
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
@ -4226,8 +4182,9 @@ Exit:
|
||||||
VP_EXPORT void
|
VP_EXPORT void
|
||||||
VpDtoV(Real *m, double d)
|
VpDtoV(Real *m, double d)
|
||||||
{
|
{
|
||||||
U_LONG i, ind_m, mm;
|
U_LONG ind_m, mm;
|
||||||
S_INT ne;
|
S_INT ne;
|
||||||
|
BDIGIT i;
|
||||||
double val, val2;
|
double val, val2;
|
||||||
|
|
||||||
if(isnan(d)) {
|
if(isnan(d)) {
|
||||||
|
@ -4261,11 +4218,11 @@ VpDtoV(Real *m, double d)
|
||||||
/* Now val = 0.xxxxx*BASE**ne */
|
/* Now val = 0.xxxxx*BASE**ne */
|
||||||
|
|
||||||
mm = m->MaxPrec;
|
mm = m->MaxPrec;
|
||||||
memset(m->frac, 0, mm * sizeof(U_LONG));
|
memset(m->frac, 0, mm * sizeof(BDIGIT));
|
||||||
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)BASE;
|
||||||
i =(U_LONG) val;
|
i = (BDIGIT)val;
|
||||||
val -=(double)((S_INT)i);
|
val -= (double)(S_INT)i;
|
||||||
m->frac[ind_m] = i;
|
m->frac[ind_m] = i;
|
||||||
}
|
}
|
||||||
if(ind_m >= mm) ind_m = mm - 1;
|
if(ind_m >= mm) ind_m = mm - 1;
|
||||||
|
@ -4278,7 +4235,7 @@ VpDtoV(Real *m, double d)
|
||||||
m->exponent = ne;
|
m->exponent = ne;
|
||||||
|
|
||||||
VpInternalRound(m,0,(m->Prec>0)?m->frac[m->Prec-1]:0,
|
VpInternalRound(m,0,(m->Prec>0)?m->frac[m->Prec-1]:0,
|
||||||
(U_LONG)(val*((double)((S_INT)BASE))));
|
(BDIGIT)(val*((double)((S_INT)BASE))));
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
|
@ -4406,7 +4363,7 @@ VpSqrt(Real *y, Real *x)
|
||||||
else --prec;
|
else --prec;
|
||||||
prec = prec - (S_LONG)y->MaxPrec;
|
prec = prec - (S_LONG)y->MaxPrec;
|
||||||
VpVtoD(&val, &e, x); /* val <- x */
|
VpVtoD(&val, &e, x); /* val <- x */
|
||||||
e /= ((S_LONG)BASE_FIG);
|
e /= (S_LONG)BASE_FIG;
|
||||||
n = e / 2;
|
n = e / 2;
|
||||||
if(e - n * 2 != 0) {
|
if(e - n * 2 != 0) {
|
||||||
val /=(double)((S_INT)BASE);
|
val /=(double)((S_INT)BASE);
|
||||||
|
@ -4417,7 +4374,7 @@ VpSqrt(Real *y, Real *x)
|
||||||
n = (DBLE_FIG + BASE_FIG - 1) / BASE_FIG;
|
n = (DBLE_FIG + BASE_FIG - 1) / BASE_FIG;
|
||||||
y->MaxPrec = (U_LONG)Min(n , y_prec);
|
y->MaxPrec = (U_LONG)Min(n , y_prec);
|
||||||
f->MaxPrec = y->MaxPrec + 1;
|
f->MaxPrec = y->MaxPrec + 1;
|
||||||
n = y_prec*((S_LONG)BASE_FIG);
|
n = y_prec * (S_LONG)BASE_FIG;
|
||||||
if((U_LONG)n<maxnr) n = (U_LONG)maxnr;
|
if((U_LONG)n<maxnr) n = (U_LONG)maxnr;
|
||||||
do {
|
do {
|
||||||
y->MaxPrec *= 2;
|
y->MaxPrec *= 2;
|
||||||
|
@ -4477,10 +4434,10 @@ VpMidRound(Real *y, int f, S_LONG nf)
|
||||||
/* exptoadd: number of digits needed to compensate negative nf */
|
/* exptoadd: number of digits needed to compensate negative nf */
|
||||||
int fracf;
|
int fracf;
|
||||||
S_LONG n,i,ix,ioffset,exptoadd;
|
S_LONG n,i,ix,ioffset,exptoadd;
|
||||||
U_LONG v,shifter;
|
BDIGIT v, shifter;
|
||||||
U_LONG div;
|
BDIGIT div;
|
||||||
|
|
||||||
nf += y->exponent*((int)BASE_FIG);
|
nf += y->exponent * (S_LONG)BASE_FIG;
|
||||||
exptoadd=0;
|
exptoadd=0;
|
||||||
if (nf < 0) {
|
if (nf < 0) {
|
||||||
/* rounding position too left(large). */
|
/* rounding position too left(large). */
|
||||||
|
@ -4493,14 +4450,14 @@ VpMidRound(Real *y, int f, S_LONG nf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ix: x->fraq[ix] contains round position */
|
/* ix: x->fraq[ix] contains round position */
|
||||||
ix = nf/(int)BASE_FIG;
|
ix = nf / (S_LONG)BASE_FIG;
|
||||||
if(((U_LONG)ix)>=y->Prec) return 0; /* rounding position too right(small). */
|
if ((U_LONG)ix >= y->Prec) return 0; /* rounding position too right(small). */
|
||||||
ioffset = nf - ix*((int)BASE_FIG);
|
ioffset = nf - ix*(S_LONG)BASE_FIG;
|
||||||
|
|
||||||
v = y->frac[ix];
|
v = y->frac[ix];
|
||||||
|
|
||||||
/* drop digits after pointed digit */
|
/* drop digits after pointed digit */
|
||||||
n = BASE_FIG - ioffset - 1;
|
n = (S_LONG)BASE_FIG - ioffset - 1;
|
||||||
for (shifter=1,i=0; i<n; ++i) shifter *= 10;
|
for (shifter=1,i=0; i<n; ++i) shifter *= 10;
|
||||||
fracf = (v % (shifter * 10) > 0);
|
fracf = (v % (shifter * 10) > 0);
|
||||||
v /= shifter;
|
v /= shifter;
|
||||||
|
@ -4514,7 +4471,7 @@ VpMidRound(Real *y, int f, S_LONG nf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memset(y->frac+ix+1, 0, (y->Prec - (ix+1)) * sizeof(U_LONG));
|
memset(y->frac+ix+1, 0, (y->Prec - (ix+1)) * sizeof(BDIGIT));
|
||||||
switch(f) {
|
switch(f) {
|
||||||
case VP_ROUND_DOWN: /* Truncate */
|
case VP_ROUND_DOWN: /* Truncate */
|
||||||
break;
|
break;
|
||||||
|
@ -4538,7 +4495,8 @@ VpMidRound(Real *y, int f, S_LONG nf)
|
||||||
else if (v==5) {
|
else if (v==5) {
|
||||||
if ((U_LONG)i == (BASE_FIG-1)) {
|
if ((U_LONG)i == (BASE_FIG-1)) {
|
||||||
if (ix && (y->frac[ix-1]%2)) ++div;
|
if (ix && (y->frac[ix-1]%2)) ++div;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (div%2) ++div;
|
if (div%2) ++div;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4561,8 +4519,8 @@ VpMidRound(Real *y, int f, S_LONG nf)
|
||||||
VpNmlz(y);
|
VpNmlz(y);
|
||||||
}
|
}
|
||||||
if (exptoadd > 0) {
|
if (exptoadd > 0) {
|
||||||
y->exponent += (S_INT)(exptoadd/BASE_FIG);
|
y->exponent += (S_INT)(exptoadd/(S_LONG)BASE_FIG);
|
||||||
exptoadd %= BASE_FIG;
|
exptoadd %= (S_LONG)BASE_FIG;
|
||||||
for(i=0;i<exptoadd;i++) {
|
for(i=0;i<exptoadd;i++) {
|
||||||
y->frac[0] *= 10;
|
y->frac[0] *= 10;
|
||||||
if (y->frac[0] >= BASE) {
|
if (y->frac[0] >= BASE) {
|
||||||
|
@ -4580,12 +4538,12 @@ VpLeftRound(Real *y, int f, S_LONG nf)
|
||||||
* Round from the left hand side of the digits.
|
* Round from the left hand side of the digits.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
U_LONG v;
|
BDIGIT v;
|
||||||
if (!VpHasVal(y)) return 0; /* Unable to round */
|
if (!VpHasVal(y)) return 0; /* Unable to round */
|
||||||
v = y->frac[0];
|
v = y->frac[0];
|
||||||
nf -= VpExponent(y)*BASE_FIG;
|
nf -= VpExponent(y)*(S_LONG)BASE_FIG;
|
||||||
while ((v /= 10) != 0) nf--;
|
while ((v /= 10) != 0) nf--;
|
||||||
nf += (BASE_FIG-1);
|
nf += (S_LONG)BASE_FIG-1;
|
||||||
return VpMidRound(y,f,nf);
|
return VpMidRound(y,f,nf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4609,7 +4567,7 @@ VpLimitRound(Real *c,U_LONG ixDigit)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
VpInternalRound(Real *c,U_LONG ixDigit,U_LONG vPrev,U_LONG v)
|
VpInternalRound(Real *c, U_LONG ixDigit, BDIGIT vPrev, BDIGIT v)
|
||||||
{
|
{
|
||||||
int f = 0;
|
int f = 0;
|
||||||
|
|
||||||
|
@ -4652,7 +4610,7 @@ VpInternalRound(Real *c,U_LONG ixDigit,U_LONG vPrev,U_LONG v)
|
||||||
static int
|
static int
|
||||||
VpRdup(Real *m, U_LONG ind_m)
|
VpRdup(Real *m, U_LONG ind_m)
|
||||||
{
|
{
|
||||||
U_LONG carry;
|
BDIGIT carry;
|
||||||
|
|
||||||
if (!ind_m) ind_m = m->Prec;
|
if (!ind_m) ind_m = m->Prec;
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ____BIG_DECIMAL__H____
|
#ifndef RUBY_BIG_DECIMAL_H
|
||||||
#define ____BIG_DECIMAL__H____
|
#define RUBY_BIG_DECIMAL_H 1
|
||||||
|
|
||||||
#include "ruby/ruby.h"
|
#include "ruby/ruby.h"
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -24,6 +25,24 @@ extern "C" {
|
||||||
|
|
||||||
extern VALUE rb_cBigDecimal;
|
extern VALUE rb_cBigDecimal;
|
||||||
|
|
||||||
|
#if 0 || SIZEOF_BDIGITS >= 16
|
||||||
|
# define RMPD_COMPONENT_FIGURES 38
|
||||||
|
# define RMPD_BASE ((BDIGIT)100000000000000000000000000000000000000U)
|
||||||
|
#elif SIZEOF_BDIGITS >= 8
|
||||||
|
# define RMPD_COMPONENT_FIGURES 19
|
||||||
|
# define RMPD_BASE ((BDIGIT)10000000000000000000U)
|
||||||
|
#elif SIZEOF_BDIGITS >= 4
|
||||||
|
# define RMPD_COMPONENT_FIGURES 9
|
||||||
|
# define RMPD_BASE ((BDIGIT)1000000000U)
|
||||||
|
#elif SIZEOF_BDIGITS >= 2
|
||||||
|
# define RMPD_COMPONENT_FIGURES 4
|
||||||
|
# define RMPD_BASE ((BDIGIT)10000U)
|
||||||
|
#else
|
||||||
|
# define RMPD_COMPONENT_FIGURES 2
|
||||||
|
# define RMPD_BASE ((BDIGIT)100U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NaN & Infinity
|
* NaN & Infinity
|
||||||
*/
|
*/
|
||||||
|
@ -97,7 +116,7 @@ typedef struct {
|
||||||
* -3 : Negative infinite number
|
* -3 : Negative infinite number
|
||||||
*/
|
*/
|
||||||
short flag; /* Not used in vp_routines,space for user. */
|
short flag; /* Not used in vp_routines,space for user. */
|
||||||
U_LONG frac[1]; /* Pointer to array of fraction part. */
|
BDIGIT frac[1]; /* Pointer to array of fraction part. */
|
||||||
} Real;
|
} Real;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -111,9 +130,16 @@ VpNewRbClass(U_LONG mx,char *str,VALUE klass);
|
||||||
|
|
||||||
VP_EXPORT Real *VpCreateRbObject(U_LONG mx,const char *str);
|
VP_EXPORT Real *VpCreateRbObject(U_LONG mx,const char *str);
|
||||||
|
|
||||||
VP_EXPORT U_LONG VpBaseFig(void);
|
static inline BDIGIT
|
||||||
VP_EXPORT U_LONG VpDblFig(void);
|
rmpd_base_value(void) { return RMPD_BASE; }
|
||||||
VP_EXPORT U_LONG VpBaseVal(void);
|
static inline size_t
|
||||||
|
rmpd_component_figures(void) { return RMPD_COMPONENT_FIGURES; }
|
||||||
|
static inline size_t
|
||||||
|
rmpd_double_figures(void) { return 1+DBL_DIG; }
|
||||||
|
|
||||||
|
#define VpBaseFig() rmpd_component_figures()
|
||||||
|
#define VpDblFig() rmpd_double_figures()
|
||||||
|
#define VpBaseVal() rmpd_base_value()
|
||||||
|
|
||||||
/* Zero,Inf,NaN (isinf(),isnan() used to check) */
|
/* Zero,Inf,NaN (isinf(),isnan() used to check) */
|
||||||
VP_EXPORT double VpGetDoubleNaN(void);
|
VP_EXPORT double VpGetDoubleNaN(void);
|
||||||
|
@ -135,7 +161,7 @@ VP_EXPORT int VpException(unsigned short f,const char *str,int always);
|
||||||
VP_EXPORT int VpIsNegDoubleZero(double v);
|
VP_EXPORT int VpIsNegDoubleZero(double v);
|
||||||
#endif
|
#endif
|
||||||
VP_EXPORT U_LONG VpNumOfChars(Real *vp,const char *pszFmt);
|
VP_EXPORT U_LONG VpNumOfChars(Real *vp,const char *pszFmt);
|
||||||
VP_EXPORT U_LONG VpInit(U_LONG BaseVal);
|
VP_EXPORT size_t VpInit(BDIGIT BaseVal);
|
||||||
VP_EXPORT void *VpMemAlloc(U_LONG mb);
|
VP_EXPORT void *VpMemAlloc(U_LONG mb);
|
||||||
VP_EXPORT void VpFree(Real *pv);
|
VP_EXPORT void VpFree(Real *pv);
|
||||||
VP_EXPORT Real *VpAlloc(U_LONG mx, const char *szVal);
|
VP_EXPORT Real *VpAlloc(U_LONG mx, const char *szVal);
|
||||||
|
@ -188,7 +214,7 @@ VP_EXPORT Real *VpOne(void);
|
||||||
#define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;}
|
#define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;}
|
||||||
|
|
||||||
/* 1 */
|
/* 1 */
|
||||||
#define VpSetOne(a) {(a)->frac[0]=(a)->Prec=(a)->exponent=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;}
|
#define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;}
|
||||||
|
|
||||||
/* ZEROs */
|
/* ZEROs */
|
||||||
#define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO)
|
#define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO)
|
||||||
|
@ -215,10 +241,11 @@ VP_EXPORT Real *VpOne(void);
|
||||||
#define VpExponent(a) (a->exponent)
|
#define VpExponent(a) (a->exponent)
|
||||||
#ifdef BIGDECIMAL_DEBUG
|
#ifdef BIGDECIMAL_DEBUG
|
||||||
int VpVarCheck(Real * v);
|
int VpVarCheck(Real * v);
|
||||||
VP_EXPORT int VPrint(FILE *fp,const char *cntl_chr,Real *a);
|
|
||||||
#endif /* BIGDECIMAL_DEBUG */
|
#endif /* BIGDECIMAL_DEBUG */
|
||||||
|
VP_EXPORT int VPrint(FILE *fp,const char *cntl_chr,Real *a);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
} /* extern "C" { */
|
} /* extern "C" { */
|
||||||
#endif
|
#endif
|
||||||
#endif /* ____BIG_DECIMAL__H____ */
|
|
||||||
|
#endif /* RUBY_BIG_DECIMAL_H */
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
require 'mkmf'
|
require 'mkmf'
|
||||||
|
|
||||||
base_fig = 0
|
|
||||||
src = "(BASE * (BASE+1)) / BASE == (BASE+1)"
|
|
||||||
while try_static_assert(src, nil, "-DBASE=10#{'0'*base_fig}UL")
|
|
||||||
base_fig += 1
|
|
||||||
end
|
|
||||||
$defs << "-DBASE=1#{'0'*base_fig}UL" << "-DBASE_FIG=#{base_fig}"
|
|
||||||
|
|
||||||
create_makefile('bigdecimal')
|
create_makefile('bigdecimal')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue