another subtract bug (sigh)
authorClaus Gittinger <cg@exept.de>
Wed, 02 Jun 1999 14:56:46 +0200
changeset 4254 3846b94301b8
parent 4253 768802bc61a4
child 4255 73212f63b6a6
another subtract bug (sigh)
LargeInt.st
LargeInteger.st
--- a/LargeInt.st	Wed Jun 02 13:31:09 1999 +0200
+++ b/LargeInt.st	Wed Jun 02 14:56:46 1999 +0200
@@ -2012,7 +2012,7 @@
             __diff = ((unsigned int *)(__digitP+__index-1))[0] - (__borrow & 0xFFFFFFFFL);
             __borrow >>= 32;
             if (__diff < 0) {
-                __diff += 0x100000000;
+                /* __diff += 0x100000000; */
                 __borrow++;
             }
             ((unsigned int *)(__resultP+__index-1))[0] = __diff;
@@ -2027,8 +2027,23 @@
             __diff = ((unsigned short *)(__digitP+__index-1))[0] - (__borrow & 0xFFFF);
             __borrow >>= 16;
             if (__diff < 0) {
-                __diff += 0x10000;
+                /* __diff += 0x10000; */
                 __borrow++;
+            } else {
+                if (__borrow == 0) {
+                    ((unsigned short *)(__resultP+__index-1))[0] = __diff;
+                    __index += 2;
+
+                    /* nothing more to subtract .. */
+                    while (__index < __len) {
+                        ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0];
+                        __index += 2;
+                    }
+                    if (__index <= __len) {
+                        __resultP[__index-1] = __digitP[__index-1];
+                    }
+                    break;
+                }
             }
             ((unsigned short *)(__resultP+__index-1))[0] = __diff;
             __index += 2;
@@ -2038,8 +2053,20 @@
             __diff = __digitP[__index-1] - (__borrow & 0xFF);
             __borrow >>= 8;
             if (__diff < 0) {
-                __diff += 0x100;
+                /* __diff += 0x100; */
                 __borrow++;
+            } else {
+                if (__borrow == 0) {
+                    __resultP[__index-1] = __diff;
+                    __index++;
+
+                    /* nothing more to subtract .. */
+                    while (__index <= __len) {
+                        __resultP[__index-1] = __digitP[__index-1];
+                        __index++;
+                    }
+                    break;
+                }
             }
             __resultP[__index-1] = __diff;
             __index++;
@@ -2449,12 +2476,13 @@
                 __borrow = 0;
             } else {
                 __borrow = 1;
-                __diff += 0x10000;
+                /* __diff += 0x10000; */
             }
             ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
             __index += 2;
         }
-        if (__index <= __minLen) {
+
+        if (__index == __minLen) {
             /* one of the operands has odd length - cannot continue short-wise */
         } else {
             if (__len1 > __len2) {
@@ -2462,17 +2490,22 @@
                     __diff = ((unsigned short *)(__myDigits+__index-1))[0] - __borrow;
                     if (__diff >= 0) {
                         __borrow = 0;
+                        ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+                        __index += 2;
+
                         /* copy over rest */
-                        __resultDigits[__index-1] = __diff;
-                        __index += 2;
                         while (__index < __len1) {
                             ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
                             __index+=2;
                         }
+                        if (__index <= __len1) {
+                            __resultDigits[__index-1] = __myDigits[__index-1];
+                            __index++;
+                        }
                         break;
                     }
                     __borrow = 1;
-                    __diff += 0x10000;
+                    /* __diff += 0x10000; */
                     ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
                     __index += 2;
                 }
@@ -2484,7 +2517,7 @@
                             __borrow = 0;
                         } else {
                             __borrow = 1;
-                            __diff += 0x10000;
+                            /* __diff += 0x10000; */
                         }
                         ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
                         __index += 2;
@@ -2502,7 +2535,7 @@
                 __borrow = 0;
             } else {
                 __borrow = 1;
-                __diff += 0x100;
+                /* __diff += 0x100; */
             }
             __resultDigits[__index-1] = __diff;
             __index++;
@@ -2523,7 +2556,7 @@
                     break;
                 }
                 __borrow = 1;
