SmallInteger.st
branchjv
changeset 19054 80cbbad08d0c
parent 18949 41f0cd5dc0ad
parent 19051 29a3a26970e8
child 19064 a091c7289e0e
equal deleted inserted replaced
19042:b81f2c85df7d 19054:80cbbad08d0c
   982     ^ self retry:#bitAnd: coercing:anInteger
   982     ^ self retry:#bitAnd: coercing:anInteger
   983 
   983 
   984     "(2r001010100 bitAnd:2r00001111) radixPrintStringRadix:2"
   984     "(2r001010100 bitAnd:2r00001111) radixPrintStringRadix:2"
   985 !
   985 !
   986 
   986 
   987 bitAt:anIntegerIndex
       
   988     "return the value of the index's bit (index starts at 1) as 0 or 1.
       
   989      Notice: the result of bitAt: on negative receivers is not
       
   990 	     defined in the language standard (since the implementation
       
   991 	     is free to choose any internal representation for integers)"
       
   992 
       
   993 %{  /* NOCONTEXT */
       
   994 #ifdef __SCHTEAM__
       
   995     return context._RETURN( self.bitAt(anIntegerIndex));
       
   996 #else
       
   997     if (__isSmallInteger(anIntegerIndex)) {
       
   998 	INT idx = __smallIntegerVal(anIntegerIndex);
       
   999 	if (idx > 0) {
       
  1000 	    if (idx > N_INT_BITS) {
       
  1001 		RETURN(__mkSmallInteger(0));
       
  1002 	    }
       
  1003 	    RETURN((__smallIntegerVal(self) & (1 << (idx-1))) ? __mkSmallInteger(1) : __mkSmallInteger(0));
       
  1004 	}
       
  1005     }
       
  1006 #endif /* not __SCHTEAM__ */
       
  1007 %}.
       
  1008 
       
  1009     ^ SubscriptOutOfBoundsError
       
  1010 	    raiseRequestWith:anIntegerIndex
       
  1011 	    errorString:'index out of bounds'
       
  1012 
       
  1013     "
       
  1014      16r00000001 bitAt:0
       
  1015      16r00000001 bitAt:1
       
  1016      16r00000001 bitAt:2
       
  1017      16r00008000 bitAt:16
       
  1018      16r00800000 bitAt:24
       
  1019      16r08000000 bitAt:28
       
  1020      16r10000000 bitAt:29
       
  1021      16r20000000 bitAt:30
       
  1022      16r40000000 bitAt:31
       
  1023      16r80000000 bitAt:32
       
  1024      16r100000000 bitAt:33
       
  1025     "
       
  1026 
       
  1027 " Smalltalk implementation:
       
  1028     |mask|
       
  1029 
       
  1030     anIntegerIndex <= 0 ifTrue:[
       
  1031 	^ SubscriptOutOfBoundsSignal
       
  1032 		raiseRequestWith:anIntegerIndex
       
  1033 		errorString:'index out of bounds'
       
  1034     ].
       
  1035     (anIntegerIndex > SmallInteger maxBits) ifTrue:[^ 0].
       
  1036     mask := 1 bitShift:(anIntegerIndex - 1).
       
  1037     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
       
  1038     ^ 1
       
  1039 "
       
  1040 !
       
  1041 
       
  1042 bitClear:anInteger
   987 bitClear:anInteger
  1043     "return the bitwise-and of the receiver and the complement of the argument, anInteger,
   988     "return the bitwise-and of the receiver and the complement of the argument, anInteger,
  1044      returning the receiver with bits of the argument cleared.
   989      returning the receiver with bits of the argument cleared.
  1045      The method's name may be misleading: the receiver is not changed,
   990      The method's name may be misleading: the receiver is not changed,
  1046      but a new number is returned. Should be named #withBitCleared:"
   991      but a new number is returned. Should be named #withBitCleared:"
  1550 #endif /* not __SCHTEAM__ */
  1495 #endif /* not __SCHTEAM__ */
  1551 %}.
  1496 %}.
  1552     ^ self retry:#bitXor: coercing:anInteger
  1497     ^ self retry:#bitXor: coercing:anInteger
  1553 !
  1498 !
  1554 
  1499 
  1555 clearBit:anInteger
       
  1556     "return a new integer where the specified bit is off.
       
  1557      Bits are counted from 1 starting with the least significant.
       
  1558      The method's name may be misleading: the receiver is not changed,
       
  1559      but a new number is returned. Should be named #withBitCleared:"
       
  1560 
       
  1561 %{  /* NOCONTEXT */
       
  1562 #ifndef __SCHTEAM__
       
  1563     if (__isSmallInteger(anInteger)) {
       
  1564 	int index = __intVal(anInteger);
       
  1565 
       
  1566 	if (index > 0) {
       
  1567 # if __POINTER_SIZE__ == 8
       
  1568 	    if (index <= 62)
       
  1569 # else
       
  1570 	    if (index <= 30)
       
  1571 # endif
       
  1572 	    {
       
  1573 		INT mask = __MASKSMALLINT(1 << (index-1));
       
  1574 
       
  1575 		RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
       
  1576 	    }
       
  1577 	    RETURN (self);  /* nothing to do ... */
       
  1578 	}
       
  1579     }
       
  1580 #endif /* not __SCHTEAM__ */
       
  1581 %}.
       
  1582     ^ super clearBit:anInteger
       
  1583 
       
  1584     "
       
  1585      (16r401 clearBit:1     ) hexPrintString
       
  1586      (16r401 clearBit:0     ) hexPrintString
       
  1587      (16r3fffffff clearBit:1) hexPrintString
       
  1588      (16r3fffffff clearBit:29) hexPrintString
       
  1589      (16r3fffffff clearBit:30) hexPrintString
       
  1590      (16r3fffffff clearBit:31) hexPrintString
       
  1591      (16r3fffffff bitAt:29) hexPrintString
       
  1592      (16r3fffffff bitAt:30) hexPrintString
       
  1593      (16r3fffffff bitAt:31) hexPrintString
       
  1594      (16r40000001 clearBit:1) hexPrintString
       
  1595      (16rF0000001 clearBit:29) hexPrintString
       
  1596      (16rF0000001 clearBit:30) hexPrintString
       
  1597      (16rF0000001 clearBit:31) hexPrintString
       
  1598      (16rF0000001 clearBit:32) hexPrintString
       
  1599     "
       
  1600 !
       
  1601 
       
  1602 highBit
  1500 highBit
  1603     "return the bitIndex of the highest bit set. The returned bitIndex
  1501     "return the bitIndex of the highest bit set. The returned bitIndex
  1604      starts at 1 for the least significant bit.
  1502      starts at 1 for the least significant bit.
  1605      Returns 0 if no bit is set."
  1503      Returns 0 if no bit is set."
  1606 
  1504 
  1729      2r000100 highBit
  1627      2r000100 highBit
  1730      2r010100 highBit
  1628      2r010100 highBit
  1731      2r000001 highBit
  1629      2r000001 highBit
  1732      0 highBit
  1630      0 highBit
  1733      SmallInteger maxVal highBit
  1631      SmallInteger maxVal highBit
  1734     "
       
  1735 !
       
  1736 
       
  1737 invertBit:anInteger
       
  1738     "return a new number where the specified bit is inverted.
       
  1739      Bits are counted from 1 starting with the least significant.
       
  1740      The method's name may be misleading: the receiver is not changed,
       
  1741      but a new number is returned. Should be named #withBitInverted:"
       
  1742 
       
  1743 %{  /* NOCONTEXT */
       
  1744 #ifndef __SCHTEAM__
       
  1745     if (__isSmallInteger(anInteger)) {
       
  1746 	int index = __intVal(anInteger);
       
  1747 
       
  1748 	if (index > 0) {
       
  1749 # if __POINTER_SIZE__ == 8
       
  1750 	    if (index <= 62)
       
  1751 # else
       
  1752 	    if (index <= 30)
       
  1753 # endif
       
  1754 	    {
       
  1755 		INT mask = __MASKSMALLINT(1 << (index-1));
       
  1756 
       
  1757 		RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
       
  1758 	    }
       
  1759 	}
       
  1760     }
       
  1761 #endif /* not __SCHTEAM__ */
       
  1762 %}.
       
  1763     ^ super invertBit:anInteger
       
  1764 
       
  1765     "
       
  1766      (16r401 invertBit:2     ) hexPrintString
       
  1767      (16r401 invertBit:1     ) hexPrintString
       
  1768      (16r30000000 invertBit:1) hexPrintString
       
  1769      (16r40000000 invertBit:0) hexPrintString
       
  1770      (16r0 invertBit:29) hexPrintString
       
  1771      (16r0 invertBit:30) hexPrintString
       
  1772      (16r0 invertBit:31) hexPrintString
       
  1773      (16r0 invertBit:32) hexPrintString
       
  1774      (16r0 invertBit:33) hexPrintString
       
  1775      (16r0 invertBit:100) hexPrintString
       
  1776     "
  1632     "
  1777 !
  1633 !
  1778 
  1634 
  1779 lowBit
  1635 lowBit
  1780     "return the bitIndex of the lowest bit set. The returned bitIndex
  1636     "return the bitIndex of the lowest bit set. The returned bitIndex
  1979 
  1835 
  1980     "
  1836     "
  1981 	16 rightShift:2
  1837 	16 rightShift:2
  1982 	 4 rightShift:-2
  1838 	 4 rightShift:-2
  1983     "
  1839     "
       
  1840 ! !
       
  1841 
       
  1842 !SmallInteger methodsFor:'bit operators - indexed'!
       
  1843 
       
  1844 bitAt:anIntegerIndex
       
  1845     "return the value of the index's bit (index starts at 1) as 0 or 1.
       
  1846      Notice: the result of bitAt: on negative receivers is not
       
  1847              defined in the language standard (since the implementation
       
  1848              is free to choose any internal representation for integers)"
       
  1849 
       
  1850 %{  /* NOCONTEXT */
       
  1851 #ifdef __SCHTEAM__
       
  1852     return context._RETURN( self.bitAt(anIntegerIndex));
       
  1853 #else
       
  1854     if (__isSmallInteger(anIntegerIndex)) {
       
  1855         INT idx = __smallIntegerVal(anIntegerIndex);
       
  1856         if (idx > 0) {
       
  1857             if (idx > N_INT_BITS) {
       
  1858                 RETURN(__mkSmallInteger(0));
       
  1859             }
       
  1860             RETURN((__smallIntegerVal(self) & ((INT)1 << (idx-1))) ? __mkSmallInteger(1) : __mkSmallInteger(0));
       
  1861         }
       
  1862     }
       
  1863 #endif /* not __SCHTEAM__ */
       
  1864 %}.
       
  1865 
       
  1866     ^ SubscriptOutOfBoundsError
       
  1867             raiseRequestWith:anIntegerIndex
       
  1868             errorString:'index out of bounds'
       
  1869 
       
  1870     "
       
  1871      16r000000001 bitAt:0 -> error
       
  1872      16r000000001 bitAt:1
       
  1873      16r000000001 bitAt:2
       
  1874      16r000008000 bitAt:16
       
  1875      16r000800000 bitAt:24
       
  1876      16r008000000 bitAt:28
       
  1877      16r010000000 bitAt:29
       
  1878      16r020000000 bitAt:30
       
  1879      16r040000000 bitAt:31
       
  1880      16r080000000 bitAt:32
       
  1881      16r100000000 bitAt:33
       
  1882     "
       
  1883 
       
  1884 " Smalltalk implementation:
       
  1885     |mask|
       
  1886 
       
  1887     anIntegerIndex <= 0 ifTrue:[
       
  1888         ^ SubscriptOutOfBoundsSignal
       
  1889                 raiseRequestWith:anIntegerIndex
       
  1890                 errorString:'index out of bounds'
       
  1891     ].
       
  1892     (anIntegerIndex > SmallInteger maxBits) ifTrue:[^ 0].
       
  1893     mask := 1 bitShift:(anIntegerIndex - 1).
       
  1894     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
       
  1895     ^ 1
       
  1896 "
       
  1897 !
       
  1898 
       
  1899 clearBit:anInteger
       
  1900     "return a new integer where the specified bit is off.
       
  1901      Bits are counted from 1 starting with the least significant.
       
  1902      The method's name may be misleading: the receiver is not changed,
       
  1903      but a new number is returned. Should be named #withBitCleared:"
       
  1904 
       
  1905 %{  /* NOCONTEXT */
       
  1906 #ifndef __SCHTEAM__
       
  1907     if (__isSmallInteger(anInteger)) {
       
  1908         int index = __intVal(anInteger);
       
  1909 
       
  1910         if (index > 0) {
       
  1911 # if __POINTER_SIZE__ == 8
       
  1912             if (index <= 62)
       
  1913 # else
       
  1914             if (index <= 30)
       
  1915 # endif
       
  1916             {
       
  1917                 INT mask = __MASKSMALLINT( ((INT)1 << (index-1)));
       
  1918 
       
  1919                 RETURN ( ((OBJ) ((INT)self & ~(INT)mask)) );
       
  1920             }
       
  1921             RETURN (self);  /* nothing to do ... */
       
  1922         }
       
  1923     }
       
  1924 #endif /* not __SCHTEAM__ */
       
  1925 %}.
       
  1926     ^ super clearBit:anInteger
       
  1927 
       
  1928     "
       
  1929      (16r401 clearBit:1     ) hexPrintString
       
  1930      (16r401 clearBit:0     ) hexPrintString
       
  1931      (16r3fffffff clearBit:1) hexPrintString
       
  1932      (16r3fffffff clearBit:29) hexPrintString
       
  1933      (16r3fffffff clearBit:30) hexPrintString
       
  1934      (16r3fffffff clearBit:31) hexPrintString
       
  1935      (16r3fffffff bitAt:29) hexPrintString
       
  1936      (16r3fffffff bitAt:30) hexPrintString
       
  1937      (16r3fffffff bitAt:31) hexPrintString
       
  1938      (16r40000001 clearBit:1) hexPrintString
       
  1939      (16rF0000001 clearBit:29) hexPrintString
       
  1940      (16rF0000001 clearBit:30) hexPrintString
       
  1941      (16rF0000001 clearBit:31) hexPrintString
       
  1942      (16rF0000001 clearBit:32) hexPrintString
       
  1943      (16r1F0000001 clearBit:33) hexPrintString
       
  1944     "
       
  1945 !
       
  1946 
       
  1947 invertBit:anInteger
       
  1948     "return a new number where the specified bit is inverted.
       
  1949      Bits are counted from 1 starting with the least significant.
       
  1950      The method's name may be misleading: the receiver is not changed,
       
  1951      but a new number is returned. Should be named #withBitInverted:"
       
  1952 
       
  1953 %{  /* NOCONTEXT */
       
  1954 #ifndef __SCHTEAM__
       
  1955     if (__isSmallInteger(anInteger)) {
       
  1956         int index = __intVal(anInteger);
       
  1957 
       
  1958         if (index > 0) {
       
  1959 # if __POINTER_SIZE__ == 8
       
  1960             if (index <= 62)
       
  1961 # else
       
  1962             if (index <= 30)
       
  1963 # endif
       
  1964             {
       
  1965                 INT mask = __MASKSMALLINT((INT)1 << (index-1));
       
  1966 
       
  1967                 RETURN ( ((OBJ) ((INT)self ^ (INT)mask)) );
       
  1968             }
       
  1969         }
       
  1970     }
       
  1971 #endif /* not __SCHTEAM__ */
       
  1972 %}.
       
  1973     ^ super invertBit:anInteger
       
  1974 
       
  1975     "
       
  1976      (16r401 invertBit:2     ) hexPrintString
       
  1977      (16r401 invertBit:1     ) hexPrintString
       
  1978      (16r30000000 invertBit:1) hexPrintString
       
  1979      (16r40000000 invertBit:0) hexPrintString
       
  1980      (16r0 invertBit:29) hexPrintString
       
  1981      (16r0 invertBit:30) hexPrintString
       
  1982      (16r0 invertBit:31) hexPrintString
       
  1983      (16r0 invertBit:32) hexPrintString
       
  1984      (16r0 invertBit:33) hexPrintString
       
  1985      (16r0 invertBit:100) hexPrintString
       
  1986     "
  1984 !
  1987 !
  1985 
  1988 
  1986 setBit:anInteger
  1989 setBit:anInteger
  1987     "return a new integer where the specified bit is on.
  1990     "return a new integer where the specified bit is on.
  1988      Bits are counted from 1 starting with the least significant.
  1991      Bits are counted from 1 starting with the least significant.
  1990      but a new number is returned. Should be named #withBitSet:"
  1993      but a new number is returned. Should be named #withBitSet:"
  1991 
  1994 
  1992 %{  /* NOCONTEXT */
  1995 %{  /* NOCONTEXT */
  1993 #ifndef __SCHTEAM__
  1996 #ifndef __SCHTEAM__
  1994     if (__isSmallInteger(anInteger)) {
  1997     if (__isSmallInteger(anInteger)) {
  1995 	int index = __intVal(anInteger);
  1998         int index = __intVal(anInteger);
  1996 
  1999 
  1997 	if (index > 0) {
  2000         if (index > 0) {
  1998 # if __POINTER_SIZE__ == 8
  2001 # if __POINTER_SIZE__ == 8
  1999 	    if (index <= 62)
  2002             if (index <= 62)
  2000 # else
  2003 # else
  2001 	    if (index <= 30)
  2004             if (index <= 30)
  2002 # endif
  2005 # endif
  2003 	    {
  2006             {
  2004 		INT mask = __MASKSMALLINT(1 << (index-1));
  2007                 INT mask = __MASKSMALLINT((INT)1 << (index-1));
  2005 
  2008 
  2006 		RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
  2009                 RETURN ( ((OBJ) ((INT)self | (INT)mask)) );
  2007 	    }
  2010             }
  2008 	}
  2011         }
  2009     }
  2012     }
  2010 #endif /* not __SCHTEAM__ */
  2013 #endif /* not __SCHTEAM__ */
  2011 %}.
  2014 %}.
  2012     ^ super setBit:anInteger
  2015     ^ super setBit:anInteger
  2013 
  2016