LargeInteger.st
changeset 11605 adff1007beb2
parent 11604 64df3632e526
child 11723 40267c26c7eb
equal deleted inserted replaced
11604:64df3632e526 11605:adff1007beb2
   869 
   869 
   870 bitAnd:anInteger
   870 bitAnd:anInteger
   871     "return the bitwise-and of the receiver and the argument, anInteger"
   871     "return the bitwise-and of the receiver and the argument, anInteger"
   872 
   872 
   873 %{  /* NOCONTEXT */
   873 %{  /* NOCONTEXT */
   874 
       
   875     if (__isSmallInteger(anInteger)) {
   874     if (__isSmallInteger(anInteger)) {
   876 	INT v2 = __intVal(anInteger);
   875         INT v2 = __intVal(anInteger);
   877 	INT v1;
   876         INT v1;
   878 #if defined(__LSBFIRST__)
   877 #if defined(__LSBFIRST__)
   879 	v1 = *(INT *)(__stringVal(__INST(digitByteArray)));
   878         v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray)));
   880 #else
   879 #else
   881 	unsigned char *digits = (unsigned char *)(__stringVal(__INST(digitByteArray)));
   880         unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
   882 
   881 
   883 	v1 = digits[0] & 0xFF;
   882         v1 = digits[0] & 0xFF;
   884 	v1 = v1 | ((digits[1] & 0xFF)<<8);
   883         v1 = v1 | ((digits[1] & 0xFF)<<8);
   885 	v1 = v1 | ((digits[2] & 0xFF)<<16);
   884         v1 = v1 | ((digits[2] & 0xFF)<<16);
   886 	v1 = v1 | ((digits[3] & 0xFF)<<24);
   885         v1 = v1 | ((digits[3] & 0xFF)<<24);
   887 	if (sizeof(unsigned INT) == 8) {
   886 # if (__POINTER_SIZE__ == 8)
   888 	    v1 = v1 | ((digits[4] & 0xFF)<<32);
   887         v1 = v1 | ((digits[4] & 0xFF)<<32);
   889 	    v1 = v1 | ((digits[5] & 0xFF)<<40);
   888         v1 = v1 | ((digits[5] & 0xFF)<<40);
   890 	    v1 = v1 | ((digits[6] & 0xFF)<<48);
   889         v1 = v1 | ((digits[6] & 0xFF)<<48);
   891 	    v1 = v1 | ((digits[7] & 0xFF)<<56);
   890         v1 = v1 | ((digits[7] & 0xFF)<<56);
   892 	}
   891  #endif
   893 #endif
   892 #endif
   894 
   893         RETURN ( __mkSmallInteger(v1 & v2) );
   895 	RETURN ( __mkSmallInteger(v1 & v2) );
       
   896     }
   894     }
   897 %}.
   895 %}.
   898     ^ super bitAnd:anInteger
   896     ^ super bitAnd:anInteger
   899 
   897 
   900     "
   898     "
   916      Notice: the result of bitAt: on negative receivers is not
   914      Notice: the result of bitAt: on negative receivers is not
   917              defined in the language standard (since the implementation
   915              defined in the language standard (since the implementation
   918              is free to choose any internal representation for integers)"
   916              is free to choose any internal representation for integers)"
   919 
   917 
   920 %{  /* NOCONTEXT */
   918 %{  /* NOCONTEXT */
   921 
       
   922     if (__isSmallInteger(anIntegerIndex)) {
   919     if (__isSmallInteger(anIntegerIndex)) {
   923         INT idx = __smallIntegerVal(anIntegerIndex) - 1;
   920         INT idx = __smallIntegerVal(anIntegerIndex) - 1;
       
   921 
   924         if (idx >= 0) {
   922         if (idx >= 0) {
   925             int v1;
   923             int v1;
   926             int byteOffset = idx / 8;
   924             int byteOffset = idx / 8;
   927             int digitLen   = __stringSize(__INST(digitByteArray));
   925             int digitLen   = __stringSize(__INST(digitByteArray));
   928 
   926 
   929             if (digitLen < byteOffset) {
   927             if (digitLen < byteOffset) {
   930                 RETURN(__mkSmallInteger(0));
   928                 RETURN(__mkSmallInteger(0));
   931             }
   929             }
   932 
   930 
   933             v1 = ((unsigned char *)(__stringVal(__INST(digitByteArray))))[byteOffset];
   931             v1 = (__byteArrayVal(__INST(digitByteArray)))[byteOffset];
   934             if (v1 & (1 << (idx % 8))) {
   932             if (v1 & (1 << (idx % 8))) {
   935                 RETURN(__mkSmallInteger(1));
   933                 RETURN(__mkSmallInteger(1));
   936             } else {
   934             } else {
   937                 RETURN(__mkSmallInteger(0));
   935                 RETURN(__mkSmallInteger(0));
   938             }
   936             }
   940     }
   938     }
   941 %}.
   939 %}.
   942     ^ super bitAt:anIntegerIndex
   940     ^ super bitAt:anIntegerIndex
   943 
   941 
   944     "
   942     "
   945      16rFFFFFFFFFF01 bitAt:0
   943      TestCase should:[ 16rFFFFFFFFFF01 bitAt:0 ] raise:Error
   946      16rFFFFFFFFFF01 bitAt:49
   944      TestCase assert:( 16rFFFFFFFFFF01 bitAt:49 ) == 0
   947      16rFFFFFFFFFF01 bitAt:1
   945      TestCase assert:( 16rFFFFFFFFFF01 bitAt:1  ) == 1
   948      16rFFFFFFFFFF01 bitAt:2
   946      TestCase assert:( 16rFFFFFFFFFF01 bitAt:2  ) == 0
   949      16rFFFFFFFFFF02 bitAt:2
   947      TestCase assert:( 16rFFFFFFFFFF02 bitAt:2  ) == 1
   950      16rFFFFFFFF01FF bitAt:8
   948      TestCase assert:( 16rFFFFFFFF01FF bitAt:8  ) == 1
   951      16rFFFFFFFF01FF bitAt:9
   949      TestCase assert:( 16rFFFFFFFF01FF bitAt:9  ) == 1
   952      16rFFFFFFFF01FF bitAt:10
   950      TestCase assert:( 16rFFFFFFFF01FF bitAt:10 ) == 0
   953     "
   951     "
   954 !
   952 !
   955 
   953 
   956 bitXor:anInteger
   954 bitXor:anInteger
   957     "return the bitwise-or of the receiver and the argument, anInteger.
   955     "return the bitwise-or of the receiver and the argument, anInteger.
  1010 %{
  1008 %{
  1011     /*
  1009     /*
  1012      * quickly advance over full 0-words
  1010      * quickly advance over full 0-words
  1013      */
  1011      */
  1014     if (__isByteArray(__INST(digitByteArray))) {
  1012     if (__isByteArray(__INST(digitByteArray))) {
  1015 	int __sz = __intVal(sz);
  1013         int __sz = __intVal(sz);
  1016 	unsigned char *__bP = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
  1014         unsigned char *__bP = __byteArrayVal(__INST(digitByteArray));
  1017 	unsigned char *__bP0 = __bP;
  1015         unsigned char *__bP0 = __bP;
  1018 
  1016 
  1019 #ifdef __UNROLL_LOOPS__
  1017 #ifdef __UNROLL_LOOPS__
  1020 	while (__sz > (sizeof(INT) * 4)) {
  1018         while (__sz > (sizeof(INT) * 4)) {
  1021 	    if ( ((INT *)__bP)[0] != 0 ) break;
  1019             if ( ((INT *)__bP)[0] != 0 ) break;
  1022 	    if ( ((INT *)__bP)[1] != 0 ) {
  1020             if ( ((INT *)__bP)[1] != 0 ) {
  1023 		__sz -= sizeof(INT);
  1021                 __sz -= sizeof(INT);
  1024 		__bP += sizeof(INT);
  1022                 __bP += sizeof(INT);
  1025 		break;
  1023                 break;
  1026 	    }
  1024             }
  1027 	    if ( ((INT *)__bP)[2] != 0 ) {
  1025             if ( ((INT *)__bP)[2] != 0 ) {
  1028 		__sz -= sizeof(INT) * 2;
  1026                 __sz -= sizeof(INT) * 2;
  1029 		__bP += sizeof(INT) * 2;
  1027                 __bP += sizeof(INT) * 2;
  1030 		break;
  1028                 break;
  1031 	    }
  1029             }
  1032 	    if ( ((INT *)__bP)[3] != 0 ) {
  1030             if ( ((INT *)__bP)[3] != 0 ) {
  1033 		__sz -= sizeof(INT) * 3;
  1031                 __sz -= sizeof(INT) * 3;
  1034 		__bP += sizeof(INT) * 3;
  1032                 __bP += sizeof(INT) * 3;
  1035 		break;
  1033                 break;
  1036 	    }
  1034             }
  1037 	    __sz -= sizeof(INT) * 4;
  1035             __sz -= sizeof(INT) * 4;
  1038 	    __bP += sizeof(INT) * 4;
  1036             __bP += sizeof(INT) * 4;
  1039 	}
  1037         }
  1040 #endif
  1038 #endif
  1041 	while (__sz > sizeof(INT)) {
  1039         while (__sz > sizeof(INT)) {
  1042 	    if ( ((INT *)__bP)[0] != 0 ) break;
  1040             if ( ((INT *)__bP)[0] != 0 ) break;
  1043 	    __sz -= sizeof(INT);
  1041             __sz -= sizeof(INT);
  1044 	    __bP += sizeof(INT);
  1042             __bP += sizeof(INT);
  1045 	}
  1043         }
  1046 	while (__sz > 0) {
  1044         while (__sz > 0) {
  1047 	    unsigned int c;
  1045             unsigned int c;
  1048 
  1046 
  1049 	    if ( (c = *__bP) != 0 ) {
  1047             if ( (c = *__bP) != 0 ) {
  1050 		int bitIdx = (__bP - __bP0) * 8;
  1048                 int bitIdx = (__bP - __bP0) * 8;
  1051 #ifdef __BSF
  1049 #ifdef __BSF
  1052 		{
  1050                 {
  1053 		    int index;
  1051                     int index;
  1054 		    int t = c;
  1052                     int t = c;
  1055 
  1053 
  1056 		    index = __BSF(t);
  1054                     index = __BSF(t);
  1057 		    RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
  1055                     RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
  1058 		}
  1056                 }
  1059 #else
  1057 #else
  1060 		if (c & 0x0F) {
  1058                 if (c & 0x0F) {
  1061 		    if (c & 0x03) {
  1059                     if (c & 0x03) {
  1062 			if (c & 0x01) {
  1060                         if (c & 0x01) {
  1063 			    RETURN ( __mkSmallInteger( bitIdx + 1) );
  1061                             RETURN ( __mkSmallInteger( bitIdx + 1) );
  1064 			} else {
  1062                         } else {
  1065 			    RETURN ( __mkSmallInteger( bitIdx + 2) );
  1063                             RETURN ( __mkSmallInteger( bitIdx + 2) );
  1066 			}
  1064                         }
  1067 		    } else {
  1065                     } else {
  1068 			if (c & 0x04) {
  1066                         if (c & 0x04) {
  1069 			    RETURN ( __mkSmallInteger( bitIdx + 3) );
  1067                             RETURN ( __mkSmallInteger( bitIdx + 3) );
  1070 			} else {
  1068                         } else {
  1071 			    RETURN ( __mkSmallInteger( bitIdx + 4) );
  1069                             RETURN ( __mkSmallInteger( bitIdx + 4) );
  1072 			}
  1070                         }
  1073 		    }
  1071                     }
  1074 		} else {
  1072                 } else {
  1075 		    if (c & 0x30) {
  1073                     if (c & 0x30) {
  1076 			if (c & 0x10) {
  1074                         if (c & 0x10) {
  1077 			    RETURN ( __mkSmallInteger( bitIdx + 5) );
  1075                             RETURN ( __mkSmallInteger( bitIdx + 5) );
  1078 			} else {
  1076                         } else {
  1079 			    RETURN ( __mkSmallInteger( bitIdx + 6) );
  1077                             RETURN ( __mkSmallInteger( bitIdx + 6) );
  1080 			}
  1078                         }
  1081 		    } else {
  1079                     } else {
  1082 			if (c & 0x40) {
  1080                         if (c & 0x40) {
  1083 			    RETURN ( __mkSmallInteger( bitIdx + 7) );
  1081                             RETURN ( __mkSmallInteger( bitIdx + 7) );
  1084 			} else {
  1082                         } else {
  1085 			    RETURN ( __mkSmallInteger( bitIdx + 8) );
  1083                             RETURN ( __mkSmallInteger( bitIdx + 8) );
  1086 			}
  1084                         }
  1087 		    }
  1085                     }
  1088 		}
  1086                 }
  1089 #endif
  1087 #endif
  1090 		break;
  1088                 break;
  1091 	    }
  1089             }
  1092 	    __sz--;
  1090             __sz--;
  1093 	    __bP++;
  1091             __bP++;
  1094 	}
  1092         }
  1095 	idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
  1093         idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
  1096     }
  1094     }
  1097 %}.
  1095 %}.
  1098     "/ never actually reached
  1096     "/ never actually reached
  1099     idx0 to:sz do:[:digitIndex |
  1097     idx0 to:sz do:[:digitIndex |
  1100 	(byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
  1098         (byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
  1101 	    ^ (digitIndex-1)*8 + (byte lowBit)
  1099             ^ (digitIndex-1)*8 + (byte lowBit)
  1102 	]
  1100         ]
  1103     ].
  1101     ].
  1104     ^ 0 "/ should not happen
  1102     ^ 0 "/ should not happen
  1105 
  1103 
  1106     "
  1104     "
  1107      (1 bitShift:0) lowBit
  1105      (1 bitShift:0) lowBit     
  1108      (1 bitShift:10) lowBit
  1106      (1 bitShift:10) lowBit
  1109      (1 bitShift:20) lowBit
  1107      (1 bitShift:20) lowBit
  1110      (1 bitShift:30) lowBit
  1108      (1 bitShift:30) lowBit
  1111      (1 bitShift:30) highBit
  1109      (1 bitShift:30) highBit
  1112      (1 bitShift:31) lowBit
  1110      (1 bitShift:31) lowBit
  1114      (1 bitShift:32) lowBit
  1112      (1 bitShift:32) lowBit
  1115      (1 bitShift:32) highBit
  1113      (1 bitShift:32) highBit
  1116      (1 bitShift:33) lowBit
  1114      (1 bitShift:33) lowBit
  1117      (1 bitShift:33) highBit
  1115      (1 bitShift:33) highBit
  1118      (1 bitShift:64) lowBit
  1116      (1 bitShift:64) lowBit
  1119      (1 bitShift:64) highBit
  1117      (1 bitShift:64) highBit  
  1120      (1 bitShift:1000) lowBit
  1118      (1 bitShift:1000) lowBit
  1121      (1 bitShift:1000) highBit
  1119      (1 bitShift:1000) highBit
  1122      ((1 bitShift:64)-1) lowBit
  1120      ((1 bitShift:64)-1) lowBit
  1123      ((1 bitShift:64)-1) highBit
  1121      ((1 bitShift:64)-1) highBit
  1124 
  1122 
  1125      1 to:1000 do:[:idx |
  1123      1 to:1000 do:[:idx |
  1126 	self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
  1124         self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
  1127 	self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
  1125         self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
  1128 	self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
  1126         self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
  1129 	self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
  1127         self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
  1130 	self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
  1128         self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
  1131 	self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
  1129         self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
  1132 	self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
  1130         self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
  1133 	self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
  1131         self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
  1134 	self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
  1132         self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
  1135      ]
  1133      ]
  1136 
  1134 
  1137      |num|
  1135      |num|
  1138 
  1136 
  1139      num := (1 bitShift:1000).
  1137      num := (1 bitShift:1000).
  1140      Time millisecondsToRun:[
  1138      Time millisecondsToRun:[
  1141 	100000 timesRepeat:[
  1139         100000 timesRepeat:[
  1142 	    num lowBit
  1140             num lowBit
  1143 	]
  1141         ]
  1144      ]
  1142      ]
  1145     "
  1143     "
  1146 
  1144 
  1147     "Modified: 14.8.1997 / 11:55:34 / cg"
  1145     "Modified: 14.8.1997 / 11:55:34 / cg"
  1148 !
  1146 !
  4822 ! !
  4820 ! !
  4823 
  4821 
  4824 !LargeInteger class methodsFor:'documentation'!
  4822 !LargeInteger class methodsFor:'documentation'!
  4825 
  4823 
  4826 version
  4824 version
  4827     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.191 2009-02-28 11:20:37 cg Exp $'
  4825     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.192 2009-02-28 11:36:19 cg Exp $'
  4828 ! !
  4826 ! !