-                __diff += 0x100;
+                /* __diff += 0x100; */
                 __resultDigits[__index-1] = __diff;
                 __index++;
             }
@@ -2535,7 +2568,7 @@
                         __borrow = 0;
                     } else {
                         __borrow = 1;
-                        __diff += 0x100;
+                        /* __diff += 0x100; */
                     }
                     __resultDigits[__index-1] = __diff;
                     __index++;
@@ -3160,7 +3193,7 @@
 absSubtract:aLargeInteger
     "private helper for division:
         destructively subtract aLargeInteger from myself
-        return true, if the result is non-zero, false otherwise.
+        AND return true, if the result is non-zero, false otherwise.
         (i.e. this method has both a return value and a side-effect
          on the receiver)
         Only allowed for positive receiver and argument
@@ -3217,12 +3250,13 @@
                 _borrow = 0;
             } else {
                 _borrow = 1;
-                _diff += 0x10000;
+                /* _diff += 0x10000; */
             }
             ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
             anyBitNonZero |= (_diff & 0xFFFF);
             _index += 2;
         }
+
         if (_index <= _len2) {
             /*
              * cannot continue with shorts - there is an odd number of
@@ -3248,7 +3282,7 @@
                     RETURN (anyBitNonZero ? true : false);
                 }
                 _borrow = 1;
-                _diff += 0x10000;
+                /* _diff += 0x10000; */
 
                 ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
                 anyBitNonZero |= (_diff & 0xFFFF);
@@ -3267,7 +3301,7 @@
                 _borrow = 0;
             } else {
                 _borrow = 1;
-                _diff += 0x100;
+                /* _diff += 0x100; */
             }
             _myDigits[_index - 1] = _diff;
             anyBitNonZero |= (_diff & 0xFF);
@@ -3288,7 +3322,7 @@
                 break;
             }
             _borrow = 1;
-            _diff += 0x100;
+            /* _diff += 0x100; */
 
             _myDigits[_index - 1] = _diff;
             anyBitNonZero |= (_diff & 0xFF);
@@ -3565,5 +3599,5 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Attic/LargeInt.st,v 1.112 1999-06-02 10:49:21 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Attic/LargeInt.st,v 1.113 1999-06-02 12:56:46 cg Exp $'
 ! !
--- a/LargeInteger.st	Wed Jun 02 13:31:09 1999 +0200
+++ b/LargeInteger.st	Wed Jun 02 14:56:46 1999 +0200
@@ -2012,7 +2012,7 @@
             __diff = ((unsigned int *)(__digitP+__index-1))[0] - (__borrow & 0xFFFFFFFFL);
             __borrow >>= 32;
             if (__diff < 0) {
-                __diff += 0x100000000;
+                /* __diff += 0x100000000; */
                 __borrow++;
             }
             ((unsigned int *)(__resultP+__index-1))[0] = __diff;
@@ -2027,8 +2027,23 @@
             __diff = ((unsigned short *)(__digitP+__index-1))[0] - (__borrow & 0xFFFF);
             __borrow >>= 16;
             if (__diff < 0) {
-                __diff += 0x10000;
+                /* __diff += 0x10000; */
                 __borrow++;
+            } else {
+                if (__borrow == 0) {
+                    ((unsigned short *)(__resultP+__index-1))[0] = __diff;
+                    __index += 2;
+
+                    /* nothing more to subtract .. */
+                    while (__index < __len) {
+                        ((unsigned short *)(__resultP+__index-1))[0] = ((unsigned short *)(__digitP+__index-1))[0];
+                        __index += 2;
+                    }
+                    if (__index <= __len) {
+                        __resultP[__index-1] = __digitP[__index-1];
+                    }
+                    break;
+                }
             }
             ((unsigned short *)(__resultP+__index-1))[0] = __diff;
             __index += 2;
@@ -2038,8 +2053,20 @@
             __diff = __digitP[__index-1] - (__borrow & 0xFF);
             __borrow >>= 8;
             if (__diff < 0) {
-                __diff += 0x100;
+                /* __diff += 0x100; */
                 __borrow++;
+            } else {
+                if (__borrow == 0) {
+                    __resultP[__index-1] = __diff;
+                    __index++;
+
+                    /* nothing more to subtract .. */
+                    while (__index <= __len) {
+                        __resultP[__index-1] = __digitP[__index-1];
+                        __index++;
+                    }
+                    break;
+                }
             }
             __resultP[__index-1] = __diff;
             __index++;
