LargeInteger.st
changeset 19132 0c0046873268
parent 19126 98adb7dc1950
child 19135 e2d82660b855
--- a/LargeInteger.st	Mon Feb 01 15:12:58 2016 +0100
+++ b/LargeInteger.st	Mon Feb 01 15:24:23 2016 +0100
@@ -1524,17 +1524,18 @@
     unsigned INT swapped;
 
     swapped = ( (__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[0]) << 24)
-	      | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
-	      | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
-	      | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
+              | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
+              | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
+              | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
     RETURN (__MKUINT(swapped));
 %}.
+    ^ super byteSwapped32
 
     "
-     (LargeInteger value:16r11223344) byteSwapped hexPrintString
-     (LargeInteger value:16r44332211) byteSwapped hexPrintString
-     16r88776655 byteSwapped hexPrintString
-     16r11223344 byteSwapped hexPrintString
+     (LargeInteger value:16r11223344) byteSwapped32 hexPrintString
+     (LargeInteger value:16r44332211) byteSwapped32 hexPrintString
+     16r88776655 byteSwapped32 hexPrintString
+     16r11223344 byteSwapped32 hexPrintString
     "
 
     "Created: / 31-01-2012 / 11:07:42 / cg"
@@ -1551,14 +1552,14 @@
     unsigned INT swapped;
 
     swappedHI = ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[0]) << 24)
-	      | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
-	      | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
-	      | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
+              | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[1]) << 16)
+              | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[2]) << 8)
+              | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[3]));
     if (__byteArraySize(__INST(digitByteArray)) > 4) {
-	swappedLO = ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[4]) << 24)
-		  | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[5]) << 16)
-		  | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[6]) << 8)
-		  | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[7]));
+        swappedLO = ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[4]) << 24)
+                  | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[5]) << 16)
+                  | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[6]) << 8)
+                  | ((__ByteArrayInstPtr(__INST(digitByteArray))->ba_element[7]));
     }
 
 #if __POINTER_SIZE__ == 8
@@ -1568,6 +1569,7 @@
     RETURN(__MKLARGEINT64(1, swappedLO, swappedHI));
 #endif
 %}.
+    ^ super byteSwapped64
 
     "
      (LargeInteger value:16r11223344) byteSwapped64 hexPrintString
@@ -2391,39 +2393,61 @@
     anInteger == 1 ifTrue:[^ self].
 
     num := anInteger abs.
