mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
F style output(like 1234.56789) implemented to to_s method.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0a0c87bb12
commit
606c473683
4 changed files with 269 additions and 110 deletions
|
@ -197,7 +197,7 @@ BigDecimal_dump(int argc, VALUE *argv, VALUE self)
|
||||||
rb_scan_args(argc, argv, "01", &dummy);
|
rb_scan_args(argc, argv, "01", &dummy);
|
||||||
GUARD_OBJ(vp,GetVpValue(self,1));
|
GUARD_OBJ(vp,GetVpValue(self,1));
|
||||||
sprintf(sz,"%lu:",VpMaxPrec(vp)*VpBaseFig());
|
sprintf(sz,"%lu:",VpMaxPrec(vp)*VpBaseFig());
|
||||||
psz = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp)+strlen(sz));
|
psz = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E")+strlen(sz));
|
||||||
sprintf(psz,"%s",sz);
|
sprintf(psz,"%s",sz);
|
||||||
VpToString(vp, psz+strlen(psz), 0);
|
VpToString(vp, psz+strlen(psz), 0);
|
||||||
return rb_str_new2(psz);
|
return rb_str_new2(psz);
|
||||||
|
@ -233,13 +233,17 @@ BigDecimal_mode(VALUE self, VALUE which, VALUE val)
|
||||||
{
|
{
|
||||||
unsigned long f,fo;
|
unsigned long f,fo;
|
||||||
|
|
||||||
if(TYPE(which)!=T_FIXNUM) return Qnil;
|
Check_Type(which, T_FIXNUM);
|
||||||
f = (unsigned long)FIX2INT(which);
|
f = (unsigned long)FIX2INT(which);
|
||||||
|
|
||||||
if(f&VP_EXCEPTION_ALL) {
|
if(f&VP_EXCEPTION_ALL) {
|
||||||
/* Exception mode setting */
|
/* Exception mode setting */
|
||||||
fo = VpGetException();
|
fo = VpGetException();
|
||||||
if(val!=Qfalse && val!=Qtrue) return Qnil;
|
if(val==Qnil) return INT2FIX(fo);
|
||||||
|
if(val!=Qfalse && val!=Qtrue) {
|
||||||
|
rb_raise(rb_eTypeError, "The second argument must be true or false.");
|
||||||
|
return Qnil; /* Not reached */
|
||||||
|
}
|
||||||
if(f&VP_EXCEPTION_INFINITY) {
|
if(f&VP_EXCEPTION_INFINITY) {
|
||||||
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):
|
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):
|
||||||
(fo&(~VP_EXCEPTION_INFINITY))));
|
(fo&(~VP_EXCEPTION_INFINITY))));
|
||||||
|
@ -248,14 +252,22 @@ BigDecimal_mode(VALUE self, VALUE which, VALUE val)
|
||||||
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):
|
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):
|
||||||
(fo&(~VP_EXCEPTION_NaN))));
|
(fo&(~VP_EXCEPTION_NaN))));
|
||||||
}
|
}
|
||||||
|
fo = VpGetException();
|
||||||
return INT2FIX(fo);
|
return INT2FIX(fo);
|
||||||
}
|
}
|
||||||
if(VP_ROUND_MODE==f) {
|
if(VP_ROUND_MODE==f) {
|
||||||
/* Rounding mode setting */
|
/* Rounding mode setting */
|
||||||
if(TYPE(val)!=T_FIXNUM) return Qnil;
|
fo = VpGetRoundMode();
|
||||||
|
if(val==Qnil) return INT2FIX(fo);
|
||||||
|
Check_Type(val, T_FIXNUM);
|
||||||
|
if(!VpIsRoundMode(FIX2INT(val))) {
|
||||||
|
rb_raise(rb_eTypeError, "Invalid rounding mode.");
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
fo = VpSetRoundMode((unsigned long)FIX2INT(val));
|
fo = VpSetRoundMode((unsigned long)FIX2INT(val));
|
||||||
return INT2FIX(fo);
|
return INT2FIX(fo);
|
||||||
}
|
}
|
||||||
|
rb_raise(rb_eTypeError, "The first argument for BigDecimal#mode is invalid.");
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,13 +931,14 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
||||||
Check_Type(vLoc, T_FIXNUM);
|
Check_Type(vLoc, T_FIXNUM);
|
||||||
iLoc = FIX2INT(vLoc);
|
iLoc = FIX2INT(vLoc);
|
||||||
break;
|
break;
|
||||||
case 2:{
|
case 2:
|
||||||
int sws = sw;
|
|
||||||
Check_Type(vLoc, T_FIXNUM);
|
Check_Type(vLoc, T_FIXNUM);
|
||||||
iLoc = FIX2INT(vLoc);
|
iLoc = FIX2INT(vLoc);
|
||||||
Check_Type(vRound, T_FIXNUM);
|
Check_Type(vRound, T_FIXNUM);
|
||||||
sw = VpSetRoundMode(FIX2INT(vRound));
|
sw = FIX2INT(vRound);
|
||||||
VpSetRoundMode(sws);
|
if(!VpIsRoundMode(sw)) {
|
||||||
|
rb_raise(rb_eTypeError, "Invalid rounding mode.");
|
||||||
|
return Qnil;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1024,20 +1037,45 @@ static VALUE
|
||||||
BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
|
BigDecimal_to_s(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
ENTER(5);
|
ENTER(5);
|
||||||
Real *vp;
|
int fmt=0; /* 0:E format */
|
||||||
char *psz;
|
Real *vp;
|
||||||
|
char *psz;
|
||||||
|
char ch;
|
||||||
U_LONG nc;
|
U_LONG nc;
|
||||||
S_INT mc = 0;
|
S_INT mc = 0;
|
||||||
VALUE f;
|
VALUE f;
|
||||||
|
|
||||||
GUARD_OBJ(vp,GetVpValue(self,1));
|
GUARD_OBJ(vp,GetVpValue(self,1));
|
||||||
nc = VpNumOfChars(vp)+1;
|
|
||||||
if(rb_scan_args(argc,argv,"01",&f)==1) {
|
if(rb_scan_args(argc,argv,"01",&f)==1) {
|
||||||
mc = GetPositiveInt(f);
|
if(TYPE(f)==T_STRING) {
|
||||||
nc += (nc + mc - 1) / mc + 1;
|
SafeStringValue(f);
|
||||||
|
psz = RSTRING(f)->ptr;
|
||||||
|
while(ch=*psz++) {
|
||||||
|
if(!ISDIGIT(ch)) {
|
||||||
|
if(ch=='F' || ch=='f') fmt = 1; /* F format */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mc = mc * 10 + ch - '0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mc = GetPositiveInt(f);
|
||||||
|
}
|
||||||
|
if(fmt) {
|
||||||
|
nc = VpNumOfChars(vp,"F");
|
||||||
|
} else {
|
||||||
|
nc = VpNumOfChars(vp,"E");
|
||||||
|
}
|
||||||
|
if(mc>0) nc += (nc + mc - 1) / mc + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
psz = ALLOCA_N(char,(unsigned int)nc);
|
psz = ALLOCA_N(char,(unsigned int)nc);
|
||||||
VpToString(vp, psz, mc);
|
|
||||||
|
if(fmt) {
|
||||||
|
VpToFString(vp, psz, mc);
|
||||||
|
} else {
|
||||||
|
VpToString (vp, psz, mc);
|
||||||
|
}
|
||||||
return rb_str_new2(psz);
|
return rb_str_new2(psz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1052,7 +1090,7 @@ BigDecimal_split(VALUE self)
|
||||||
char *psz1;
|
char *psz1;
|
||||||
|
|
||||||
GUARD_OBJ(vp,GetVpValue(self,1));
|
GUARD_OBJ(vp,GetVpValue(self,1));
|
||||||
psz1 = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp));
|
psz1 = ALLOCA_N(char,(unsigned int)VpNumOfChars(vp,"E"));
|
||||||
VpSzMantissa(vp,psz1);
|
VpSzMantissa(vp,psz1);
|
||||||
s = 1;
|
s = 1;
|
||||||
if(psz1[0]=='-') {
|
if(psz1[0]=='-') {
|
||||||
|
@ -1087,7 +1125,7 @@ BigDecimal_inspect(VALUE self)
|
||||||
char *pszAll;
|
char *pszAll;
|
||||||
|
|
||||||
GUARD_OBJ(vp,GetVpValue(self,1));
|
GUARD_OBJ(vp,GetVpValue(self,1));
|
||||||
nc = VpNumOfChars(vp);
|
nc = VpNumOfChars(vp,"E");
|
||||||
nc +=(nc + 9) / 10;
|
nc +=(nc + 9) / 10;
|
||||||
|
|
||||||
psz1 = ALLOCA_N(char,nc);
|
psz1 = ALLOCA_N(char,nc);
|
||||||
|
@ -1298,7 +1336,7 @@ Init_bigdecimal(void)
|
||||||
rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE",INT2FIX(VP_SIGN_NEGATIVE_INFINITE));
|
rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE",INT2FIX(VP_SIGN_NEGATIVE_INFINITE));
|
||||||
|
|
||||||
/* instance methods */
|
/* instance methods */
|
||||||
rb_define_method(rb_cBigDecimal, "prec", BigDecimal_prec, 0);
|
rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0);
|
||||||
rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
|
rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2);
|
||||||
rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2);
|
rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2);
|
||||||
rb_define_method(rb_cBigDecimal, "mult", BigDecimal_mult2, 2);
|
rb_define_method(rb_cBigDecimal, "mult", BigDecimal_mult2, 2);
|
||||||
|
@ -1478,14 +1516,21 @@ VpGetRoundMode(void)
|
||||||
return gfRoundMode;
|
return gfRoundMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT unsigned long
|
VP_EXPORT int
|
||||||
VpSetRoundMode(unsigned long n)
|
VpIsRoundMode(unsigned long n)
|
||||||
{
|
{
|
||||||
if(n==VP_ROUND_UP || n!=VP_ROUND_DOWN ||
|
if(n==VP_ROUND_UP || n!=VP_ROUND_DOWN ||
|
||||||
n==VP_ROUND_HALF_UP || n!=VP_ROUND_HALF_DOWN ||
|
n==VP_ROUND_HALF_UP || n!=VP_ROUND_HALF_DOWN ||
|
||||||
n==VP_ROUND_CEIL || n!=VP_ROUND_FLOOR ||
|
n==VP_ROUND_CEIL || n!=VP_ROUND_FLOOR ||
|
||||||
n==VP_ROUND_HALF_EVEN
|
n==VP_ROUND_HALF_EVEN
|
||||||
) gfRoundMode = n;
|
) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VP_EXPORT unsigned long
|
||||||
|
VpSetRoundMode(unsigned long n)
|
||||||
|
{
|
||||||
|
if(VpIsRoundMode(n)) gfRoundMode = n;
|
||||||
return gfRoundMode;
|
return gfRoundMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1630,13 +1675,13 @@ raise:
|
||||||
static int
|
static int
|
||||||
VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
||||||
{
|
{
|
||||||
if(VpIsNaN(a) || VpIsNaN(b)) {
|
if(VpIsNaN(a) || VpIsNaN(b)) {
|
||||||
/* at least a or b is NaN */
|
/* at least a or b is NaN */
|
||||||
VpSetNaN(c);
|
VpSetNaN(c);
|
||||||
goto NaN;
|
goto NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VpIsInf(a)) {
|
if(VpIsInf(a)) {
|
||||||
if(VpIsInf(b)) {
|
if(VpIsInf(b)) {
|
||||||
switch(sw)
|
switch(sw)
|
||||||
{
|
{
|
||||||
|
@ -1686,7 +1731,7 @@ VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
||||||
VpSetInf(c,VpGetSign(a)*VpGetSign(b));
|
VpSetInf(c,VpGetSign(a)*VpGetSign(b));
|
||||||
}
|
}
|
||||||
goto Inf;
|
goto Inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VpIsInf(b)) {
|
if(VpIsInf(b)) {
|
||||||
switch(sw)
|
switch(sw)
|
||||||
|
@ -1722,14 +1767,35 @@ NaN:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns number of chars needed to represent vp.
|
* returns number of chars needed to represent vp in specified format.
|
||||||
*/
|
*/
|
||||||
VP_EXPORT U_LONG
|
VP_EXPORT U_LONG
|
||||||
VpNumOfChars(Real *vp)
|
VpNumOfChars(Real *vp,char *pszFmt)
|
||||||
{
|
{
|
||||||
|
S_INT ex;
|
||||||
|
U_LONG nc;
|
||||||
|
|
||||||
if(vp == NULL) return BASE_FIG*2+6;
|
if(vp == NULL) return BASE_FIG*2+6;
|
||||||
if(!VpIsDef(vp)) return 32; /* not sure,may be OK */
|
if(!VpIsDef(vp)) return 32; /* not sure,may be OK */
|
||||||
return BASE_FIG *(vp->Prec + 2)+6; /* 3: sign + exponent chars */
|
|
||||||
|
switch(*pszFmt)
|
||||||
|
{
|
||||||
|
case 'F':
|
||||||
|
nc = BASE_FIG*(vp->Prec + 1)+2;
|
||||||
|
ex = vp->exponent;
|
||||||
|
if(ex<0) {
|
||||||
|
nc += BASE_FIG*(-ex);
|
||||||
|
} else {
|
||||||
|
if(ex > (S_INT)vp->Prec) {
|
||||||
|
nc += BASE_FIG*(ex - (S_INT)vp->Prec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
default:
|
||||||
|
nc = BASE_FIG*(vp->Prec + 2)+6; /* 3: sign + exponent chars */
|
||||||
|
}
|
||||||
|
return nc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2110,10 +2176,10 @@ end_if:
|
||||||
isw = VpGetSign(a) + sw *VpGetSign(b);
|
isw = VpGetSign(a) + sw *VpGetSign(b);
|
||||||
/*
|
/*
|
||||||
* isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1)
|
* isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1)
|
||||||
* = 2 ...( 1)+( 1),( 1)-(-1)
|
* = 2 ...( 1)+( 1),( 1)-(-1)
|
||||||
* =-2 ...(-1)+(-1),(-1)-( 1)
|
* =-2 ...(-1)+(-1),(-1)-( 1)
|
||||||
* If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|)
|
* If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|)
|
||||||
* else c =(Sign of isw)(|a_ptr|+|b_ptr|)
|
* else c =(Sign ofisw)(|a_ptr|+|b_ptr|)
|
||||||
*/
|
*/
|
||||||
if(isw) { /* addition */
|
if(isw) { /* addition */
|
||||||
VpSetSign(c,(S_INT)1);
|
VpSetSign(c,(S_INT)1);
|
||||||
|
@ -2363,12 +2429,12 @@ Exit:
|
||||||
* a = xxxxxxxxxxx
|
* a = xxxxxxxxxxx
|
||||||
* b = xxxxxxxxxx
|
* b = xxxxxxxxxx
|
||||||
* c =xxxxxxxxxxxxxxx
|
* c =xxxxxxxxxxxxxxx
|
||||||
* word_shift = | |
|
* word_shift = | |
|
||||||
* right_word = | | (Total digits in RHSV)
|
* right_word = | | (Total digits in RHSV)
|
||||||
* left_word = | | (Total digits in LHSV)
|
* left_word = | | (Total digits in LHSV)
|
||||||
* a_pos = |
|
* a_pos = |
|
||||||
* b_pos = |
|
* b_pos = |
|
||||||
* 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, U_LONG *av, U_LONG *bv)
|
||||||
|
@ -2381,17 +2447,17 @@ VpSetPTR(Real *a, Real *b, Real *c, U_LONG *a_pos, U_LONG *b_pos, U_LONG *c_pos,
|
||||||
right_word = Max((a->Prec),left_word);
|
right_word = Max((a->Prec),left_word);
|
||||||
left_word =(c->MaxPrec) - 1; /* -1 ... prepare for round up */
|
left_word =(c->MaxPrec) - 1; /* -1 ... prepare for round up */
|
||||||
/*
|
/*
|
||||||
* check if 'round off' is needed.
|
* check if 'round' is needed.
|
||||||
*/
|
*/
|
||||||
if(right_word > left_word) { /* round off ? */
|
if(right_word > left_word) { /* round ? */
|
||||||
/*---------------------------------
|
/*---------------------------------
|
||||||
* Actual size of a = xxxxxxAxx
|
* Actual size of a = xxxxxxAxx
|
||||||
* Actual size of b = xxxBxxxxx
|
* Actual size of b = xxxBxxxxx
|
||||||
* Max. size of c = xxxxxx
|
* Max. size of c = xxxxxx
|
||||||
* Round off = |-----|
|
* Round off = |-----|
|
||||||
* c_pos = |
|
* c_pos = |
|
||||||
* right_word = |
|
* right_word = |
|
||||||
* a_pos = |
|
* a_pos = |
|
||||||
*/
|
*/
|
||||||
*c_pos = right_word = left_word + 1; /* Set resulting precision */
|
*c_pos = right_word = left_word + 1; /* Set resulting precision */
|
||||||
/* be equal to that of c */
|
/* be equal to that of c */
|
||||||
|
@ -3036,7 +3102,8 @@ VpFormatSt(char *psz,S_INT fFmt)
|
||||||
U_LONG i;
|
U_LONG i;
|
||||||
S_INT nf = 0;
|
S_INT nf = 0;
|
||||||
char ch;
|
char ch;
|
||||||
int fDot = 0;
|
|
||||||
|
if(fFmt<=0) return;
|
||||||
|
|
||||||
ie = strlen(psz);
|
ie = strlen(psz);
|
||||||
for(i = 0; i < ie; ++i) {
|
for(i = 0; i < ie; ++i) {
|
||||||
|
@ -3044,10 +3111,8 @@ VpFormatSt(char *psz,S_INT fFmt)
|
||||||
if(!ch) break;
|
if(!ch) break;
|
||||||
if(ch == '.') {
|
if(ch == '.') {
|
||||||
nf = 0;
|
nf = 0;
|
||||||
fDot = 1;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!fDot) continue;
|
|
||||||
if(ch == 'E') break;
|
if(ch == 'E') break;
|
||||||
nf++;
|
nf++;
|
||||||
if(nf > fFmt) {
|
if(nf > fFmt) {
|
||||||
|
@ -3123,6 +3188,29 @@ VpSzMantissa(Real *a,char *psz)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VP_EXPORT int
|
||||||
|
VpToSpecialString(Real *a,char *psz)
|
||||||
|
{
|
||||||
|
if(VpIsNaN(a)) {
|
||||||
|
sprintf(psz,SZ_NaN);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(VpIsPosInf(a)) {
|
||||||
|
sprintf(psz,SZ_INF);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(VpIsNegInf(a)) {
|
||||||
|
sprintf(psz,SZ_NINF);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(VpIsZero(a)) {
|
||||||
|
if(VpIsPosZero(a)) sprintf(psz, "0.0");
|
||||||
|
else sprintf(psz, "-0.0");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
VP_EXPORT void
|
VP_EXPORT void
|
||||||
VpToString(Real *a,char *psz,int fFmt)
|
VpToString(Real *a,char *psz,int fFmt)
|
||||||
{
|
{
|
||||||
|
@ -3131,52 +3219,87 @@ VpToString(Real *a,char *psz,int fFmt)
|
||||||
char *pszSav = psz;
|
char *pszSav = psz;
|
||||||
S_LONG ex;
|
S_LONG ex;
|
||||||
|
|
||||||
if(VpIsNaN(a)) {
|
if(VpToSpecialString(a,psz)) return;
|
||||||
sprintf(psz,SZ_NaN);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(VpIsPosInf(a)) {
|
|
||||||
sprintf(psz,SZ_INF);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(VpIsNegInf(a)) {
|
|
||||||
sprintf(psz,SZ_NINF);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
|
ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
|
||||||
if(!VpIsZero(a)) {
|
|
||||||
if(VpGetSign(a) < 0) *psz++ = '-';
|
if(VpGetSign(a) < 0) *psz++ = '-';
|
||||||
*psz++ = '0';
|
*psz++ = '0';
|
||||||
*psz++ = '.';
|
*psz++ = '.';
|
||||||
n = a->Prec;
|
n = a->Prec;
|
||||||
for(i=0;i < n;++i) {
|
for(i=0;i < n;++i) {
|
||||||
m = BASE1;
|
m = BASE1;
|
||||||
e = a->frac[i];
|
e = a->frac[i];
|
||||||
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", 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 */
|
||||||
}
|
|
||||||
e = e - nn * m;
|
|
||||||
m /= 10;
|
|
||||||
}
|
}
|
||||||
|
e = e - nn * m;
|
||||||
|
m /= 10;
|
||||||
}
|
}
|
||||||
ex =(a->exponent) * BASE_FIG;
|
|
||||||
n = BASE1;
|
|
||||||
while((a->frac[0] / n) == 0) {
|
|
||||||
--ex;
|
|
||||||
n /= 10;
|
|
||||||
}
|
|
||||||
while(psz[-1]=='0') *(--psz) = 0;
|
|
||||||
sprintf(psz, "E%ld", ex);
|
|
||||||
} else {
|
|
||||||
if(VpIsPosZero(a)) sprintf(psz, "0.0");
|
|
||||||
else sprintf(psz, "-0.0");
|
|
||||||
}
|
}
|
||||||
|
ex =(a->exponent) * BASE_FIG;
|
||||||
|
n = BASE1;
|
||||||
|
while((a->frac[0] / n) == 0) {
|
||||||
|
--ex;
|
||||||
|
n /= 10;
|
||||||
|
}
|
||||||
|
while(psz[-1]=='0') *(--psz) = 0;
|
||||||
|
sprintf(psz, "E%ld", ex);
|
||||||
|
if(fFmt) VpFormatSt(pszSav, fFmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
VP_EXPORT void
|
||||||
|
VpToFString(Real *a,char *psz,int fFmt)
|
||||||
|
{
|
||||||
|
U_LONG i;
|
||||||
|
U_LONG n, m, e, nn;
|
||||||
|
char *pszSav = psz;
|
||||||
|
S_LONG ex;
|
||||||
|
|
||||||
|
if(VpToSpecialString(a,psz)) return;
|
||||||
|
|
||||||
|
if(VpGetSign(a) < 0) *psz++ = '-';
|
||||||
|
n = a->Prec;
|
||||||
|
ex = a->exponent;
|
||||||
|
if(ex<=0) {
|
||||||
|
*psz++ = '0';*psz++ = '.';
|
||||||
|
while(ex<0) {
|
||||||
|
for(i=0;i<BASE_FIG;++i) *psz++ = '0';
|
||||||
|
++ex;
|
||||||
|
}
|
||||||
|
ex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i < n;++i) {
|
||||||
|
--ex;
|
||||||
|
if(i==0 && ex >= 0) {
|
||||||
|
sprintf(psz, "%lu", a->frac[i]);
|
||||||
|
psz += strlen(psz);
|
||||||
|
} else {
|
||||||
|
m = BASE1;
|
||||||
|
e = a->frac[i];
|
||||||
|
while(m) {
|
||||||
|
nn = e / m;
|
||||||
|
*psz++ = nn + '0';
|
||||||
|
e = e - nn * m;
|
||||||
|
m /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ex == 0) *psz++ = '.';
|
||||||
|
}
|
||||||
|
while(--ex>=0) {
|
||||||
|
m = BASE;
|
||||||
|
while(m/=10) *psz++ = '0';
|
||||||
|
if(ex == 0) *psz++ = '.';
|
||||||
|
}
|
||||||
|
*psz = 0;
|
||||||
|
while(psz[-1]=='0') *(--psz) = 0;
|
||||||
|
if(psz[-1]=='.') sprintf(psz, "0");
|
||||||
if(fFmt) VpFormatSt(pszSav, fFmt);
|
if(fFmt) VpFormatSt(pszSav, fFmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,12 +122,13 @@ VP_EXPORT U_LONG VpGetPrecLimit(void);
|
||||||
VP_EXPORT U_LONG VpSetPrecLimit(U_LONG n);
|
VP_EXPORT U_LONG VpSetPrecLimit(U_LONG n);
|
||||||
|
|
||||||
/* Round mode */
|
/* Round mode */
|
||||||
|
VP_EXPORT int VpIsRoundMode(unsigned long n);
|
||||||
VP_EXPORT unsigned long VpGetRoundMode(void);
|
VP_EXPORT unsigned long VpGetRoundMode(void);
|
||||||
VP_EXPORT unsigned long VpSetRoundMode(unsigned long n);
|
VP_EXPORT unsigned long VpSetRoundMode(unsigned long n);
|
||||||
|
|
||||||
VP_EXPORT int VpException(unsigned short f,char *str,int always);
|
VP_EXPORT int VpException(unsigned short f,char *str,int always);
|
||||||
VP_EXPORT int VpIsNegDoubleZero(double v);
|
VP_EXPORT int VpIsNegDoubleZero(double v);
|
||||||
VP_EXPORT U_LONG VpNumOfChars(Real *vp);
|
VP_EXPORT U_LONG VpNumOfChars(Real *vp,char *pszFmt);
|
||||||
VP_EXPORT U_LONG VpInit(U_LONG BaseVal);
|
VP_EXPORT U_LONG VpInit(U_LONG 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);
|
||||||
|
@ -139,7 +140,9 @@ VP_EXPORT int VpDivd(Real *c,Real *r,Real *a,Real *b);
|
||||||
VP_EXPORT int VpComp(Real *a,Real *b);
|
VP_EXPORT int VpComp(Real *a,Real *b);
|
||||||
VP_EXPORT S_LONG VpExponent10(Real *a);
|
VP_EXPORT S_LONG VpExponent10(Real *a);
|
||||||
VP_EXPORT void VpSzMantissa(Real *a,char *psz);
|
VP_EXPORT void VpSzMantissa(Real *a,char *psz);
|
||||||
|
VP_EXPORT int VpToSpecialString(Real *a,char *psz);
|
||||||
VP_EXPORT void VpToString(Real *a,char *psz,int fFmt);
|
VP_EXPORT void VpToString(Real *a,char *psz,int fFmt);
|
||||||
|
VP_EXPORT void VpToFString(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 int VpVtoD(double *d,S_LONG *e,Real *m);
|
VP_EXPORT int VpVtoD(double *d,S_LONG *e,Real *m);
|
||||||
VP_EXPORT void VpDtoV(Real *m,double d);
|
VP_EXPORT void VpDtoV(Real *m,double d);
|
||||||
|
|
|
@ -148,8 +148,8 @@ EXCEPTION_ZERODIVIDE results to +Infinity or -Infinity<BR>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
EXCEPTION_INFINITY,EXCEPTION_OVERFLOW, and EXCEPTION_ZERODIVIDE are
|
EXCEPTION_INFINITY,EXCEPTION_OVERFLOW, and EXCEPTION_ZERODIVIDE are
|
||||||
currently the same.<BR>
|
currently the same.<BR>
|
||||||
The return value of mode method is the previous value set.<BR>
|
The return value of mode method is the value set.<BR>
|
||||||
nil is returned if any argument is wrong.<BR>
|
If nil is specified for the second argument,then current setting is returned.<BR>
|
||||||
Suppose the return value of the mode method is f,then
|
Suppose the return value of the mode method is f,then
|
||||||
f & BigDecimal::EXCEPTION_NaN !=0 means EXCEPTION_NaN is set to on.
|
f & BigDecimal::EXCEPTION_NaN !=0 means EXCEPTION_NaN is set to on.
|
||||||
<P>
|
<P>
|
||||||
|
@ -169,8 +169,7 @@ where flag must be one of:
|
||||||
<TR><TD>ROUND_CEILING</TD><TD>round towards positive infinity(ceil).</TD></TR>
|
<TR><TD>ROUND_CEILING</TD><TD>round towards positive infinity(ceil).</TD></TR>
|
||||||
<TR><TD>ROUND_FLOOR</TD><TD>round towards negative infinity(floor).</TD></TR>
|
<TR><TD>ROUND_FLOOR</TD><TD>round towards negative infinity(floor).</TD></TR>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
New rounding mode is returned,nil is returned if any argument is not an integer.
|
New rounding mode is returned. If nil is specified for the second argument,then current setting is returned.<BR>
|
||||||
Bad specification is ignored.<BR>
|
|
||||||
The digit location for rounding operation can not be specified by this mode method,
|
The digit location for rounding operation can not be specified by this mode method,
|
||||||
use truncate/round/ceil/floor/add/sub/mult/div mthods for each instance instead.
|
use truncate/round/ceil/floor/add/sub/mult/div mthods for each instance instead.
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
@ -359,10 +358,27 @@ If a is Infinity or NaN,then i becomes to nil.
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
|
<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
|
||||||
converts to string(results look like "0.xxxxxEn").<BR>
|
converts to string(default results look like "0.xxxxxEn").
|
||||||
s = a.to_s<BR>
|
<CODE><PRE>
|
||||||
If n is given,then a space is inserted after every n digits for readability.<BR>
|
BigDecimal("1.23456").to_s # ==> "0.123456E1"
|
||||||
s = a.to_s(n)
|
</PRE></CODE>
|
||||||
|
If n(>0) is given,then a space is inserted to each of two parts divided by the decimal point
|
||||||
|
after every n digits for readability.
|
||||||
|
<CODE><PRE>
|
||||||
|
BigDecimal("0.1234567890123456789").to_s(10) # ==> "0.1234567890 123456789E0"
|
||||||
|
</PRE></CODE>
|
||||||
|
n can be an string representing a positive integer number.
|
||||||
|
<CODE><PRE>
|
||||||
|
BigDecimal("0.1234567890123456789").to_s("10") # ==> "0.1234567890 123456789E0"
|
||||||
|
</PRE></CODE>
|
||||||
|
At the end of the string,'E'(or 'e') or 'F'(or 'f') can be specified to change
|
||||||
|
number representation.
|
||||||
|
<CODE><PRE>
|
||||||
|
BigDecimal("1234567890.123456789").to_s("E") # ==> "0.1234567890123456789E10"
|
||||||
|
BigDecimal("1234567890.123456789").to_s("F") # ==> "1234567890.123456789"
|
||||||
|
BigDecimal("1234567890.123456789").to_s("5E") # ==> "0.12345 67890 12345 6789E10"
|
||||||
|
BigDecimal("1234567890.123456789").to_s("5F") # ==> "12345 67890.12345 6789"
|
||||||
|
</PRE></CODE>
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>exponent</B></LI><BLOCKQUOTE>
|
<LI><B>exponent</B></LI><BLOCKQUOTE>
|
||||||
|
@ -371,8 +387,8 @@ n = a.exponent <BR>
|
||||||
means a = 0.xxxxxxx*10**n.
|
means a = 0.xxxxxxx*10**n.
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<LI><B>prec</B></LI><BLOCKQUOTE>
|
<LI><B>precs</B></LI><BLOCKQUOTE>
|
||||||
n,m = a.prec <BR>
|
n,m = a.precs <BR>
|
||||||
prec returns number of significant digits (n) and maximum number of
|
prec returns number of significant digits (n) and maximum number of
|
||||||
significant digits (m) of a.
|
significant digits (m) of a.
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
|
@ -157,10 +157,10 @@ EXCEPTION_ZERODIVIDE
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
EXCEPTION_INFINITY、EXCEPTION_OVERFLOW、EXCEPTION_ZERODIVIDE
|
EXCEPTION_INFINITY、EXCEPTION_OVERFLOW、EXCEPTION_ZERODIVIDE
|
||||||
は今のところ同じです。<BR>
|
は今のところ同じです。<BR>
|
||||||
戻り値は、設定前の値です。「値」の意味は、例えば
|
戻り値は、設定後の値です。「値」の意味は、例えば
|
||||||
BigDecimal::EXCEPTION_NaNと「値」の & が ゼロ以外ならば
|
BigDecimal::EXCEPTION_NaNと「値」の & が ゼロ以外ならば
|
||||||
EXCEPTION_NaNが設定されているという意味です。<BR>
|
EXCEPTION_NaNが設定されているという意味です。<BR>
|
||||||
引数に正しくないものが指定された場合は nil が返ります。
|
第2引数に nil を指定すると、現状の設定値が返ります。
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<B>[丸め処理指定]</B><P>
|
<B>[丸め処理指定]</B><P>
|
||||||
|
@ -181,8 +181,7 @@ f = BigDecimal::mode(BigDecimal::ROUND_MODE,flag)
|
||||||
|
|
||||||
</TABLE>
|
</TABLE>
|
||||||
戻り値は指定後の flag の値です。
|
戻り値は指定後の flag の値です。
|
||||||
引数に数値以外が指定された場合は nil が返ります。正しくない ROUND_MODE が指定されたときは
|
第2引数に nil を指定すると、現状の設定値が返ります。
|
||||||
無視され、現状の ROUND_MODE が返ります。<BR>
|
|
||||||
mode メソッドでは丸め操作の位置をユーザが指定することはできません。
|
mode メソッドでは丸め操作の位置をユーザが指定することはできません。
|
||||||
丸め操作と位置を自分で制御したい場合は truncate/round/ceil/floor や
|
丸め操作と位置を自分で制御したい場合は truncate/round/ceil/floor や
|
||||||
add/sub/mult/div といったインスタンスメソッドを使用して下さい。
|
add/sub/mult/div といったインスタンスメソッドを使用して下さい。
|
||||||
|
@ -375,10 +374,28 @@ Float
|
||||||
ください。
|
ください。
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
|
<LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
|
||||||
文字列に変換します("0.xxxxxEn"の形になります)。<BR>
|
文字列に変換します(デフォルトは "0.xxxxxEn" の形になります)。
|
||||||
s = a.to_s<BR>
|
<CODE><PRE>
|
||||||
n が指定されたときは、仮数部分を n 桁毎に空白で区切ります。<BR>
|
BigDecimal("1.23456").to_s # ==> "0.123456E1"
|
||||||
s = a.to_s(n)
|
</PRE></CODE>
|
||||||
|
引数 n に正の整数が指定されたときは、少数点で分けられる左右部分を、それぞれ n 桁毎
|
||||||
|
に空白で区切ります。
|
||||||
|
<CODE><PRE>
|
||||||
|
BigDecimal("0.1234567890123456789").to_s(10) # ==> "0.1234567890 123456789E0"
|
||||||
|
</PRE></CODE>
|
||||||
|
引数 n に正の整数を表す文字列を指定することもできます。
|
||||||
|
<CODE><PRE>
|
||||||
|
BigDecimal("0.1234567890123456789").to_s("10") # ==> "0.1234567890 123456789E0"
|
||||||
|
</PRE></CODE>
|
||||||
|
さらに文字列の最後に E(または e) か F(または f) を指定することで、以下のように
|
||||||
|
表示形式を変更することができます。
|
||||||
|
<CODE><PRE>
|
||||||
|
BigDecimal("1234567890.123456789").to_s("E") # ==> "0.1234567890123456789E10"
|
||||||
|
BigDecimal("1234567890.123456789").to_s("F") # ==> "1234567890.123456789"
|
||||||
|
BigDecimal("1234567890.123456789").to_s("5E") # ==> "0.12345 67890 12345 6789E10"
|
||||||
|
BigDecimal("1234567890.123456789").to_s("5F") # ==> "12345 67890.12345 6789"
|
||||||
|
</PRE></CODE>
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
<LI><B>exponent</B></LI><BLOCKQUOTE>
|
<LI><B>exponent</B></LI><BLOCKQUOTE>
|
||||||
指数部を整数値で返します。
|
指数部を整数値で返します。
|
||||||
|
@ -386,8 +403,8 @@ n = a.exponent <BR>
|
||||||
は a の値が 0.xxxxxxx*10**n を意味します。
|
は a の値が 0.xxxxxxx*10**n を意味します。
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<LI><B>prec</B></LI><BLOCKQUOTE>
|
<LI><B>precs</B></LI><BLOCKQUOTE>
|
||||||
n,m = a.prec<BR>
|
n,m = a.precs<BR>
|
||||||
a の有効数字 (n) と最大有効数字 (m) の配列を返します。
|
a の有効数字 (n) と最大有効数字 (m) の配列を返します。
|
||||||
|
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
Loading…
Reference in a new issue