class: LargeInteger
authorClaus Gittinger <cg@exept.de>
Mon, 27 May 2013 10:13:50 +0200
changeset 15326 7cc303092044
parent 15325 48feb23cd013
child 15327 0615616bb8da
class: LargeInteger comment/format in: #numberOfDigits: changed: #absMul: fixed a 64bit bug #absSubtract: #div2 #mul2 enhanced 64bit code
LargeInteger.st
--- a/LargeInteger.st	Mon May 27 10:12:49 2013 +0200
+++ b/LargeInteger.st	Mon May 27 10:13:50 2013 +0200
@@ -290,6 +290,8 @@
     "Modified: / 8.5.1998 / 21:40:41 / cg"
 ! !
 
+
+
 !LargeInteger class methodsFor:'queries'!
 
 isBuiltInClass
@@ -3930,267 +3932,267 @@
      && __isByteArray(otherDigitByteArray)
      && __isByteArray(resultDigitByteArray)
      && __bothSmallInteger(len1, len2)) {
-	unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
-	unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
-	unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
-	unsigned char *_p1, *_p2, *_pResult, *_pResult0, *_pResult1, *_p1Last, *_p2Last;
-	unsigned char *_pResultLast1;
-	unsigned INT _v;
-	int _len1 = __intVal(len1);
-	int _len2 = __intVal(len2);
-
-	_p1Last = myBytes    + _len1 - 1;  /* the last byte */
-	_p2Last = otherBytes + _len2 - 1;  /* the last byte */
-	_pResult0 = resultBytes;
-
-	/*
-	 *        aaa...aaa      f1[0] * f2
-	 *       bbb...bbb       f1[1] * f2
-	 *      ccc...ccc        f1[2] * f2
-	 *     ...
-	 *    xxx...xxx          f1[high] * f2
-	 *
-	 * start short-wise
-	 * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
-	 */
-	_p1 = myBytes;
+        unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+        unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+        unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+        unsigned char *_p1, *_p2, *_pResult, *_pResult0, *_pResult1, *_p1Last, *_p2Last;
+        unsigned char *_pResultLast1;
+        unsigned INT _v;
+        int _len1 = __intVal(len1);
+        int _len2 = __intVal(len2);
+
+        _p1Last = myBytes    + _len1 - 1;  /* the last byte */
+        _p2Last = otherBytes + _len2 - 1;  /* the last byte */
+        _pResult0 = resultBytes;
+
+        /*
+         *        aaa...aaa      f1[0] * f2
+         *       bbb...bbb       f1[1] * f2
+         *      ccc...ccc        f1[2] * f2
+         *     ...
+         *    xxx...xxx          f1[high] * f2
+         *
+         * start short-wise
+         * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
+         */
+        _p1 = myBytes;
 
 #if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
-	/* loop over ints of f1 */
-	for (; _p1 < _p1Last-2; _p1 += 4, _pResult0 += 4) {
-	    unsigned INT word1 = ((unsigned int *)_p1)[0];
-
-	    _pResult = _pResult0;
-	    _p2 = otherBytes;
-
-	    /* loop over ints of f2 */
-	    while (_p2 < (_p2Last-2)) {
-		_v = (word1 * ((unsigned int *)_p2)[0]) + ((unsigned int *)_pResult)[0];
-		((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
-		_v >>= 32; /* now _v contains the carry*/
-		_pResult += 4;
-		if (_v) {
-		    unsigned char *_pResultLast3;
-
-		    /* distribute carry - int-wise, then byte-wise */
-		    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
-		    for (_pResult1 = _pResult; _v; _pResult1 += 4) {
-			if (_pResult1 > _pResultLast3) break;
-			_v += ((unsigned int *)_pResult1)[0];
-			((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
-			_v >>= 32;
-		    }
-		    for (; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2 += 4;
-	    }
-
-	    /* possible odd highByte of f2 */
-	    while (_p2 <= _p2Last) {
-		_v = (word1 * _p2[0]) + ((unsigned int *)_pResult)[0];
-		((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
-		_v >>= 32; /* now _v contains the carry*/
-		_pResult += 4;
-		if (_v) {
-		    unsigned char *_pResultLast3;
-
-		    /* distribute carry - int-wise, then byte-wise */
-		    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
-		    for (_pResult1 = _pResult; _v; _pResult1 += 4) {
-			if (_pResult1 > _pResultLast3) break;
-			_v += ((unsigned int *)_pResult1)[0];
-			((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
-			_v >>= 32;
-		    }
-		    for (; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2++;
-	    }
-	}
+        /* loop over ints of f1 */
+        for (; _p1 < _p1Last-3; _p1 += 4, _pResult0 += 4) {
+            unsigned INT word1 = ((unsigned int *)_p1)[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
+
+            /* loop over ints of f2 */
+            while (_p2 < (_p2Last-3)) {
+                _v = (word1 * ((unsigned int *)_p2)[0]) + ((unsigned int *)_pResult)[0];
+                ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
+                _v >>= 32; /* now _v contains the carry*/
+                _pResult += 4;
+                if (_v) {
+                    unsigned char *_pResultLast3;
+
+                    /* distribute carry - int-wise, then byte-wise */
+                    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
+                    for (_pResult1 = _pResult; _v; _pResult1 += 4) {
+                        if (_pResult1 > _pResultLast3) break;
+                        _v += ((unsigned int *)_pResult1)[0];
+                        ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
+                        _v >>= 32;
+                    }
+                    for (; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 4;
+            }
+
+            /* possible odd highByte of f2 */
+            while (_p2 <= _p2Last) {
+                _v = (word1 * _p2[0]) + ((unsigned int *)_pResult)[0];
+                ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
+                _v >>= 32; /* now _v contains the carry*/
+                _pResult += 4;
+                if (_v) {
+                    unsigned char *_pResultLast3;
+
+                    /* distribute carry - int-wise, then byte-wise */
+                    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
+                    for (_pResult1 = _pResult; _v; _pResult1 += 4) {
+                        if (_pResult1 > _pResultLast3) break;
+                        _v += ((unsigned int *)_pResult1)[0];
+                        ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
+                        _v >>= 32;
+                    }
+                    for (; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
 #endif /* 64bit */
 
-	/* loop over shorts of f1 */
-	for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
-	    unsigned int short1 = ((unsigned short *)_p1)[0];
+        /* loop over shorts of f1 */
+        for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
+            unsigned int short1 = ((unsigned short *)_p1)[0];
 
 #if !defined(__LSBFIRST__)
-	    short1 = ((short1 >> 8) & 0xFF) | ((short1 & 0xFF) << 8);
+            short1 = ((short1 >> 8) & 0xFF) | ((short1 & 0xFF) << 8);
 #endif
-	    _pResult = _pResult0;
-	    _p2 = otherBytes;
-
-	    /* loop over shorts of f2 */
-	    while (_p2 < _p2Last) {
+            _pResult = _pResult0;
+            _p2 = otherBytes;
+
+            /* loop over shorts of f2 */
+            while (_p2 < _p2Last) {
 #if !defined(__LSBFIRST__)
-		unsigned int _short2;
-		unsigned int _short3;
-
-		_short2 = ((unsigned short *)_p2)[0];
-		_short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
-		_short3 = ((unsigned short *)_pResult)[0];
-		_short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
-		_v = (short1 * _short2) + _short3;
-		_pResult[0] = _v;
-		_pResult[1] = _v >> 8;
+                unsigned int _short2;
+                unsigned int _short3;
+
+                _short2 = ((unsigned short *)_p2)[0];
+                _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
+                _short3 = ((unsigned short *)_pResult)[0];
+                _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
+                _v = (short1 * _short2) + _short3;
+                _pResult[0] = _v;
+                _pResult[1] = _v >> 8;
 #else /* __LSBFIRST__ */
-		_v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
 #endif
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;
-		if (_v) {
-		    /* distribute carry - short-wise, then byte-wise */
-		    _pResult1 = _pResult;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;
+                if (_v) {
+                    /* distribute carry - short-wise, then byte-wise */
+                    _pResult1 = _pResult;
 #if defined(__LSBFIRST__)
-		    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
-		    for (; _v; _pResult1 += 2) {
-			if (_pResult1 > _pResultLast1) break;
-			_v += ((unsigned short *)_pResult1)[0];
-			((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
-			_v >>= 16;
-		    }
+                    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
+                    for (; _v; _pResult1 += 2) {
+                        if (_pResult1 > _pResultLast1) break;
+                        _v += ((unsigned short *)_pResult1)[0];
+                        ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
+                        _v >>= 16;
+                    }
 #endif
-		    for (; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2 += 2;
-	    }
-
-	    /* possible odd highByte of f2 */
-	    if (_p2 <= _p2Last) {
+                    for (; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 2;
+            }
+
+            /* possible odd highByte of f2 */
+            if (_p2 <= _p2Last) {
 #if !defined(__LSBFIRST__)
-		unsigned int _short3;
-
-		_short3 = ((unsigned short *)_pResult)[0];
-		_short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
-		_v = (short1 * _p2[0]) + _short3;
-		_pResult[0] = _v;
-		_pResult[1] = _v >> 8;
+                unsigned int _short3;
+
+                _short3 = ((unsigned short *)_pResult)[0];
+                _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
+                _v = (short1 * _p2[0]) + _short3;
+                _pResult[0] = _v;
+                _pResult[1] = _v >> 8;
 #else /* __LSBFIRST__ */
-		_v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
 #endif
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;
-		if (_v) {
-		    /* distribute carry - short-wise, then byte-wise */
-		    _pResult1 = _pResult;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;
+                if (_v) {
+                    /* distribute carry - short-wise, then byte-wise */
+                    _pResult1 = _pResult;
 #if defined(__LSBFIRST__)
-		    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
-		    for (; _v; _pResult1 += 2) {
-			if (_pResult1 > _pResultLast1) break;
-			_v += ((unsigned short *)_pResult1)[0];
-			((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
-			_v >>= 16;
-		    }
+                    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
+                    for (; _v; _pResult1 += 2) {
+                        if (_pResult1 > _pResultLast1) break;
+                        _v += ((unsigned short *)_pResult1)[0];
+                        ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
+                        _v >>= 16;
+                    }
 #endif
-		    for (; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2++;
-	    }
-	}
-
-	/* possible odd highByte of f1 (or byteLoop, if not __LSBFIRST__) */
-	for (; _p1 <= _p1Last; _p1++, _pResult0++) {
-	    unsigned int byte1 = _p1[0];
-
-	    _pResult = _pResult0;
-	    _p2 = otherBytes;
-
-	    /* loop over shorts of f2 */
-	    while (_p2 < _p2Last) {
+                    for (; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
+
+        /* possible odd highByte of f1 (or byteLoop, if not __LSBFIRST__) */
+        for (; _p1 <= _p1Last; _p1++, _pResult0++) {
+            unsigned int byte1 = _p1[0];
+
+            _pResult = _pResult0;
+            _p2 = otherBytes;
+
+            /* loop over shorts of f2 */
+            while (_p2 < _p2Last) {
 #if !defined(__LSBFIRST__)
-		unsigned int _short2;
-		unsigned int _short3;
-
-		_short2 = ((unsigned short *)_p2)[0];
-		_short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
-		_short3 = ((unsigned short *)_pResult)[0];
-		_short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
-		_v = (byte1 * _short2) + _short3;
-		_pResult[0] = _v;
-		_pResult[1] = _v >> 8;
+                unsigned int _short2;
+                unsigned int _short3;
+
+                _short2 = ((unsigned short *)_p2)[0];
+                _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
+                _short3 = ((unsigned short *)_pResult)[0];
+                _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
+                _v = (byte1 * _short2) + _short3;
+                _pResult[0] = _v;
+                _pResult[1] = _v >> 8;
 #else /* __LSBFIRST__ */
-		_v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
-		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
+                _v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
+                ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
 #endif
-		_v >>= 16; /* now _v contains the carry*/
-		_pResult += 2;
-		if (_v) {
-		    /* distribute carry - short-wise, then byte-wise */
-		    _pResult1 = _pResult;
+                _v >>= 16; /* now _v contains the carry*/
+                _pResult += 2;
+                if (_v) {
+                    /* distribute carry - short-wise, then byte-wise */
+                    _pResult1 = _pResult;
 #if defined(__LSBFIRST__)
-		    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
-		    for (_pResult1 = _pResult; _v; _pResult1 += 2) {
-			if (_pResult1 > _pResultLast1) break;
-			_v += ((unsigned short *)_pResult1)[0];
-			((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
-			_v >>= 16;
-		    }
+                    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
+                    for (_pResult1 = _pResult; _v; _pResult1 += 2) {
+                        if (_pResult1 > _pResultLast1) break;
+                        _v += ((unsigned short *)_pResult1)[0];
+                        ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
+                        _v >>= 16;
+                    }
 #endif /* __LSBFIRST__ */
-		    for (; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2 += 2;
-	    }
-
-	    /* possible odd highByte of f2 (or byteLoop, if not __LSBFIRST__) */
-	    while (_p2 <= _p2Last) {
-		_v = (byte1 * _p2[0]) + _pResult[0];
-		_pResult[0] = _v /* & 0xFF */;
-		_v >>= 8; /* now _v contains the carry*/
-		_pResult++;
-		if (_v) {
-		    /* distribute carry */
-		    for (_pResult1 = _pResult; _v; _pResult1++) {
-			_v += _pResult1[0];
-			_pResult1[0] = _v /* & 0xFF */;
-			_v >>= 8;
-		    }
-		}
-		_p2++;
-	    }
-	}
-	ok = true;
+                    for (; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2 += 2;
+            }
+
+            /* possible odd highByte of f2 (or byteLoop, if not __LSBFIRST__) */
+            while (_p2 <= _p2Last) {
+                _v = (byte1 * _p2[0]) + _pResult[0];
+                _pResult[0] = _v /* & 0xFF */;
+                _v >>= 8; /* now _v contains the carry*/
+                _pResult++;
+                if (_v) {
+                    /* distribute carry */
+                    for (_pResult1 = _pResult; _v; _pResult1++) {
+                        _v += _pResult1[0];
+                        _pResult1[0] = _v /* & 0xFF */;
+                        _v >>= 8;
+                    }
+                }
+                _p2++;
+            }
+        }
+        ok = true;
     }
 %}.
     ok ifFalse:[
-	1 to:len1 do:[:index1 |
-	    1 to:len2 do:[:index2 |
-		dstIndex := index1 + index2 - 1.
-		prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
-		prod := prod + (resultDigitByteArray basicAt:dstIndex).
-		resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
-		carry := prod bitShift:-8.
-		carry ~~ 0 ifTrue:[
-		    idx := dstIndex + 1.
-		    [carry ~~ 0] whileTrue:[
-			v := (resultDigitByteArray basicAt:idx) + carry.
-			resultDigitByteArray basicAt:idx put:(v bitAnd:255).
-			carry := v bitShift:-8.
-			idx := idx + 1
-		    ]
-		]
-	    ]
-	].
+        1 to:len1 do:[:index1 |
+            1 to:len2 do:[:index2 |
+                dstIndex := index1 + index2 - 1.
+                prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
+                prod := prod + (resultDigitByteArray basicAt:dstIndex).
+                resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
+                carry := prod bitShift:-8.
+                carry ~~ 0 ifTrue:[
+                    idx := dstIndex + 1.
+                    [carry ~~ 0] whileTrue:[
+                        v := (resultDigitByteArray basicAt:idx) + carry.
+                        resultDigitByteArray basicAt:idx put:(v bitAnd:255).
+                        carry := v bitShift:-8.
+                        idx := idx + 1
+                    ]
+                ]
+            ]
+        ].
     ].
     ^ result compressed
 !
@@ -4714,13 +4716,13 @@
 
 absSubtract:aLargeInteger
     "private helper for division:
-	destructively subtract aLargeInteger from myself
-	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
-	The receiver must be >= the argument.
-	The receiver must be a temporary scratch-number"
+        destructively subtract aLargeInteger from myself
+        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
+        The receiver must be >= the argument.
+        The receiver must be a temporary scratch-number"
 
     |otherDigitByteArray
      len1   "{ Class: SmallInteger }"
@@ -4736,12 +4738,12 @@
     otherDigitByteArray := aLargeInteger digitBytes.
     len2 := otherDigitByteArray size.
     len2 > len1 ifTrue:[
-	[(otherDigitByteArray at:len2) == 0] whileTrue:[
-	    len2 := len2 - 1
-	].
-	len2 > len1 ifTrue:[
-	    self error:'operation failed' "/ may not be called that way
-	].
+        [(otherDigitByteArray at:len2) == 0] whileTrue:[
+            len2 := len2 - 1
+        ].
+        len2 > len1 ifTrue:[
+            self error:'operation failed' "/ may not be called that way
+        ].
     ].
     "/ knowing that len2 is <= len1
 %{
@@ -4750,147 +4752,147 @@
 
     if (__isByteArray(_digitByteArray)
      && __isByteArray(otherDigitByteArray)) {
-	int _len1 = __intVal(len1),
-	    _len2 = __intVal(len2);
-	unsigned char *_myDigits, *_otherDigits;
-	int _index = 1, _borrow = 0;
-	INT _diff;
-	INT anyBitNonZero = 0;
-
-	_otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
-	_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
+        int _len1 = __intVal(len1),
+            _len2 = __intVal(len2);
+        unsigned char *_myDigits, *_otherDigits;
+        int _index = 1, _borrow = 0;
+        INT _diff;
+        int anyBitNonZero = 0;
+
+        _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
+        _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
 
 #if defined(__LSBFIRST__)
 # if __POINTER_SIZE__ == 8
-	{
-	    int _len2Q;
-	    /*
-	     * subtract int-wise
-	     */
-	    _len2Q = _len2-2;
-	    while (_index < _len2Q) {
-		/* do not combine the expression below (may lead to unsigned result on some machines */
-		_diff = ((unsigned int *)(_myDigits+_index-1))[0];
-		_diff -= ((unsigned int *)(_otherDigits+_index-1))[0];
-		_diff -= _borrow;
-		if (_diff >= 0) {
-		    _borrow = 0;
-		} else {
-		    _borrow = 1;
-		    /* _diff += 0x10000; */
-		}
-		((unsigned int *)(_myDigits+_index-1))[0] = _diff;
-		anyBitNonZero |= (_diff & 0xFFFFFFFFL);
-		_index += 4;
-	    }
-	}
+        {
+            int _len2Q;
+            /*
+             * subtract int-wise
+             */
+            _len2Q = _len2-2;
+            while (_index < _len2Q) {
+                /* do not combine the expression below (may lead to unsigned result on some machines */
+                _diff = ((unsigned int *)(_myDigits+_index-1))[0];
+                _diff -= ((unsigned int *)(_otherDigits+_index-1))[0];
+                _diff -= _borrow;
+                if (_diff >= 0) {
+                    _borrow = 0;
+                } else {
+                    _borrow = 1;
+                    /* _diff += 0x10000; */
+                }
+                ((unsigned int *)(_myDigits+_index-1))[0] = _diff;
+                anyBitNonZero |= (_diff & 0xFFFFFFFFL);
+                _index += 4;
+            }
+        }
 # endif
 
-	/*
-	 * subtract short-wise
-	 */
-	while (_index < _len2) {
-	    /* do not combine the expression below (may lead to unsigned result on some machines */
-	    _diff = ((unsigned short *)(_myDigits+_index-1))[0];
-	    _diff -= ((unsigned short *)(_otherDigits+_index-1))[0];
-	    _diff -= _borrow;
-	    if (_diff >= 0) {
-		_borrow = 0;
-	    } else {
-		_borrow = 1;
-		/* _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
-	     * bytes in the minuent
-	     */
-	} else {
-	    while (_index < _len1) {
-		/* do not combine the expression below (may lead to unsigned result on some machines */
-		_diff = ((unsigned short *)(_myDigits+_index-1))[0];
-		_diff -= _borrow;
-		if (_diff >= 0) {
-		    /* _borrow = 0; */
-		    ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
-		    anyBitNonZero |= (_diff & 0xFFFF);
-		    _index += 2;
-		    while (_index < _len1) {
-			anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0];
-			if (anyBitNonZero) {
-			    RETURN (true);
-			}
-			_index += 2;
-		    }
-		    /* last odd index */
-		    if (_index <= _len1) {
-			anyBitNonZero |= _myDigits[_index - 1];;
-			if (anyBitNonZero) {
-			    RETURN (true);
-			}
-			_index++;
-		    }
-		    RETURN (anyBitNonZero ? true : false);
-		}
-		_borrow = 1;
-		/* _diff += 0x10000; */
-
-		((unsigned short *)(_myDigits+_index-1))[0] = _diff;
-		anyBitNonZero |= (_diff & 0xFFFF);
-		_index += 2;
-	    }
-	}
+        /*
+         * subtract short-wise
+         */
+        while (_index < _len2) {
+            /* do not combine the expression below (may lead to unsigned result on some machines */
+            _diff = ((unsigned short *)(_myDigits+_index-1))[0];
+            _diff -= ((unsigned short *)(_otherDigits+_index-1))[0];
+            _diff -= _borrow;
+            if (_diff >= 0) {
+                _borrow = 0;
+            } else {
+                _borrow = 1;
+                /* _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
+             * bytes in the minuent
+             */
+        } else {
+            while (_index < _len1) {
+                /* do not combine the expression below (may lead to unsigned result on some machines */
+                _diff = ((unsigned short *)(_myDigits+_index-1))[0];
+                _diff -= _borrow;
+                if (_diff >= 0) {
+                    /* _borrow = 0; */
+                    ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
+                    anyBitNonZero |= (_diff & 0xFFFF);
+                    _index += 2;
+                    while (_index < _len1) {
+                        anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0];
+                        if (anyBitNonZero) {
+                            RETURN (true);
+                        }
+                        _index += 2;
+                    }
+                    /* last odd index */
+                    if (_index <= _len1) {
+                        anyBitNonZero |= _myDigits[_index - 1];;
+                        if (anyBitNonZero) {
+                            RETURN (true);
+                        }
+                        _index++;
+                    }
+                    RETURN (anyBitNonZero ? true : false);
+                }
+                _borrow = 1;
+                /* _diff += 0x10000; */
+
+                ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
+                anyBitNonZero |= (_diff & 0xFFFF);
+                _index += 2;
+            }
+        }
 #endif
-	/*
-	 * subtract byte-wise
-	 */
-	while (_index <= _len2) {
-	    /* do not combine the expression below (may lead to unsigned result on some machines */
-	    _diff = _myDigits[_index - 1];
-	    _diff -= _otherDigits[_index - 1];
-	    _diff -= _borrow;
-	    if (_diff >= 0) {
-		_borrow = 0;
-	    } else {
-		_borrow = 1;
-		/* _diff += 0x100; */
-	    }
-	    _myDigits[_index - 1] = _diff;
-	    anyBitNonZero |= (_diff & 0xFF);
-	    _index++;
-	}
-
-	while (_index <= _len1) {
-	    /* do not combine the expression below (may lead to unsigned result on some machines */
-	    _diff = _myDigits[_index - 1];
-	    _diff -= _borrow;
-	    if (_diff >= 0) {
-		/* _borrow = 0; */
-		_myDigits[_index - 1] = _diff;
-		anyBitNonZero |= (_diff & 0xFF);
-		_index++;
-		while (_index <= _len1) {
-		    anyBitNonZero |= _myDigits[_index - 1];
-		    if (anyBitNonZero) {
-			RETURN (true);
-		    }
-		    _index++;
-		}
-		break;
-	    }
-	    _borrow = 1;
-	    /* _diff += 0x100; */
-
-	    _myDigits[_index - 1] = _diff;
-	    anyBitNonZero |= (_diff & 0xFF);
-	    _index++;
-	}
-	RETURN (anyBitNonZero ? true : false);
+        /*
+         * subtract byte-wise
+         */
+        while (_index <= _len2) {
+            /* do not combine the expression below (may lead to unsigned result on some machines */
+            _diff = _myDigits[_index - 1];
+            _diff -= _otherDigits[_index - 1];
+            _diff -= _borrow;
+            if (_diff >= 0) {
+                _borrow = 0;
+            } else {
+                _borrow = 1;
+                /* _diff += 0x100; */
+            }
+            _myDigits[_index - 1] = _diff;
+            anyBitNonZero |= (_diff & 0xFF);
+            _index++;
+        }
+
+        while (_index <= _len1) {
+            /* do not combine the expression below (may lead to unsigned result on some machines */
+            _diff = _myDigits[_index - 1];
+            _diff -= _borrow;
+            if (_diff >= 0) {
+                /* _borrow = 0; */
+                _myDigits[_index - 1] = _diff;
+                anyBitNonZero |= (_diff & 0xFF);
+                _index++;
+                while (_index <= _len1) {
+                    anyBitNonZero |= _myDigits[_index - 1];
+                    if (anyBitNonZero) {
+                        RETURN (true);
+                    }
+                    _index++;
+                }
+                break;
+            }
+            _borrow = 1;
+            /* _diff += 0x100; */
+
+            _myDigits[_index - 1] = _diff;
+            anyBitNonZero |= (_diff & 0xFF);
+            _index++;
+        }
+        RETURN (anyBitNonZero ? true : false);
     }
 %}.
 
@@ -4898,26 +4900,26 @@
     borrow := 0.
 
     [index <= len1] whileTrue:[
-	diff := borrow.
-	diff := diff + (digitByteArray basicAt:index).
-	index <= len2 ifTrue:[
-	    diff := diff - (otherDigitByteArray basicAt:index).
-	].
-
-	"/ workaround for
-	"/ gcc code generator bug
-
-	(diff >= 0) ifTrue:[
-	    borrow := 0
-	] ifFalse:[
-	    borrow := -1.
-	    diff := diff + 16r100
-	].
-	diff ~~ 0 ifTrue:[
-	    notZero := true
-	].
-	digitByteArray basicAt:index put:diff.
-	index := index + 1
+        diff := borrow.
+        diff := diff + (digitByteArray basicAt:index).
+        index <= len2 ifTrue:[
+            diff := diff - (otherDigitByteArray basicAt:index).
+        ].
+
+        "/ workaround for
+        "/ gcc code generator bug
+
+        (diff >= 0) ifTrue:[
+            borrow := 0
+        ] ifFalse:[
+            borrow := -1.
+            diff := diff + 16r100
+        ].
+        diff ~~ 0 ifTrue:[
+            notZero := true
+        ].
+        digitByteArray basicAt:index put:diff.
+        index := index + 1
     ].
 
     ^ notZero
@@ -4929,7 +4931,8 @@
 
 div2
     "private helper for division:
-       destructively divide the receiver by 2."
+       destructively divide the receiver by 2.
+       may leave the receiver unnormalized (i.e. with a leftover 0 high-byte)"
 
     |prevBit|
 
@@ -4937,100 +4940,103 @@
     OBJ __digits = __INST(digitByteArray);
 
     if (__isByteArray(__digits)) {
-	int __nBytes = __byteArraySize(__digits);
-	unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
-	unsigned INT __this, __next;
-	int __idx;
-
-	if (__nBytes == 1) {
-	    __bp[0] >>= 1;
-	    RETURN (self);
-	}
-
-	__idx = 1;
-
-#if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
-	if (sizeof(unsigned INT) == 8) {
-	    int __endIndex = __nBytes - 8;
-
-	    if (__idx < __endIndex) {
-		__this = ((unsigned INT *)__bp)[0];
-
-		while (__idx < __endIndex) {
-		    __next = ((unsigned INT *)__bp)[1];
-		    __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
-		    __this |= __next << 63;
-		    ((unsigned INT *)__bp)[0] = __this;
-		    __this = __next;
-		    __bp += 8;
-		    __idx += 8;
-		}
-	    }
-	}
-#else
-# if defined(__LSBFIRST__)
-	if (sizeof(unsigned int) == 4) {
-	    int __endIndex = __nBytes - 4;
-
-	    if (__idx < __endIndex) {
-		__this = ((unsigned INT *)__bp)[0];
-
-# if 0
-		__idx += 4;
-		while (__idx < __endIndex) {
-		    __next = ((unsigned int *)__bp)[1];
-		    __this = (__this >> 1) /* & 0x7FFFFFF */;
-		    __this |= __next << 31;
-		    ((unsigned int *)__bp)[0] = __this;
-		    __this = __next;
-
-		    __next = ((unsigned int *)__bp)[2];
-		    __this = (__this >> 1) /* & 0x7FFFFFF */;
-		    __this |= __next << 31;
-		    ((unsigned int *)__bp)[1] = __this;
-		    __this = __next;
-
-		    __bp += 8;
-		    __idx += 8;
-		}
-		__idx -= 4;
-# endif
-		while (__idx < __endIndex) {
-		    __next = ((unsigned int *)__bp)[1];
-		    __this = (__this >> 1) /* & 0x7FFFFFF */;
-		    __this |= __next << 31;
-		    ((unsigned int *)__bp)[0] = __this;
-		    __this = __next;
-		    __bp += 4;
-		    __idx += 4;
-		}
-	    }
-	}
+        int __nBytes = __byteArraySize(__digits);
+        unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
+        unsigned INT __this, __next;
+        int __idx;
+
+        if (__nBytes == 1) {
+            __bp[0] >>= 1;
+            RETURN (self);
+        }
+
+        __idx = 1;
+
+#if defined(__LSBFIRST__) 
+# if (__POINTER_SIZE__ == 8)
+        if (sizeof(unsigned INT) == 8) {
+            int __endIndex = __nBytes - 8;
+
+            if (__idx < __endIndex) {
+                __this = ((unsigned INT *)__bp)[0];
+
+                while (__idx < __endIndex) {
+                    __next = ((unsigned INT *)__bp)[1];
+                    __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
+                    __this |= __next << 63;
+                    ((unsigned INT *)__bp)[0] = __this;
+                    __this = __next;
+                    __bp += 8;
+                    __idx += 8;
+                }
+            }
+
+            if (__idx < (__nBytes - 4)) {
+                __this = ((unsigned int *)__bp)[0];
+
+                __next = ((unsigned int *)__bp)[1];
+                __this = (__this >> 1) /* & 0x7FFFFFF */;
+                __this |= __next << 31;
+                ((unsigned int *)__bp)[0] = __this;
+                __this = __next;
+                __bp += 4;
+                __idx += 4;
+            }
+            if (__idx < (__nBytes - 2)) {
+                __this = ((unsigned short *)__bp)[0];
+
+                __next = ((unsigned short *)__bp)[1];
+                __this = (__this >> 1) /* & 0x7FFFFFF */;
+                __this |= __next << 15;
+                ((unsigned short *)__bp)[0] = __this;
+                __this = __next;
+                __bp += 2;
+                __idx += 2;
+            }
+        }
+# else
+        if (sizeof(unsigned int) == 4) {
+            int __endIndex = __nBytes - 4;
+
+            if (__idx < __endIndex) {
+                __this = ((unsigned int *)__bp)[0];
+
+                while (__idx < __endIndex) {
+                    __next = ((unsigned int *)__bp)[1];
+                    __this = (__this >> 1) /* & 0x7FFFFFF */;
+                    __this |= __next << 31;
+                    ((unsigned int *)__bp)[0] = __this;
+                    __this = __next;
+                    __bp += 4;
+                    __idx += 4;
+                }
+            }
+        }
 # endif
 #endif
 
-	__this = __bp[0];
-	while (__idx < __nBytes) {
-	    __next = __bp[1];
-	    __this >>= 1;
-	    __this |= __next << 7;
-	    __bp[0] = __this;
-	    __this = __next;
-	    __bp++;
-	    __idx++;
-	}
-	__bp[0] = __this >> 1;
-	RETURN (self);
+        __this = __bp[0];
+        while (__idx < __nBytes) {
+            __next = __bp[1];
+            __this >>= 1;
+            __this |= __next << 7;
+            __bp[0] = __this;
+            __this = __next;
+            __bp++;
+            __idx++;
+        }
+        __bp[0] = __this >> 1;
+        RETURN (self);
     }
 %}.
 
     prevBit := 0.
     digitByteArray size to:1 by:-1 do:[:idx |
-	|thisByte|
-
-	thisByte := digitByteArray at:idx.
-	digitByteArray at:idx put:((thisByte bitShift:-1) bitOr:prevBit).
-	prevBit := (thisByte bitAnd:1) bitShift:7.
+        |thisByte|
+
+        thisByte := digitByteArray at:idx.
+        digitByteArray at:idx put:((thisByte bitShift:-1) bitOr:prevBit).
+        prevBit := (thisByte bitAnd:1) bitShift:7.
     ].
 
     "
@@ -5054,71 +5060,81 @@
 
     b := digitByteArray at:nBytes.
     (b bitAnd:16r80) ~~ 0 ifTrue:[
-	"/ need another byte
-	nBytes := nBytes + 1.
-	t := ByteArray uninitializedNew:nBytes.
-	t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
-	t at:nBytes put:0.
-	digitByteArray := t.
+        "/ need another byte
+        nBytes := nBytes + 1.
+        t := ByteArray uninitializedNew:nBytes.
+        t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
+        t at:nBytes put:0.
+        digitByteArray := t.
     ].
 
 %{
     OBJ __digits = __INST(digitByteArray);
 
     if (__isByteArray(__digits)) {
-	int __nBytes = __intVal(nBytes);
-	unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
-	unsigned INT __carry = 0, __newCarry;
+        int __nBytes = __intVal(nBytes);
+        unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
+        unsigned INT __carry = 0, __newCarry;
 
 #if defined(__LSBFIRST__)
 # if (__POINTER_SIZE__ == 8)
-	if (sizeof(unsigned INT) == 8) {
-	    while (__nBytes >= 8) {
-		unsigned INT __this;
-
-		__this = ((unsigned INT *)__bp)[0];
-		__newCarry = (__this >> 63) /* & 1 */;
-		((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
-		__carry = __newCarry;
-		__bp += 8;
-		__nBytes -= 8;
-	    }
-	}
+        if (sizeof(unsigned INT) == 8) {
+            while (__nBytes >= 8) {
+                unsigned INT __this;
+
+                __this = ((unsigned INT *)__bp)[0];
+                __newCarry = (__this >> 63) /* & 1 */;
+                ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
+                __carry = __newCarry;
+                __bp += 8;
+                __nBytes -= 8;
+            }
+        }
 # endif
-	if (sizeof(unsigned int) == 4) {
-	    while (__nBytes >= 4) {
-		unsigned int __this;
-
-		__this = ((unsigned int *)__bp)[0];
-		__newCarry = (__this >> 31) /* & 1 */;
-		((unsigned int *)__bp)[0] = (__this << 1) | __carry;
-		__carry = __newCarry;
-		__bp += 4;
-		__nBytes -= 4;
-	    }
-	}
+        if (sizeof(unsigned int) == 4) {
+            while (__nBytes >= 4) {
+                unsigned int __this;
+
+                __this = ((unsigned int *)__bp)[0];
+                __newCarry = (__this >> 31) /* & 1 */;
+                ((unsigned int *)__bp)[0] = (__this << 1) | __carry;
+                __carry = __newCarry;
+                __bp += 4;
+                __nBytes -= 4;
+            }
+        }
+        if (__nBytes >= 2) {
+            unsigned short __this;
+
+            __this = ((unsigned short *)__bp)[0];
+            __newCarry = (__this >> 15) /* & 1 */;
+            ((unsigned short *)__bp)[0] = (__this << 1) | __carry;
+            __carry = __newCarry;
+            __bp += 2;
+            __nBytes -= 2;
+        }
 #endif /* LSBFIRST */
-	while (__nBytes) {
-	    unsigned char __this;
-
-	    __this = __bp[0];
-	    __newCarry = (__this >> 7) /* & 1 */;
-	    __bp[0] = (__this << 1) | __carry;
-	    __carry = __newCarry;
-	    __bp++;
-	    __nBytes--;
-	}
-	RETURN (self);
+        while (__nBytes) {
+            unsigned char __this;
+
+            __this = __bp[0];
+            __newCarry = (__this >> 7) /* & 1 */;
+            __bp[0] = (__this << 1) | __carry;
+            __carry = __newCarry;
+            __bp++;
+            __nBytes--;
+        }
+        RETURN (self);
     }
 %}.
 
     prevBit := 0.
     1 to:digitByteArray size do:[:idx |
-	|thisByte|
-
-	thisByte := digitByteArray at:idx.
-	digitByteArray at:idx put:(((thisByte bitShift:1) bitAnd:16rFF) bitOr:prevBit).
-	prevBit := (thisByte bitShift:-7) bitAnd:1.
+        |thisByte|
+
+        thisByte := digitByteArray at:idx.
+        digitByteArray at:idx put:(((thisByte bitShift:1) bitAnd:16rFF) bitOr:prevBit).
+        prevBit := (thisByte bitShift:-7) bitAnd:1.
     ].
 
     "
@@ -5206,10 +5222,10 @@
 !LargeInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.209 2013-05-21 20:44:47 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.210 2013-05-27 08:13:50 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.209 2013-05-21 20:44:47 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.210 2013-05-27 08:13:50 cg Exp $'
 ! !