-    (num > 16r3FFFFF) ifTrue:[
-	"if num is too big (so that multiplying by a byte could create a Large)"
-
-	^ anInteger retry:#* coercing:self
+    SmallInteger maxBytes == 8 ifTrue:[
+        (num > 16r3FFFFFFF) ifTrue:[
+            "if num is too big (so that multiplying by a byte could create a Large)"
+            ^ anInteger retry:#* coercing:self
+        ].
+    ] ifFalse:[    
+        (num > 16r3FFFFF) ifTrue:[
+            "if num is too big (so that multiplying by a byte could create a Large)"
+            ^ anInteger retry:#* coercing:self
+        ].
     ].
 
     len := digitByteArray size.
 
     val := num.
     val <= 16rFF ifTrue:[
-	lResult := len + 1.
+        lResult := len + 1.
     ] ifFalse:[
-	val <= 16rFFFF ifTrue:[
-	    lResult := len + 2
-	] ifFalse:[
-	    val <= 16rFFFFFF ifTrue:[
-		lResult := len + 4.
-	    ] ifFalse:[
-		lResult := len + 6.
-	    ]
-	]
+        val <= 16rFFFF ifTrue:[
+            lResult := len + 2
+        ] ifFalse:[
+            val <= 16rFFFFFF ifTrue:[
+                lResult := len + 4.
+            ] ifFalse:[
+                val <= 16rFFFFFFFF ifTrue:[
+                    lResult := len + 6.
+                ] ifFalse:[
+                    val <= 16rFFFFFFFFFF ifTrue:[
+                        lResult := len + 8.
+                    ] ifFalse:[
+                        val <= 16rFFFFFFFFFF ifTrue:[
+                            lResult := len + 10.
+                        ] ifFalse:[
+                            val <= 16rFFFFFFFFFFFF ifTrue:[
+                                lResult := len + 12.
+                            ] ifFalse:[
+                                lResult := len + 14.
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ]
     ].
     resultDigitByteArray := ByteArray uninitializedNew:lResult.
     result := self class basicNew setDigits:resultDigitByteArray.
 
     anInteger < 0 ifTrue:[
-	sign > 0 ifTrue:[
-	    result setSign:-1
-	].
+        sign > 0 ifTrue:[
+            result setSign:-1
+        ].
     ] ifFalse:[
-	sign < 0 ifTrue:[
-	    result setSign:sign
-	]
+        sign < 0 ifTrue:[
+            result setSign:sign
+        ]
     ].
 
     ok := false.
@@ -2433,156 +2457,194 @@
     if (__isSmallInteger(len)
      && __isByteArray(__digitByteArray)
      && __isByteArray(resultDigitByteArray)) {
-	INT _l = __intVal(len);
-	INT _v = __intVal(val);
-	unsigned INT _carry = 0;
-	unsigned INT _prod;
-	unsigned char *digitP = __ByteArrayInstPtr(__digitByteArray)->ba_element;
-	unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
-
-	/*
-	 * skipping zeros does not help much (a few percent) on
-	 * a P5 or other CPUS with a fast multiplier.
-	 * It may make more of a difference on CPUs with slower 0-multiply.
-	 */
-	while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
-	    ((unsigned INT *)resultP)[0] = 0;
-	    digitP += sizeof(INT);
-	    resultP += sizeof(INT);
-	    _l -= sizeof(INT);
-	}
+        INT _l = __intVal(len);
+        INT _v = __intVal(val);
+        unsigned INT _carry = 0;
+        unsigned INT _prod;
+        unsigned char *digitP = __ByteArrayInstPtr(__digitByteArray)->ba_element;
+        unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
+
+        /*
+         * skipping zeros does not help much (a few percent) on
+         * a P5 or other CPUS with a fast multiplier.
+         * It may make more of a difference on CPUs with slower 0-multiply.
+         * Late news: it actually hurts modern x86_64 cpus.
+         * So only reenable for specific CPUs after concrete benchmarks.
+         */
+#if 0
+        while ((_l >= sizeof(INT)) && (((unsigned INT *)digitP)[0] == 0)) {
+            ((unsigned INT *)resultP)[0] = 0;
+            digitP += sizeof(INT);
+            resultP += sizeof(INT);
+            _l -= sizeof(INT);
+        }
+#endif
 
 #if defined(__LSBFIRST__)
 # if defined (__GNUC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
-	/*
-	 * can do it long-word-wise;
-	 * 32*32 -> 64 multiplication
-	 */
-	while (_l > 3) {
-	    unsigned __pHi, __pLow;
-	    unsigned __digit;
-
-	    /*
-	     * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
-	     * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
-	     */
-	    __digit = ((unsigned long *)digitP)[0];
-	    asm ("mull %3               \n\
-		  addl %4,%%eax         \n\
-		  adcl $0,%%edx"
-		    : "=a"  (__pLow),
-		      "=d"  (__pHi)
-		    : "0"   (__digit),
-		      "1"   ((unsigned long)(_v)),
-		      "rm"  ((unsigned long)(_carry)) );
-
-	    ((unsigned long *)resultP)[0] = __pLow;
-	    _carry = __pHi;
-	    digitP += 4;
-	    resultP += 4;
-	    _l -= 4;
-	}
+        /*
+         * can do it long-word-wise;
+         * 32*32 -> 64 multiplication
+         */
+        while (_l > 3) {
+            unsigned __pHi, __pLow;
+            unsigned __digit;
+
+            /*
+             * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
+             * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
+             */
+            __digit = ((unsigned long *)digitP)[0];
+            asm ("mull %3               \n\
+                  addl %4,%%eax         \n\
+                  adcl $0,%%edx"
+                    : "=a"  (__pLow),
+                      "=d"  (__pHi)
+                    : "0"   (__digit),
+                      "1"   ((unsigned long)(_v)),
+                      "rm"  ((unsigned long)(_carry)) );
+
+            ((unsigned long *)resultP)[0] = __pLow;
+            _carry = __pHi;
+            digitP += 4;
+            resultP += 4;
+            _l -= 4;
+        }
 # else /* not GNU-i386 */
 #  if defined(WIN32) && defined(__BORLANDC__) && defined(__i386__) && (__POINTER_SIZE__ == 4)
-	/*
-	 * can do it long-word-wise;
-	 * 32*32 -> 64 multiplication
-	 */
-	while (_l > 3) {
-	    unsigned __pLow;
-	    unsigned digit;
-
-	    /*
-	     * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
-	     * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
-	     */
+        /*
+         * can do it long-word-wise;
+         * 32*32 -> 64 multiplication
+         */
+        while (_l > 3) {
+            unsigned __pLow;
+            unsigned digit;
+
+            /*
+             * max: 0xFFFF.FFFF * 0xFFFF.FFFF -> 0xFFFF.FFFE.0000.0001
+             * + maxCarry (0xFFFF.FFFF)  -> 0xFFFF.FFFF.0000.0000
+             */
 /*
-	    digit = ((unsigned long *)digitP)[0];
-	    edx::eax = (digit * _v);
-	    edx::eax += _carry;
-	    ((unsigned long *)resultP)[0] = eax; -- pLow
-	    _carry = edx; -- pHigh
-	    digitP += 4;
-	    resultP += 4;
+            digit = ((unsigned long *)digitP)[0];
+            edx::eax = (digit * _v);
+            edx::eax += _carry;
+            ((unsigned long *)resultP)[0] = eax; -- pLow
+            _carry = edx; -- pHigh
+            digitP += 4;
+            resultP += 4;
 */
-	    digit = ((unsigned long *)digitP)[0];
-	    asm {
-		mov   eax, digit
-		mov   edx, _v
-		mul   edx
-		add   eax, _carry
-		adc   edx, 0
-		mov   __pLow, eax
-		mov   _carry, edx
-	    }
-
-	    ((unsigned long *)resultP)[0] = __pLow;
-	    digitP += 4;
-	    resultP += 4;
-	    _l -= 4;
-	}
+            digit = ((unsigned long *)digitP)[0];
+            asm {
+                mov   eax, digit
+                mov   edx, _v
+                mul   edx
+                add   eax, _carry
+                adc   edx, 0
+                mov   __pLow, eax
+                mov   _carry, edx
+            }
+
+            ((unsigned long *)resultP)[0] = __pLow;
+            digitP += 4;
+            resultP += 4;
+            _l -= 4;
+        }
 #  else /* not WIN32-i386 */
 #   if defined(INT64)
-	if (_v <= 0xFFFFFFFFL) {
-	    /*
-	     * have a 64bit int type ... good
-	     */
-	    UINT64 _prod64;
-
-	    /* have 64bit ints; can do it int-wise
-	     *
-	     * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
-	     * + maxCarry (0xFFFFFFFF)  -> 0xFFFFFFFF.0000
-	     */
-	    while (_l > 3) {
-		unsigned __t;
-
-		__t = ((unsigned *)digitP)[0];
-		digitP += 4;
-		_prod64 = (INT64)_v;
-		_prod64 *= __t;
-		_prod64 += _carry;
-		((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
-		_carry = _prod64 >> 32;
-		resultP += 4;
-		_l -= 4;
-	    }
-	    if (_l > 1) {
-		unsigned short __t;
-
-		__t = ((unsigned short *)digitP)[0];
-		digitP += 2;
-		_prod64 = (INT64)_v;
-		_prod64 *= __t;
-		_prod64 += _carry;
-		((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
-		_carry = _prod64 >> 16;
-		resultP += 2;
-		_l -= 2;
-	    }
-	    if (_l > 0) {
-		_prod64 = *digitP++ * _v + _carry;
-		*resultP++ = _prod64 /* & 0xFF */;
-		_carry = _prod64 >> 8;
-		_l--;
-	    }
-	}
+        if (_v <= 0xFFFFFFFFL) {
+            /* have 64bit ints; can do it int-wise
+             *
+             * max: 0xFFFFFFFF * 0xFFFFFFFF -> 0xFFFFFFFE.0001
+             * + maxCarry (0xFFFFFFFF)  -> 0xFFFFFFFF.0000
+             */
+            while (_l >= (4+4+4+4)) {
+                unsigned __t1, __t2, __t3, __t4;
+                UINT64 _prod64a, _prod64b, _prod64c, _prod64d;
+
+                __t1 = ((unsigned *)digitP)[0];
+                _prod64a = (INT64)_v;
+                _prod64a *= __t1;
+                _prod64a += _carry;
+                ((unsigned *)resultP)[0] = _prod64a /* & 0xFFFFFFFFL */;
+                _carry = _prod64a >> 32;
+
+                __t2 = ((unsigned *)digitP)[1];
+                _prod64b = (INT64)_v;
+                _prod64b *= __t2;
+                _prod64b += _carry;
+                ((unsigned *)resultP)[1] = _prod64b /* & 0xFFFFFFFFL */;
+                _carry = _prod64b >> 32;
+                
+                __t3 = ((unsigned *)digitP)[2];
+                _prod64c = (INT64)_v;
+                _prod64c *= __t3;
+                _prod64c += _carry;
+                ((unsigned *)resultP)[2] = _prod64c /* & 0xFFFFFFFFL */;
+                _carry = _prod64c >> 32;
+
+                __t4 = ((unsigned *)digitP)[3];
+                _prod64d = (INT64)_v;
+                _prod64d *= __t4;
+                _prod64d += _carry;
+                ((unsigned *)resultP)[3] = _prod64d /* & 0xFFFFFFFFL */;
+                _carry = _prod64d >> 32;
+
+                digitP += (4+4+4+4);
+                resultP += (4+4+4+4);
+                _l -= (4+4+4+4);
+            }
+            while (_l >= 4) {
+                unsigned __t;
+                UINT64 _prod64;
+
+                __t = ((unsigned *)digitP)[0];
+                digitP += 4;
+                _prod64 = (INT64)_v;
+                _prod64 *= __t;
+                _prod64 += _carry;
+                ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */;
+                _carry = _prod64 >> 32;
+                resultP += 4;
+                _l -= 4;
+            }
+            if (_l >= 2) {
+                unsigned short __t;
+                UINT64 _prod64;
+
+                __t = ((unsigned short *)digitP)[0];
+                digitP += 2;
+                _prod64 = (INT64)_v;
+                _prod64 *= __t;
+                _prod64 += _carry;
+                ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */;
+                _carry = _prod64 >> 16;
+                resultP += 2;
+                _l -= 2;
+            }
+            if (_l > 0) {
+                UINT64 _prod64;
+                _prod64 = *digitP++ * _v + _carry;
+                *resultP++ = _prod64 /* & 0xFF */;
+                _carry = _prod64 >> 8;
+                _l--;
+            }
+        }
 #   else /* no INT64 type */
-	if (_v <= 0xFFFF) {
-	    /* can do it short-wise
-	     *
-	     * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
-	     * + maxCarry (0xFFFF)  -> 0xFFFF.0000
-	     */
-	    while (_l > 1) {
-		_prod = ((unsigned short *)digitP)[0] * _v + _carry;
-		((unsigned short *)resultP)[0] = _prod /* & 0xFFFF */;
-		_carry = _prod >> 16;
-		digitP += 2;
-		resultP += 2;
-		_l -= 2;
-	    }
-	}
+        if (_v <= 0xFFFF) {
+            /* can do it short-wise
+             *
+             * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
+             * + maxCarry (0xFFFF)  -> 0xFFFF.0000
+             */
+            while (_l > 1) {
+                _prod = ((unsigned short *)digitP)[0] * _v + _carry;
+                ((unsigned short *)resultP)[0] = _prod /* & 0xFFFF */;
+                _carry = _prod >> 16;
+                digitP += 2;
+                resultP += 2;
+                _l -= 2;
+            }
+        }
 #   endif /* no INT64 */
 #  endif /* not WIN32-i386 */
 # endif /* not GNU-i386 */
@@ -2593,80 +2655,80 @@
    /* no, STORE_WORD_WISE makes it slower */
 # endif
 
-	if (_v <= 0xFFFF) {
-	    /* can do it short-wise
-	     *
-	     * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
-	     * + maxCarry (0xFFFF)  -> 0xFFFF.0000
-	     */
-	    while (_l > 1) {
-		unsigned int t;
+        if (_v <= 0xFFFF) {
+            /* can do it short-wise
+             *
+             * max: 0xFFFF * 0xFFFF -> 0xFFFE.0001
+             * + maxCarry (0xFFFF)  -> 0xFFFF.0000
+             */
+            while (_l > 1) {
+                unsigned int t;
 
 #if defined(LOAD_WORD_WISE)
-		/* better fetch short-wise */
-		t = ((unsigned short *)digitP)[0];
-		digitP += 2;
-		t = ((t >> 8) | (t << 8)) & 0xFFFF;
+                /* better fetch short-wise */
+                t = ((unsigned short *)digitP)[0];
+                digitP += 2;
+                t = ((t >> 8) | (t << 8)) & 0xFFFF;
 #else
-		t = (digitP[1]<<8) + digitP[0];
-		digitP += 2;
+                t = (digitP[1]<<8) + digitP[0];
+                digitP += 2;
 #endif
-		_prod = t * _v + _carry;
-		_carry = _prod >> 16;
+                _prod = t * _v + _carry;
+                _carry = _prod >> 16;
 #if defined(STORE_WORD_WISE)
-		/* better store short-wise */
-		_prod = ((_prod >> 8) | (_prod << 8)) & 0xFFFF;
-		((unsigned short *)resultP)[0] = _prod;
+                /* better store short-wise */
+                _prod = ((_prod >> 8) | (_prod << 8)) & 0xFFFF;
+                ((unsigned short *)resultP)[0] = _prod;
 #else
-		resultP[0] = _prod /* & 0xFF */;
-		resultP[1] = (_prod>>8) /* & 0xFF */;
+                resultP[0] = _prod /* & 0xFF */;
+                resultP[1] = (_prod>>8) /* & 0xFF */;
 #endif
-		resultP += 2;
-		_l -= 2;
-	    }
-	}
+                resultP += 2;
+                _l -= 2;
+            }
+        }
 
 #endif /* LSB_FIRST */
 
-	/*
-	 * rest is done byte-wise
-	 */
-	while (_l > 0) {
-	    _prod = *digitP++ * _v + _carry;
-	    *resultP++ = _prod /* & 0xFF */;
-	    _carry = _prod >> 8;
-	    _l--;
-	}
-
-	_l = __intVal(lResult) - __intVal(len);
-
-	/*
-	 * remaining carry
-	 */
-	while (_carry) {
-	    *resultP++ = _carry /* & 0xFF */;
-	    _carry >>= 8;
-	    _l--;
-	}
-
-	/*
-	 * remaining zeros
-	 */
-	while (_l--) {
-	    *resultP++ = 0;
-	}
-
-	/*
-	 * need compress ?
-	 */
-	if (resultP[-1]) {
-	    /*
-	     * no
-	     */
-	    RETURN(result);
-	}
-
-	ok = true;
+        /*
+         * rest is done byte-wise
+         */
+        while (_l > 0) {
+            _prod = *digitP++ * _v + _carry;
+            *resultP++ = _prod /* & 0xFF */;
+            _carry = _prod >> 8;
+            _l--;
+        }
+
+        _l = __intVal(lResult) - __intVal(len);
+
+        /*
+         * remaining carry
+         */
+        while (_carry) {
+            *resultP++ = _carry /* & 0xFF */;
+            _carry >>= 8;
+            _l--;
+        }
+
+        /*
+         * remaining zeros
+         */
+        while (_l--) {
+            *resultP++ = 0;
+        }
+
+        /*
+         * need compress ?
+         */
+        if (resultP[-1]) {
+            /*
+             * no
+             */
+            RETURN(result);
+        }
+
+        ok = true;
     }
 %}.
     "
@@ -2674,21 +2736,21 @@
      (could make it a primitive-failure as well)
     "
     ok ifFalse:[
-	carry := 0.
-	1 to:len do:[:i |
-	    prod := (digitByteArray basicAt:i) * val + carry.
-	    resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF).
-	    carry := prod bitShift:-8.
-	].
-	[carry ~~ 0] whileTrue:[
-	    len := len + 1.
-	    resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
-	    carry := carry bitShift:-8
-	].
-	[len < lResult] whileTrue:[
-	    len := len + 1.
-	    resultDigitByteArray basicAt:len put:0
-	]
+        carry := 0.
+        1 to:len do:[:i |
+            prod := (digitByteArray basicAt:i) * val + carry.
+            resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF).
+            carry := prod bitShift:-8.
+        ].
+        [carry ~~ 0] whileTrue:[
+            len := len + 1.
+            resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
+            carry := carry bitShift:-8
+        ].
+        [len < lResult] whileTrue:[
+            len := len + 1.
+            resultDigitByteArray basicAt:len put:0
+        ]
     ].
     ^ result compressed
 !
@@ -3613,49 +3675,58 @@
 #if defined(__LSBFIRST__)
     if (__isByteArray(__INST(digitByteArray))
      && __isLargeInteger(aLargeInteger)) {
-	OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
-
-	if (__isByteArray(_otherDigitByteArray)) {
-	    unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
-	    unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
-	    INT _myLen = __byteArraySize(__INST(digitByteArray));
-
-	    if (_myLen == __POINTER_SIZE__) {
-		INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
-		if (_otherLen == __POINTER_SIZE__) {
-		    unsigned INT _myVal = *((unsigned INT *)_myDigits);
-		    unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
-		    RETURN( (_myVal < _otherVal) ? true : false );
-		}
-	    }
+        OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
+
+        if (__isByteArray(_otherDigitByteArray)) {
+            unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
+            unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
+            INT _myLen = __byteArraySize(__INST(digitByteArray));
+            INT _otherLen = __byteArraySize(_otherDigitByteArray);
+
+            if (_myLen == __POINTER_SIZE__) {
+                if (_otherLen == __POINTER_SIZE__) {
+                    unsigned INT _myVal = *((unsigned INT *)_myDigits);
+                    unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
+                    RETURN( (_myVal < _otherVal) ? true : false );
+                }
+            }
 # if defined(UINT64) && (__POINTER_SIZE__ != 8)
-	    if (_myLen == __POINTER_SIZE__) {
-		INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
-		if (_otherLen <= 8) {
-		    UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
-		    UINT64 _otherVal = *((UINT64 *)_otherDigits);
-		    RETURN( (_myVal < _otherVal) ? true : false );
-		}
-	    } else {
-		if (_myLen <= 8) {
-		    INT _otherLen = __byteArraySize(_otherDigitByteArray);
-
-		    if (_otherLen <= 8) {
-			UINT64 _myVal = (*((UINT64 *)_myDigits));
-			UINT64 _otherVal = *((UINT64 *)_otherDigits);
-			RETURN( (_myVal < _otherVal) ? true : false );
-		    }
-		    if (_otherLen == __POINTER_SIZE__) {
-			UINT64 _myVal = (*((UINT64 *)_myDigits));
-			UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
-			RETURN( (_myVal < _otherVal) ? true : false );
-		    }
-		}
-	    }
+            if (_myLen == __POINTER_SIZE__) {
+                if (_otherLen <= 8) {
+                    UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
+                    UINT64 _otherVal = *((UINT64 *)_otherDigits);
+                    RETURN( (_myVal < _otherVal) ? true : false );
+                }
+            } else {
+                if (_myLen <= 8) {
+                    if (_otherLen <= 8) {
+                        UINT64 _myVal = (*((UINT64 *)_myDigits));
+                        UINT64 _otherVal = *((UINT64 *)_otherDigits);
+                        RETURN( (_myVal < _otherVal) ? true : false );
+                    }
+                    if (_otherLen == __POINTER_SIZE__) {
+                        UINT64 _myVal = (*((UINT64 *)_myDigits));
+                        UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
+                        RETURN( (_myVal < _otherVal) ? true : false );
+                    }
+                }
+            }
 # endif /* UINT64 */
-	}
+            while ((_myLen > 0) && (_myDigits[_myLen-1] == 0)) _myLen--;
+            while ((_otherLen > 0) && (_otherDigits[_otherLen-1] == 0)) _otherLen--;
+            if (_myLen < _otherLen) { RETURN( true ); }
+            if (_myLen > _otherLen) { RETURN (false ); }
+            while (_myLen-- > 0) {
+                unsigned char _d1 = _myDigits[_myLen];
+                unsigned char _d2 = _otherDigits[_myLen];
+                
+                if (_d1 != _d2) {
+                    if (_d1 < _d2) { RETURN( true ); }
+                    RETURN (false );
+                }
+            }
+            RETURN (false );
+        }
     }
 #endif /* LSBFIRST */
 %}.
@@ -3670,22 +3741,22 @@
     "/ numbers to be compared ...
 
     [myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
-	myLen := myLen - 1
+        myLen := myLen - 1
     ].
     [otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
-	otherLen := otherLen - 1
+        otherLen := otherLen - 1
     ].
     (myLen < otherLen) ifTrue:[^ true].
     (myLen > otherLen) ifTrue:[^ false].
 
     [myLen > 0] whileTrue:[
-	d1 := digitByteArray basicAt:myLen.
-	d2 := otherDigitByteArray basicAt:myLen.
-	d1 == d2 ifFalse:[
-	    (d1 < d2) ifTrue:[^ true].
-	    ^ false
-	].
-	myLen := myLen - 1
+        d1 := digitByteArray basicAt:myLen.
+        d2 := otherDigitByteArray basicAt:myLen.
+        d1 == d2 ifFalse:[
+            (d1 < d2) ifTrue:[^ true].
+            ^ false
+        ].
+        myLen := myLen - 1
     ].
     ^ false