@@ -2449,12 +2476,13 @@
                 __borrow = 0;
             } else {
                 __borrow = 1;
-                __diff += 0x10000;
+                /* __diff += 0x10000; */
             }
             ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
             __index += 2;
         }
-        if (__index <= __minLen) {
+
+        if (__index == __minLen) {
             /* one of the operands has odd length - cannot continue short-wise */
         } else {
             if (__len1 > __len2) {
@@ -2462,17 +2490,22 @@
                     __diff = ((unsigned short *)(__myDigits+__index-1))[0] - __borrow;
                     if (__diff >= 0) {
                         __borrow = 0;
+                        ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
+                        __index += 2;
+
                         /* copy over rest */
-                        __resultDigits[__index-1] = __diff;
-                        __index += 2;
                         while (__index < __len1) {
                             ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
                             __index+=2;
                         }
+                        if (__index <= __len1) {
+                            __resultDigits[__index-1] = __myDigits[__index-1];
+                            __index++;
+                        }
                         break;
                     }
                     __borrow = 1;
-                    __diff += 0x10000;
+                    /* __diff += 0x10000; */
                     ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
                     __index += 2;
                 }
@@ -2484,7 +2517,7 @@
                             __borrow = 0;
                         } else {
                             __borrow = 1;
-                            __diff += 0x10000;
+                            /* __diff += 0x10000; */
                         }
                         ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
                         __index += 2;
@@ -2502,7 +2535,7 @@
                 __borrow = 0;
             } else {
                 __borrow = 1;
-                __diff += 0x100;
+                /* __diff += 0x100; */
             }
             __resultDigits[__index-1] = __diff;
             __index++;
@@ -2523,7 +2556,7 @@
                     break;
                 }
                 __borrow = 1;
-                __diff += 0x100;
+                /* __diff += 0x100; */
                 __resultDigits[__index-1] = __diff;
                 __index++;
             }
@@ -2535,7 +2568,7 @@
                         __borrow = 0;
                     } else {
                         __borrow = 1;
-                        __diff += 0x100;
+                        /* __diff += 0x100; */
                     }
                     __resultDigits[__index-1] = __diff;
                     __index++;
@@ -3160,7 +3193,7 @@
 absSubtract:aLargeInteger
     "private helper for division:
         destructively subtract aLargeInteger from myself
-        return true, if the result is non-zero, false otherwise.
+        AND return true, if the result is non-zero, false otherwise.
         (i.e. this method has both a return value and a side-effect
          on the receiver)
         Only allowed for positive receiver and argument
@@ -3217,12 +3250,13 @@
                 _borrow = 0;
             } else {
                 _borrow = 1;
-                _diff += 0x10000;
+                /* _diff += 0x10000; */
             }
             ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
             anyBitNonZero |= (_diff & 0xFFFF);
             _index += 2;
         }
+
         if (_index <= _len2) {
             /*
              * cannot continue with shorts - there is an odd number of
@@ -3248,7 +3282,7 @@
                     RETURN (anyBitNonZero ? true : false);
                 }
                 _borrow = 1;
-                _diff += 0x10000;
+                /* _diff += 0x10000; */
 
                 ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
                 anyBitNonZero |= (_diff & 0xFFFF);
@@ -3267,7 +3301,7 @@
                 _borrow = 0;
             } else {
                 _borrow = 1;
-                _diff += 0x100;
+                /* _diff += 0x100; */
             }
             _myDigits[_index - 1] = _diff;
             anyBitNonZero |= (_diff & 0xFF);
@@ -3288,7 +3322,7 @@
                 break;
             }
             _borrow = 1;
-            _diff += 0x100;
+            /* _diff += 0x100; */
 
             _myDigits[_index - 1] = _diff;
             anyBitNonZero |= (_diff & 0xFF);
@@ -3565,5 +3599,5 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.112 1999-06-02 10:49:21 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.113 1999-06-02 12:56:46 cg Exp $'
 ! !