diff options
author | shigek <shigek@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-08-21 15:13:45 +0000 |
---|---|---|
committer | shigek <shigek@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-08-21 15:13:45 +0000 |
commit | 39503e4d0fca75b03e78a03a55dec8f063dec224 (patch) | |
tree | c0c17378c816576bf9882e42c471ca504da561e1 /ext/bigdecimal | |
parent | 87f143f99d836f51fab39e4f378f139ab88d817f (diff) | |
download | ruby-39503e4d0fca75b03e78a03a55dec8f063dec224.tar.gz |
Int. overflow bug in multiplication fixed & VpNmlz() speed up.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4420 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/bigdecimal')
-rw-r--r-- | ext/bigdecimal/bigdecimal.c | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 945ae6e6b5..a6e34bde61 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -2495,7 +2495,7 @@ VP_EXPORT int VpMult(Real *c, Real *a, Real *b) { U_LONG MxIndA, MxIndB, MxIndAB, MxIndC; - U_LONG ind_c, i, nc; + U_LONG ind_c, i, ii, nc; U_LONG ind_as, ind_ae, ind_bs, ind_be; U_LONG Carry, s; Real *w; @@ -2568,26 +2568,26 @@ VpMult(Real *c, Real *a, Real *b) ind_be = 0; } - s = 0L; - for(i = ind_as; i <= ind_ae; ++i) s +=((a->frac[i]) *(b->frac[ind_bs--])); - Carry = s / BASE; - s = s -(Carry * BASE); - - c->frac[ind_c] += s; - if(c->frac[ind_c] >= BASE) { - s = c->frac[ind_c] / BASE; - Carry += s; - c->frac[ind_c] -=(s * BASE); - } - i = ind_c; - if(Carry) { - while((--i) >= 0) { - c->frac[i] += Carry; - if(c->frac[i] >= BASE) { - Carry = c->frac[i] / BASE; - c->frac[i] -=(Carry * BASE); - } else { - break; + for(i = ind_as; i <= ind_ae; ++i) { + s =((a->frac[i]) *(b->frac[ind_bs--])); + Carry = s / BASE; + s = s -(Carry * BASE); + c->frac[ind_c] += s; + if(c->frac[ind_c] >= BASE) { + s = c->frac[ind_c] / BASE; + Carry += s; + c->frac[ind_c] -= (s * BASE); + } + if(Carry) { + ii = ind_c; + while((--ii) >= 0) { + c->frac[ii] += Carry; + if(c->frac[ii] >= BASE) { + Carry = c->frac[ii] / BASE; + c->frac[ii] -=(Carry * BASE); + } else { + break; + } } } } @@ -2827,7 +2827,7 @@ Exit: static int VpNmlz(Real *a) { - U_LONG ind_a, i, j; + U_LONG ind_a, i; if(!VpIsDef(a)) goto NoVal; if(VpIsZero(a)) goto NoVal; @@ -2836,20 +2836,13 @@ VpNmlz(Real *a) while(ind_a--) { if(a->frac[ind_a]) { a->Prec = ind_a + 1; - i = j = 0; + i = 0; while(a->frac[i] == 0) ++i; /* skip the first few zeros */ if(i) { a->Prec -= i; if(!AddExponent(a,-((S_INT)i))) return 0; - while(i <= ind_a) { - a->frac[j] = a->frac[i]; - ++i; - ++j; - } + memmove(&(a->frac[0]),&(a->frac[i]),(a->Prec)*sizeof(U_LONG)); } -#ifdef _DEBUG - if(gfCheckVal) VpVarCheck(a); -#endif /* _DEBUG */ return 1; } } |