summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshigek <shigek@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-21 15:13:45 +0000
committershigek <shigek@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-21 15:13:45 +0000
commit39503e4d0fca75b03e78a03a55dec8f063dec224 (patch)
treec0c17378c816576bf9882e42c471ca504da561e1
parent87f143f99d836f51fab39e4f378f139ab88d817f (diff)
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
-rw-r--r--ChangeLog5
-rw-r--r--ext/bigdecimal/bigdecimal.c55
2 files changed, 29 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index bed1d9a60c..ad8152a9c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Aug 21 00:13:00 2003 Shigeo Kobayashi <shigek@ruby-lang.org>
+
+ * ext/bigdecimal/bigdecimal.c: Int. overflow bug in multiplication fixed,
+ and VpNmlz() speed up.
+
Wed Aug 20 16:44:49 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/socket/socket.c (ruby_connect): many systems seem to have
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;
}
}