LargeInteger.st
changeset 4157 f9a673441ba5
parent 4151 6d6971c27567
child 4160 5fb87a530e29
equal deleted inserted replaced
4156:3079a5a94617 4157:f9a673441ba5
  1725 
  1725 
  1726     len1 := digitByteArray size.
  1726     len1 := digitByteArray size.
  1727     otherDigitByteArray := aLargeInteger digits.
  1727     otherDigitByteArray := aLargeInteger digits.
  1728     len2 := otherDigitByteArray size.
  1728     len2 := otherDigitByteArray size.
  1729 
  1729 
       
  1730     "/ the highest digit(s) should not be zero
       
  1731     "/ when properly normalized; 
       
  1732     "/ but we are tolerant here, to allow for unnormalized
       
  1733     "/ numbers to be compared ...
       
  1734 
  1730     [(digitByteArray basicAt:len1) == 0] whileTrue:[
  1735     [(digitByteArray basicAt:len1) == 0] whileTrue:[
  1731 	len1 := len1 - 1
  1736         len1 := len1 - 1
  1732     ].
  1737     ].
  1733     [(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
  1738     [(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
  1734 	len2 := len2 - 1
  1739         len2 := len2 - 1
  1735     ].
  1740     ].
  1736     (len1 ~~ len2) ifTrue:[^ false].
  1741     (len1 ~~ len2) ifTrue:[^ false].
  1737     [len1 > 0] whileTrue:[
  1742     [len1 > 0] whileTrue:[
  1738 	d1 := digitByteArray basicAt:len1.
  1743         d1 := digitByteArray basicAt:len1.
  1739 	d2 := otherDigitByteArray basicAt:len1.
  1744         d2 := otherDigitByteArray basicAt:len1.
  1740 	(d1 ~~ d2) ifTrue:[^ false].
  1745         (d1 ~~ d2) ifTrue:[^ false].
  1741 	len1 := len1 - 1
  1746         len1 := len1 - 1
  1742     ].
  1747     ].
  1743     ^ true
  1748     ^ true
       
  1749 
       
  1750     "Modified: / 8.5.1999 / 18:37:02 / cg"
  1744 !
  1751 !
  1745 
  1752 
  1746 absFastDivMod:aPositiveSmallInteger
  1753 absFastDivMod:aPositiveSmallInteger
  1747     "return an array with two LargeIntegers representing
  1754     "return an array with two LargeIntegers representing
  1748      abs(self) // aPositiveSmallInteger and abs(self) \\ aPositiveSmallInteger"
  1755      abs(self) // aPositiveSmallInteger and abs(self) \\ aPositiveSmallInteger"
  1930      rsltLen "{ Class: SmallInteger }"
  1937      rsltLen "{ Class: SmallInteger }"
  1931      index "{ Class: SmallInteger }"
  1938      index "{ Class: SmallInteger }"
  1932      carry "{ Class: SmallInteger }" |
  1939      carry "{ Class: SmallInteger }" |
  1933 
  1940 
  1934     "/ the following code only works with
  1941     "/ the following code only works with
  1935     "/ smallIntegers in te range _MIN_INT+255 .. _MAX_INT-255
  1942     "/ smallIntegers in the range _MIN_INT+255 .. _MAX_INT-255
  1936 
  1943 
  1937     ((aSmallInteger < (SmallInteger minVal + 255))
  1944     ((aSmallInteger < (SmallInteger minVal + 255))
  1938     or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
  1945     or:[aSmallInteger > (SmallInteger maxVal - 255)]) ifTrue:[
  1939 	^ self absPlus:(LargeInteger value:aSmallInteger).
  1946         ^ self absPlus:(LargeInteger value:aSmallInteger).
  1940     ]. 
  1947     ]. 
  1941 
  1948 
  1942     len := digitByteArray size.
  1949     len := digitByteArray size.
  1943     rsltLen := len + 1.
  1950     rsltLen := len + 1.
  1944 
  1951 
  1947 
  1954 
  1948 %{
  1955 %{
  1949     if (__isByteArray(__INST(digitByteArray))
  1956     if (__isByteArray(__INST(digitByteArray))
  1950      && __isByteArray(resultDigitByteArray)
  1957      && __isByteArray(resultDigitByteArray)
  1951      && __isSmallInteger(aSmallInteger)) {
  1958      && __isSmallInteger(aSmallInteger)) {
  1952 	int __carry = __intVal(aSmallInteger);
  1959         int __carry = __intVal(aSmallInteger);
  1953 	int __index = 1;
  1960         int __index = 1;
  1954 	int __len = __intVal(len);
  1961         int __len = __intVal(len);
  1955 	unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
  1962         unsigned char *__src = (unsigned char *)(__ByteArrayInstPtr(__INST(digitByteArray))->ba_element);
  1956 	unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
  1963         unsigned char *__dst = (unsigned char *)(__ByteArrayInstPtr(resultDigitByteArray)->ba_element);
  1957 	int __lastDigit = 0;
  1964         int __lastDigit = 0;
  1958 
  1965 
  1959 	if (__carry < 0) {
  1966         if (__carry < 0) {
  1960 	    __carry = -__carry;
  1967             __carry = -__carry;
  1961 	}
  1968         }
  1962 
  1969 
  1963 	while (__carry) {
  1970         while (__carry) {
  1964 	    if (__index <= __len) {
  1971             if (__index <= __len) {
  1965 		__carry += __src[__index-1];
  1972                 __carry += __src[__index-1];
  1966 	    }
  1973             }
  1967 	    __dst[__index-1] = __lastDigit = __carry & 0xFF;
  1974             __dst[__index-1] = __lastDigit = __carry & 0xFF;
  1968 	    __carry >>= 8;
  1975             __carry >>= 8;
  1969 	    __index++;
  1976             __index++;
  1970 	}
  1977         }
  1971 	if (__index <= __intVal(rsltLen)) {
  1978         if (__index <= __intVal(rsltLen)) {
  1972 	    while (__index <= __len) {
  1979             while (__index <= __len) {
  1973 		__dst[__index-1] = __src[__index-1];
  1980                 __dst[__index-1] = __src[__index-1];
  1974 		__index++;
  1981                 __index++;
  1975 	    }
  1982             }
  1976 	    __lastDigit = 0;
  1983             __lastDigit = 0;
  1977 	}
  1984         }
  1978 	if (lastDigit) {
  1985         if (lastDigit) {
  1979 	    RETURN (result);
  1986             RETURN (result);
  1980 	}
  1987         }
  1981 	ok = true;
  1988         ok = true;
  1982     }
  1989     }
  1983 %}.
  1990 %}.
  1984 
  1991 
  1985     ok ~~ true ifTrue:[
  1992     ok ~~ true ifTrue:[
  1986 	index := 1.
  1993         index := 1.
  1987 	carry := aSmallInteger abs.
  1994         carry := aSmallInteger abs.
  1988 
  1995 
  1989 	[carry ~~ 0] whileTrue:[
  1996         [carry ~~ 0] whileTrue:[
  1990 	    (index <= len) ifTrue:[
  1997             (index <= len) ifTrue:[
  1991 		carry := (digitByteArray basicAt:index) + carry.
  1998                 carry := (digitByteArray basicAt:index) + carry.
  1992 	    ].
  1999             ].
  1993 	    resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF).
  2000             resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF).
  1994 	    carry := carry bitShift:-8.
  2001             carry := carry bitShift:-8.
  1995 	    index := index + 1
  2002             index := index + 1
  1996 	].
  2003         ].
  1997 
  2004 
  1998 	(index <= rsltLen) ifTrue:[
  2005         (index <= rsltLen) ifTrue:[
  1999 	    [index <= len] whileTrue:[
  2006             [index <= len] whileTrue:[
  2000 		resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
  2007                 resultDigitByteArray basicAt:index put:(digitByteArray basicAt:index).
  2001 		index := index + 1
  2008                 index := index + 1
  2002 	    ].
  2009             ].
  2003 	    lastDigit := 0.
  2010             lastDigit := 0.
  2004 	].
  2011         ].
  2005 
  2012 
  2006 	lastDigit ~~ 0 ifTrue:[
  2013         lastDigit ~~ 0 ifTrue:[
  2007 	    ^ result
  2014             ^ result
  2008 	].
  2015         ].
  2009     ].
  2016     ].
  2010 
  2017 
  2011     ^ result compressed
  2018     ^ result compressed
  2012 
  2019 
  2013     "Modified: 24.3.1997 / 21:32:41 / cg"
  2020     "Modified: 24.3.1997 / 21:32:41 / cg"
  2024      otherDigitByteArray |
  2031      otherDigitByteArray |
  2025 
  2032 
  2026     myLen := digitByteArray size.
  2033     myLen := digitByteArray size.
  2027     otherDigitByteArray := aLargeInteger digits.
  2034     otherDigitByteArray := aLargeInteger digits.
  2028     otherLen := otherDigitByteArray size.
  2035     otherLen := otherDigitByteArray size.
       
  2036 
       
  2037     "/ the highest digit(s) should not be zero
       
  2038     "/ when properly normalized; 
       
  2039     "/ but we are tolerant here, to allow for unnormalized
       
  2040     "/ numbers to be compared ...
  2029 
  2041 
  2030     [myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
  2042     [myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
  2031         myLen := myLen - 1
  2043         myLen := myLen - 1
  2032     ].
  2044     ].
  2033     [otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
  2045     [otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
  2045         ].
  2057         ].
  2046         myLen := myLen - 1
  2058         myLen := myLen - 1
  2047     ].
  2059     ].
  2048     ^ false
  2060     ^ false
  2049 
  2061 
  2050     "Modified: / 5.11.1996 / 18:37:27 / cg"
       
  2051     "Modified: / 3.5.1999 / 08:06:28 / stefan"
  2062     "Modified: / 3.5.1999 / 08:06:28 / stefan"
       
  2063     "Modified: / 8.5.1999 / 18:37:11 / cg"
  2052 !
  2064 !
  2053 
  2065 
  2054 absLessEq:aLargeInteger
  2066 absLessEq:aLargeInteger
  2055     "return true, if abs(self) <= abs(theArgument).
  2067     "return true, if abs(self) <= abs(theArgument).
  2056      This handles unnormalized largeIntegers."
  2068      This handles unnormalized largeIntegers."
  2062      otherDigitByteArray |
  2074      otherDigitByteArray |
  2063 
  2075 
  2064     myLen := digitByteArray size.
  2076     myLen := digitByteArray size.
  2065     otherDigitByteArray := aLargeInteger digits.
  2077     otherDigitByteArray := aLargeInteger digits.
  2066     otherLen := otherDigitByteArray size.
  2078     otherLen := otherDigitByteArray size.
       
  2079 
       
  2080     "/ the highest digit(s) should not be zero
       
  2081     "/ when properly normalized; 
       
  2082     "/ but we are tolerant here, to allow for unnormalized
       
  2083     "/ numbers to be compared ...
  2067 
  2084 
  2068     [(digitByteArray basicAt:myLen) == 0] whileTrue:[
  2085     [(digitByteArray basicAt:myLen) == 0] whileTrue:[
  2069         myLen := myLen - 1
  2086         myLen := myLen - 1
  2070     ].
  2087     ].
  2071     [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
  2088     [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
  2083         ].
  2100         ].
  2084         myLen := myLen - 1
  2101         myLen := myLen - 1
  2085     ].
  2102     ].
  2086     ^ true
  2103     ^ true
  2087 
  2104 
  2088     "Modified: / 5.11.1996 / 18:37:27 / cg"
       
  2089     "Created: / 13.2.1998 / 12:19:45 / stefan"
  2105     "Created: / 13.2.1998 / 12:19:45 / stefan"
  2090     "Modified: / 30.4.1999 / 12:46:31 / stefan"
  2106     "Modified: / 30.4.1999 / 12:46:31 / stefan"
       
  2107     "Modified: / 8.5.1999 / 18:37:15 / cg"
  2091 !
  2108 !
  2092 
  2109 
  2093 absMinus:aLargeInteger
  2110 absMinus:aLargeInteger
  2094     "return a LargeInteger representing abs(self) - abs(theArgument)"
  2111     "return a LargeInteger representing abs(self) - abs(theArgument)"
  2095 
  2112 
  2784 ! !
  2801 ! !
  2785 
  2802 
  2786 !LargeInteger class methodsFor:'documentation'!
  2803 !LargeInteger class methodsFor:'documentation'!
  2787 
  2804 
  2788 version
  2805 version
  2789     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.77 1999-05-06 12:43:58 stefan Exp $'
  2806     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.78 1999-05-08 16:38:51 cg Exp $'
  2790 ! !
  2807 ! !