LargeInteger.st
changeset 15312 2c69166c1fb2
parent 15276 a25ed9d7c50a
child 15326 7cc303092044
equal deleted inserted replaced
15311:6cd342b231f2 15312:2c69166c1fb2
   287 
   287 
   288     "LargeInteger value:3689"
   288     "LargeInteger value:3689"
   289 
   289 
   290     "Modified: / 8.5.1998 / 21:40:41 / cg"
   290     "Modified: / 8.5.1998 / 21:40:41 / cg"
   291 ! !
   291 ! !
   292 
       
   293 
       
   294 
   292 
   295 !LargeInteger class methodsFor:'queries'!
   293 !LargeInteger class methodsFor:'queries'!
   296 
   294 
   297 isBuiltInClass
   295 isBuiltInClass
   298     "return true if this class is known by the run-time-system.
   296     "return true if this class is known by the run-time-system.
  3930 %{
  3928 %{
  3931     if (__isByteArray(__INST(digitByteArray))
  3929     if (__isByteArray(__INST(digitByteArray))
  3932      && __isByteArray(otherDigitByteArray)
  3930      && __isByteArray(otherDigitByteArray)
  3933      && __isByteArray(resultDigitByteArray)
  3931      && __isByteArray(resultDigitByteArray)
  3934      && __bothSmallInteger(len1, len2)) {
  3932      && __bothSmallInteger(len1, len2)) {
  3935         unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  3933 	unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  3936         unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  3934 	unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  3937         unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3935 	unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3938         unsigned char *_p1, *_p2, *_pResult, *_pResult0, *_pResult1, *_p1Last, *_p2Last;
  3936 	unsigned char *_p1, *_p2, *_pResult, *_pResult0, *_pResult1, *_p1Last, *_p2Last;
  3939         unsigned char *_pResultLast1;
  3937 	unsigned char *_pResultLast1;
  3940         unsigned INT _v;
  3938 	unsigned INT _v;
  3941         int _len1 = __intVal(len1);
  3939 	int _len1 = __intVal(len1);
  3942         int _len2 = __intVal(len2);
  3940 	int _len2 = __intVal(len2);
  3943 
  3941 
  3944         _p1Last = myBytes    + _len1 - 1;  /* the last byte */
  3942 	_p1Last = myBytes    + _len1 - 1;  /* the last byte */
  3945         _p2Last = otherBytes + _len2 - 1;  /* the last byte */
  3943 	_p2Last = otherBytes + _len2 - 1;  /* the last byte */
  3946         _pResult0 = resultBytes;
  3944 	_pResult0 = resultBytes;
  3947 
  3945 
  3948         /*
  3946 	/*
  3949          *        aaa...aaa      f1[0] * f2
  3947 	 *        aaa...aaa      f1[0] * f2
  3950          *       bbb...bbb       f1[1] * f2
  3948 	 *       bbb...bbb       f1[1] * f2
  3951          *      ccc...ccc        f1[2] * f2
  3949 	 *      ccc...ccc        f1[2] * f2
  3952          *     ...
  3950 	 *     ...
  3953          *    xxx...xxx          f1[high] * f2
  3951 	 *    xxx...xxx          f1[high] * f2
  3954          *
  3952 	 *
  3955          * start short-wise
  3953 	 * start short-wise
  3956          * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
  3954 	 * bounds: (16rFFFF * 16rFFFF) + 16rFFFF -> FFFF0000
  3957          */
  3955 	 */
  3958         _p1 = myBytes;
  3956 	_p1 = myBytes;
  3959 
  3957 
  3960 #if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
  3958 #if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
  3961         /* loop over ints of f1 */
  3959 	/* loop over ints of f1 */
  3962         for (; _p1 < _p1Last-3; _p1 += 4, _pResult0 += 4) {
  3960 	for (; _p1 < _p1Last-2; _p1 += 4, _pResult0 += 4) {
  3963             unsigned INT word1 = ((unsigned int *)_p1)[0];
  3961 	    unsigned INT word1 = ((unsigned int *)_p1)[0];
  3964 
  3962 
  3965             _pResult = _pResult0;
  3963 	    _pResult = _pResult0;
  3966             _p2 = otherBytes;
  3964 	    _p2 = otherBytes;
  3967 
  3965 
  3968             /* loop over ints of f2 */
  3966 	    /* loop over ints of f2 */
  3969             while (_p2 < (_p2Last-3)) {
  3967 	    while (_p2 < (_p2Last-2)) {
  3970                 _v = (word1 * ((unsigned int *)_p2)[0]) + ((unsigned int *)_pResult)[0];
  3968 		_v = (word1 * ((unsigned int *)_p2)[0]) + ((unsigned int *)_pResult)[0];
  3971                 ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
  3969 		((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
  3972                 _v >>= 32; /* now _v contains the carry*/
  3970 		_v >>= 32; /* now _v contains the carry*/
  3973                 _pResult += 4;
  3971 		_pResult += 4;
  3974                 if (_v) {
  3972 		if (_v) {
  3975                     unsigned char *_pResultLast3;
  3973 		    unsigned char *_pResultLast3;
  3976 
  3974 
  3977                     /* distribute carry - int-wise, then byte-wise */
  3975 		    /* distribute carry - int-wise, then byte-wise */
  3978                     _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
  3976 		    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
  3979                     for (_pResult1 = _pResult; _v; _pResult1 += 4) {
  3977 		    for (_pResult1 = _pResult; _v; _pResult1 += 4) {
  3980                         if (_pResult1 > _pResultLast3) break;
  3978 			if (_pResult1 > _pResultLast3) break;
  3981                         _v += ((unsigned int *)_pResult1)[0];
  3979 			_v += ((unsigned int *)_pResult1)[0];
  3982                         ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
  3980 			((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
  3983                         _v >>= 32;
  3981 			_v >>= 32;
  3984                     }
  3982 		    }
  3985                     for (; _v; _pResult1++) {
  3983 		    for (; _v; _pResult1++) {
  3986                         _v += _pResult1[0];
  3984 			_v += _pResult1[0];
  3987                         _pResult1[0] = _v /* & 0xFF */;
  3985 			_pResult1[0] = _v /* & 0xFF */;
  3988                         _v >>= 8;
  3986 			_v >>= 8;
  3989                     }
  3987 		    }
  3990                 }
  3988 		}
  3991                 _p2 += 4;
  3989 		_p2 += 4;
  3992             }
  3990 	    }
  3993 
  3991 
  3994             /* possible odd highByte of f2 */
  3992 	    /* possible odd highByte of f2 */
  3995             while (_p2 <= _p2Last) {
  3993 	    while (_p2 <= _p2Last) {
  3996                 _v = (word1 * _p2[0]) + ((unsigned int *)_pResult)[0];
  3994 		_v = (word1 * _p2[0]) + ((unsigned int *)_pResult)[0];
  3997                 ((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
  3995 		((unsigned int *)_pResult)[0] = _v /* & 0xFFFFFFFF */;
  3998                 _v >>= 32; /* now _v contains the carry*/
  3996 		_v >>= 32; /* now _v contains the carry*/
  3999                 _pResult += 4;
  3997 		_pResult += 4;
  4000                 if (_v) {
  3998 		if (_v) {
  4001                     unsigned char *_pResultLast3;
  3999 		    unsigned char *_pResultLast3;
  4002 
  4000 
  4003                     /* distribute carry - int-wise, then byte-wise */
  4001 		    /* distribute carry - int-wise, then byte-wise */
  4004                     _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
  4002 		    _pResultLast3 = _pResult0 + _len1 + _len2 - 1 - 3;
  4005                     for (_pResult1 = _pResult; _v; _pResult1 += 4) {
  4003 		    for (_pResult1 = _pResult; _v; _pResult1 += 4) {
  4006                         if (_pResult1 > _pResultLast3) break;
  4004 			if (_pResult1 > _pResultLast3) break;
  4007                         _v += ((unsigned int *)_pResult1)[0];
  4005 			_v += ((unsigned int *)_pResult1)[0];
  4008                         ((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
  4006 			((unsigned int *)_pResult1)[0] = _v /* & 0xFFFFFFFF */;
  4009                         _v >>= 32;
  4007 			_v >>= 32;
  4010                     }
  4008 		    }
  4011                     for (; _v; _pResult1++) {
  4009 		    for (; _v; _pResult1++) {
  4012                         _v += _pResult1[0];
  4010 			_v += _pResult1[0];
  4013                         _pResult1[0] = _v /* & 0xFF */;
  4011 			_pResult1[0] = _v /* & 0xFF */;
  4014                         _v >>= 8;
  4012 			_v >>= 8;
  4015                     }
  4013 		    }
  4016                 }
  4014 		}
  4017                 _p2++;
  4015 		_p2++;
  4018             }
  4016 	    }
  4019         }
  4017 	}
  4020 #endif /* 64bit */
  4018 #endif /* 64bit */
  4021 
  4019 
  4022         /* loop over shorts of f1 */
  4020 	/* loop over shorts of f1 */
  4023         for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
  4021 	for (; _p1 < _p1Last; _p1 += 2, _pResult0 += 2) {
  4024             unsigned int short1 = ((unsigned short *)_p1)[0];
  4022 	    unsigned int short1 = ((unsigned short *)_p1)[0];
  4025 
  4023 
  4026 #if !defined(__LSBFIRST__)
  4024 #if !defined(__LSBFIRST__)
  4027             short1 = ((short1 >> 8) & 0xFF) | ((short1 & 0xFF) << 8);
  4025 	    short1 = ((short1 >> 8) & 0xFF) | ((short1 & 0xFF) << 8);
  4028 #endif
  4026 #endif
  4029             _pResult = _pResult0;
  4027 	    _pResult = _pResult0;
  4030             _p2 = otherBytes;
  4028 	    _p2 = otherBytes;
  4031 
  4029 
  4032             /* loop over shorts of f2 */
  4030 	    /* loop over shorts of f2 */
  4033             while (_p2 < _p2Last) {
  4031 	    while (_p2 < _p2Last) {
  4034 #if !defined(__LSBFIRST__)
  4032 #if !defined(__LSBFIRST__)
  4035                 unsigned int _short2;
  4033 		unsigned int _short2;
  4036                 unsigned int _short3;
  4034 		unsigned int _short3;
  4037 
  4035 
  4038                 _short2 = ((unsigned short *)_p2)[0];
  4036 		_short2 = ((unsigned short *)_p2)[0];
  4039                 _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
  4037 		_short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
  4040                 _short3 = ((unsigned short *)_pResult)[0];
  4038 		_short3 = ((unsigned short *)_pResult)[0];
  4041                 _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
  4039 		_short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
  4042                 _v = (short1 * _short2) + _short3;
  4040 		_v = (short1 * _short2) + _short3;
  4043                 _pResult[0] = _v;
  4041 		_pResult[0] = _v;
  4044                 _pResult[1] = _v >> 8;
  4042 		_pResult[1] = _v >> 8;
  4045 #else /* __LSBFIRST__ */
  4043 #else /* __LSBFIRST__ */
  4046                 _v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
  4044 		_v = (short1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
  4047                 ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
  4045 		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
  4048 #endif
  4046 #endif
  4049                 _v >>= 16; /* now _v contains the carry*/
  4047 		_v >>= 16; /* now _v contains the carry*/
  4050                 _pResult += 2;
  4048 		_pResult += 2;
  4051                 if (_v) {
  4049 		if (_v) {
  4052                     /* distribute carry - short-wise, then byte-wise */
  4050 		    /* distribute carry - short-wise, then byte-wise */
  4053                     _pResult1 = _pResult;
  4051 		    _pResult1 = _pResult;
  4054 #if defined(__LSBFIRST__)
  4052 #if defined(__LSBFIRST__)
  4055                     _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
  4053 		    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
  4056                     for (; _v; _pResult1 += 2) {
  4054 		    for (; _v; _pResult1 += 2) {
  4057                         if (_pResult1 > _pResultLast1) break;
  4055 			if (_pResult1 > _pResultLast1) break;
  4058                         _v += ((unsigned short *)_pResult1)[0];
  4056 			_v += ((unsigned short *)_pResult1)[0];
  4059                         ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
  4057 			((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
  4060                         _v >>= 16;
  4058 			_v >>= 16;
  4061                     }
  4059 		    }
  4062 #endif
  4060 #endif
  4063                     for (; _v; _pResult1++) {
  4061 		    for (; _v; _pResult1++) {
  4064                         _v += _pResult1[0];
  4062 			_v += _pResult1[0];
  4065                         _pResult1[0] = _v /* & 0xFF */;
  4063 			_pResult1[0] = _v /* & 0xFF */;
  4066                         _v >>= 8;
  4064 			_v >>= 8;
  4067                     }
  4065 		    }
  4068                 }
  4066 		}
  4069                 _p2 += 2;
  4067 		_p2 += 2;
  4070             }
  4068 	    }
  4071 
  4069 
  4072             /* possible odd highByte of f2 */
  4070 	    /* possible odd highByte of f2 */
  4073             if (_p2 <= _p2Last) {
  4071 	    if (_p2 <= _p2Last) {
  4074 #if !defined(__LSBFIRST__)
  4072 #if !defined(__LSBFIRST__)
  4075                 unsigned int _short3;
  4073 		unsigned int _short3;
  4076 
  4074 
  4077                 _short3 = ((unsigned short *)_pResult)[0];
  4075 		_short3 = ((unsigned short *)_pResult)[0];
  4078                 _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
  4076 		_short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
  4079                 _v = (short1 * _p2[0]) + _short3;
  4077 		_v = (short1 * _p2[0]) + _short3;
  4080                 _pResult[0] = _v;
  4078 		_pResult[0] = _v;
  4081                 _pResult[1] = _v >> 8;
  4079 		_pResult[1] = _v >> 8;
  4082 #else /* __LSBFIRST__ */
  4080 #else /* __LSBFIRST__ */
  4083                 _v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
  4081 		_v = (short1 * _p2[0]) + ((unsigned short *)_pResult)[0];
  4084                 ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
  4082 		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
  4085 #endif
  4083 #endif
  4086                 _v >>= 16; /* now _v contains the carry*/
  4084 		_v >>= 16; /* now _v contains the carry*/
  4087                 _pResult += 2;
  4085 		_pResult += 2;
  4088                 if (_v) {
  4086 		if (_v) {
  4089                     /* distribute carry - short-wise, then byte-wise */
  4087 		    /* distribute carry - short-wise, then byte-wise */
  4090                     _pResult1 = _pResult;
  4088 		    _pResult1 = _pResult;
  4091 #if defined(__LSBFIRST__)
  4089 #if defined(__LSBFIRST__)
  4092                     _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
  4090 		    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
  4093                     for (; _v; _pResult1 += 2) {
  4091 		    for (; _v; _pResult1 += 2) {
  4094                         if (_pResult1 > _pResultLast1) break;
  4092 			if (_pResult1 > _pResultLast1) break;
  4095                         _v += ((unsigned short *)_pResult1)[0];
  4093 			_v += ((unsigned short *)_pResult1)[0];
  4096                         ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
  4094 			((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
  4097                         _v >>= 16;
  4095 			_v >>= 16;
  4098                     }
  4096 		    }
  4099 #endif
  4097 #endif
  4100                     for (; _v; _pResult1++) {
  4098 		    for (; _v; _pResult1++) {
  4101                         _v += _pResult1[0];
  4099 			_v += _pResult1[0];
  4102                         _pResult1[0] = _v /* & 0xFF */;
  4100 			_pResult1[0] = _v /* & 0xFF */;
  4103                         _v >>= 8;
  4101 			_v >>= 8;
  4104                     }
  4102 		    }
  4105                 }
  4103 		}
  4106                 _p2++;
  4104 		_p2++;
  4107             }
  4105 	    }
  4108         }
  4106 	}
  4109 
  4107 
  4110         /* possible odd highByte of f1 (or byteLoop, if not __LSBFIRST__) */
  4108 	/* possible odd highByte of f1 (or byteLoop, if not __LSBFIRST__) */
  4111         for (; _p1 <= _p1Last; _p1++, _pResult0++) {
  4109 	for (; _p1 <= _p1Last; _p1++, _pResult0++) {
  4112             unsigned int byte1 = _p1[0];
  4110 	    unsigned int byte1 = _p1[0];
  4113 
  4111 
  4114             _pResult = _pResult0;
  4112 	    _pResult = _pResult0;
  4115             _p2 = otherBytes;
  4113 	    _p2 = otherBytes;
  4116 
  4114 
  4117             /* loop over shorts of f2 */
  4115 	    /* loop over shorts of f2 */
  4118             while (_p2 < _p2Last) {
  4116 	    while (_p2 < _p2Last) {
  4119 #if !defined(__LSBFIRST__)
  4117 #if !defined(__LSBFIRST__)
  4120                 unsigned int _short2;
  4118 		unsigned int _short2;
  4121                 unsigned int _short3;
  4119 		unsigned int _short3;
  4122 
  4120 
  4123                 _short2 = ((unsigned short *)_p2)[0];
  4121 		_short2 = ((unsigned short *)_p2)[0];
  4124                 _short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
  4122 		_short2 = ((_short2 >> 8) /* & 0xFF */) | ((_short2 & 0xFF) << 8);
  4125                 _short3 = ((unsigned short *)_pResult)[0];
  4123 		_short3 = ((unsigned short *)_pResult)[0];
  4126                 _short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
  4124 		_short3 = ((_short3 >> 8) /* & 0xFF */) | ((_short3 & 0xFF) << 8);
  4127                 _v = (byte1 * _short2) + _short3;
  4125 		_v = (byte1 * _short2) + _short3;
  4128                 _pResult[0] = _v;
  4126 		_pResult[0] = _v;
  4129                 _pResult[1] = _v >> 8;
  4127 		_pResult[1] = _v >> 8;
  4130 #else /* __LSBFIRST__ */
  4128 #else /* __LSBFIRST__ */
  4131                 _v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
  4129 		_v = (byte1 * ((unsigned short *)_p2)[0]) + ((unsigned short *)_pResult)[0];
  4132                 ((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
  4130 		((unsigned short *)_pResult)[0] = _v /* & 0xFFFF */;
  4133 #endif
  4131 #endif
  4134                 _v >>= 16; /* now _v contains the carry*/
  4132 		_v >>= 16; /* now _v contains the carry*/
  4135                 _pResult += 2;
  4133 		_pResult += 2;
  4136                 if (_v) {
  4134 		if (_v) {
  4137                     /* distribute carry - short-wise, then byte-wise */
  4135 		    /* distribute carry - short-wise, then byte-wise */
  4138                     _pResult1 = _pResult;
  4136 		    _pResult1 = _pResult;
  4139 #if defined(__LSBFIRST__)
  4137 #if defined(__LSBFIRST__)
  4140                     _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
  4138 		    _pResultLast1 = _pResult0 + _len1 + _len2 - 1 - 1;
  4141                     for (_pResult1 = _pResult; _v; _pResult1 += 2) {
  4139 		    for (_pResult1 = _pResult; _v; _pResult1 += 2) {
  4142                         if (_pResult1 > _pResultLast1) break;
  4140 			if (_pResult1 > _pResultLast1) break;
  4143                         _v += ((unsigned short *)_pResult1)[0];
  4141 			_v += ((unsigned short *)_pResult1)[0];
  4144                         ((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
  4142 			((unsigned short *)_pResult1)[0] = _v /* & 0xFFFF */;
  4145                         _v >>= 16;
  4143 			_v >>= 16;
  4146                     }
  4144 		    }
  4147 #endif /* __LSBFIRST__ */
  4145 #endif /* __LSBFIRST__ */
  4148                     for (; _v; _pResult1++) {
  4146 		    for (; _v; _pResult1++) {
  4149                         _v += _pResult1[0];
  4147 			_v += _pResult1[0];
  4150                         _pResult1[0] = _v /* & 0xFF */;
  4148 			_pResult1[0] = _v /* & 0xFF */;
  4151                         _v >>= 8;
  4149 			_v >>= 8;
  4152                     }
  4150 		    }
  4153                 }
  4151 		}
  4154                 _p2 += 2;
  4152 		_p2 += 2;
  4155             }
  4153 	    }
  4156 
  4154 
  4157             /* possible odd highByte of f2 (or byteLoop, if not __LSBFIRST__) */
  4155 	    /* possible odd highByte of f2 (or byteLoop, if not __LSBFIRST__) */
  4158             while (_p2 <= _p2Last) {
  4156 	    while (_p2 <= _p2Last) {
  4159                 _v = (byte1 * _p2[0]) + _pResult[0];
  4157 		_v = (byte1 * _p2[0]) + _pResult[0];
  4160                 _pResult[0] = _v /* & 0xFF */;
  4158 		_pResult[0] = _v /* & 0xFF */;
  4161                 _v >>= 8; /* now _v contains the carry*/
  4159 		_v >>= 8; /* now _v contains the carry*/
  4162                 _pResult++;
  4160 		_pResult++;
  4163                 if (_v) {
  4161 		if (_v) {
  4164                     /* distribute carry */
  4162 		    /* distribute carry */
  4165                     for (_pResult1 = _pResult; _v; _pResult1++) {
  4163 		    for (_pResult1 = _pResult; _v; _pResult1++) {
  4166                         _v += _pResult1[0];
  4164 			_v += _pResult1[0];
  4167                         _pResult1[0] = _v /* & 0xFF */;
  4165 			_pResult1[0] = _v /* & 0xFF */;
  4168                         _v >>= 8;
  4166 			_v >>= 8;
  4169                     }
  4167 		    }
  4170                 }
  4168 		}
  4171                 _p2++;
  4169 		_p2++;
  4172             }
  4170 	    }
  4173         }
  4171 	}
  4174         ok = true;
  4172 	ok = true;
  4175     }
  4173     }
  4176 %}.
  4174 %}.
  4177     ok ifFalse:[
  4175     ok ifFalse:[
  4178         1 to:len1 do:[:index1 |
  4176 	1 to:len1 do:[:index1 |
  4179             1 to:len2 do:[:index2 |
  4177 	    1 to:len2 do:[:index2 |
  4180                 dstIndex := index1 + index2 - 1.
  4178 		dstIndex := index1 + index2 - 1.
  4181                 prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
  4179 		prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
  4182                 prod := prod + (resultDigitByteArray basicAt:dstIndex).
  4180 		prod := prod + (resultDigitByteArray basicAt:dstIndex).
  4183                 resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
  4181 		resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
  4184                 carry := prod bitShift:-8.
  4182 		carry := prod bitShift:-8.
  4185                 carry ~~ 0 ifTrue:[
  4183 		carry ~~ 0 ifTrue:[
  4186                     idx := dstIndex + 1.
  4184 		    idx := dstIndex + 1.
  4187                     [carry ~~ 0] whileTrue:[
  4185 		    [carry ~~ 0] whileTrue:[
  4188                         v := (resultDigitByteArray basicAt:idx) + carry.
  4186 			v := (resultDigitByteArray basicAt:idx) + carry.
  4189                         resultDigitByteArray basicAt:idx put:(v bitAnd:255).
  4187 			resultDigitByteArray basicAt:idx put:(v bitAnd:255).
  4190                         carry := v bitShift:-8.
  4188 			carry := v bitShift:-8.
  4191                         idx := idx + 1
  4189 			idx := idx + 1
  4192                     ]
  4190 		    ]
  4193                 ]
  4191 		]
  4194             ]
  4192 	    ]
  4195         ].
  4193 	].
  4196     ].
  4194     ].
  4197     ^ result compressed
  4195     ^ result compressed
  4198 !
  4196 !
  4199 
  4197 
  4200 absPlus:aLargeInteger sign:newSign
  4198 absPlus:aLargeInteger sign:newSign
  4714     "Modified: 11.8.1997 / 03:23:37 / cg"
  4712     "Modified: 11.8.1997 / 03:23:37 / cg"
  4715 !
  4713 !
  4716 
  4714 
  4717 absSubtract:aLargeInteger
  4715 absSubtract:aLargeInteger
  4718     "private helper for division:
  4716     "private helper for division:
  4719         destructively subtract aLargeInteger from myself
  4717 	destructively subtract aLargeInteger from myself
  4720         AND return true, if the result is non-zero, false otherwise.
  4718 	AND return true, if the result is non-zero, false otherwise.
  4721         (i.e. this method has both a return value and a side-effect
  4719 	(i.e. this method has both a return value and a side-effect
  4722          on the receiver)
  4720 	 on the receiver)
  4723         Only allowed for positive receiver and argument
  4721 	Only allowed for positive receiver and argument
  4724         The receiver must be >= the argument.
  4722 	The receiver must be >= the argument.
  4725         The receiver must be a temporary scratch-number"
  4723 	The receiver must be a temporary scratch-number"
  4726 
  4724 
  4727     |otherDigitByteArray
  4725     |otherDigitByteArray
  4728      len1   "{ Class: SmallInteger }"
  4726      len1   "{ Class: SmallInteger }"
  4729      len2   "{ Class: SmallInteger }"
  4727      len2   "{ Class: SmallInteger }"
  4730      index  "{ Class: SmallInteger }"
  4728      index  "{ Class: SmallInteger }"
  4736     notZero := false.
  4734     notZero := false.
  4737     len1 := digitByteArray size.
  4735     len1 := digitByteArray size.
  4738     otherDigitByteArray := aLargeInteger digitBytes.
  4736     otherDigitByteArray := aLargeInteger digitBytes.
  4739     len2 := otherDigitByteArray size.
  4737     len2 := otherDigitByteArray size.
  4740     len2 > len1 ifTrue:[
  4738     len2 > len1 ifTrue:[
  4741         [(otherDigitByteArray at:len2) == 0] whileTrue:[
  4739 	[(otherDigitByteArray at:len2) == 0] whileTrue:[
  4742             len2 := len2 - 1
  4740 	    len2 := len2 - 1
  4743         ].
  4741 	].
  4744         len2 > len1 ifTrue:[
  4742 	len2 > len1 ifTrue:[
  4745             self error:'operation failed' "/ may not be called that way
  4743 	    self error:'operation failed' "/ may not be called that way
  4746         ].
  4744 	].
  4747     ].
  4745     ].
  4748     "/ knowing that len2 is <= len1
  4746     "/ knowing that len2 is <= len1
  4749 %{
  4747 %{
  4750 
  4748 
  4751     OBJ _digitByteArray = __INST(digitByteArray);
  4749     OBJ _digitByteArray = __INST(digitByteArray);
  4752 
  4750 
  4753     if (__isByteArray(_digitByteArray)
  4751     if (__isByteArray(_digitByteArray)
  4754      && __isByteArray(otherDigitByteArray)) {
  4752      && __isByteArray(otherDigitByteArray)) {
  4755         int _len1 = __intVal(len1),
  4753 	int _len1 = __intVal(len1),
  4756             _len2 = __intVal(len2);
  4754 	    _len2 = __intVal(len2);
  4757         unsigned char *_myDigits, *_otherDigits;
  4755 	unsigned char *_myDigits, *_otherDigits;
  4758         int _index = 1, _borrow = 0;
  4756 	int _index = 1, _borrow = 0;
  4759         INT _diff;
  4757 	INT _diff;
  4760         int anyBitNonZero = 0;
  4758 	INT anyBitNonZero = 0;
  4761 
  4759 
  4762         _otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  4760 	_otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  4763         _myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  4761 	_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  4764 
  4762 
  4765 #if defined(__LSBFIRST__)
  4763 #if defined(__LSBFIRST__)
  4766 # if __POINTER_SIZE__ == 8
  4764 # if __POINTER_SIZE__ == 8
  4767         {
  4765 	{
  4768             int _len2Q;
  4766 	    int _len2Q;
  4769             /*
  4767 	    /*
  4770              * subtract int-wise
  4768 	     * subtract int-wise
  4771              */
  4769 	     */
  4772             _len2Q = _len2-2;
  4770 	    _len2Q = _len2-2;
  4773             while (_index < _len2Q) {
  4771 	    while (_index < _len2Q) {
  4774                 /* do not combine the expression below (may lead to unsigned result on some machines */
  4772 		/* do not combine the expression below (may lead to unsigned result on some machines */
  4775                 _diff = ((unsigned int *)(_myDigits+_index-1))[0];
  4773 		_diff = ((unsigned int *)(_myDigits+_index-1))[0];
  4776                 _diff -= ((unsigned int *)(_otherDigits+_index-1))[0];
  4774 		_diff -= ((unsigned int *)(_otherDigits+_index-1))[0];
  4777                 _diff -= _borrow;
  4775 		_diff -= _borrow;
  4778                 if (_diff >= 0) {
  4776 		if (_diff >= 0) {
  4779                     _borrow = 0;
  4777 		    _borrow = 0;
  4780                 } else {
  4778 		} else {
  4781                     _borrow = 1;
  4779 		    _borrow = 1;
  4782                     /* _diff += 0x10000; */
  4780 		    /* _diff += 0x10000; */
  4783                 }
  4781 		}
  4784                 ((unsigned int *)(_myDigits+_index-1))[0] = _diff;
  4782 		((unsigned int *)(_myDigits+_index-1))[0] = _diff;
  4785                 anyBitNonZero |= (_diff & 0xFFFFFFFFL);
  4783 		anyBitNonZero |= (_diff & 0xFFFFFFFFL);
  4786                 _index += 4;
  4784 		_index += 4;
  4787             }
  4785 	    }
  4788         }
  4786 	}
  4789 # endif
  4787 # endif
  4790 
  4788 
  4791         /*
  4789 	/*
  4792          * subtract short-wise
  4790 	 * subtract short-wise
  4793          */
  4791 	 */
  4794         while (_index < _len2) {
  4792 	while (_index < _len2) {
  4795             /* do not combine the expression below (may lead to unsigned result on some machines */
  4793 	    /* do not combine the expression below (may lead to unsigned result on some machines */
  4796             _diff = ((unsigned short *)(_myDigits+_index-1))[0];
  4794 	    _diff = ((unsigned short *)(_myDigits+_index-1))[0];
  4797             _diff -= ((unsigned short *)(_otherDigits+_index-1))[0];
  4795 	    _diff -= ((unsigned short *)(_otherDigits+_index-1))[0];
  4798             _diff -= _borrow;
  4796 	    _diff -= _borrow;
  4799             if (_diff >= 0) {
  4797 	    if (_diff >= 0) {
  4800                 _borrow = 0;
  4798 		_borrow = 0;
  4801             } else {
  4799 	    } else {
  4802                 _borrow = 1;
  4800 		_borrow = 1;
  4803                 /* _diff += 0x10000; */
  4801 		/* _diff += 0x10000; */
  4804             }
  4802 	    }
  4805             ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
  4803 	    ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
  4806             anyBitNonZero |= (_diff & 0xFFFF);
  4804 	    anyBitNonZero |= (_diff & 0xFFFF);
  4807             _index += 2;
  4805 	    _index += 2;
  4808         }
  4806 	}
  4809 
  4807 
  4810         if (_index <= _len2) {
  4808 	if (_index <= _len2) {
  4811             /*
  4809 	    /*
  4812              * cannot continue with shorts - there is an odd number of
  4810 	     * cannot continue with shorts - there is an odd number of
  4813              * bytes in the minuent
  4811 	     * bytes in the minuent
  4814              */
  4812 	     */
  4815         } else {
  4813 	} else {
  4816             while (_index < _len1) {
  4814 	    while (_index < _len1) {
  4817                 /* do not combine the expression below (may lead to unsigned result on some machines */
  4815 		/* do not combine the expression below (may lead to unsigned result on some machines */
  4818                 _diff = ((unsigned short *)(_myDigits+_index-1))[0];
  4816 		_diff = ((unsigned short *)(_myDigits+_index-1))[0];
  4819                 _diff -= _borrow;
  4817 		_diff -= _borrow;
  4820                 if (_diff >= 0) {
  4818 		if (_diff >= 0) {
  4821                     /* _borrow = 0; */
  4819 		    /* _borrow = 0; */
  4822                     ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
  4820 		    ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
  4823                     anyBitNonZero |= (_diff & 0xFFFF);
  4821 		    anyBitNonZero |= (_diff & 0xFFFF);
  4824                     _index += 2;
  4822 		    _index += 2;
  4825                     while (_index < _len1) {
  4823 		    while (_index < _len1) {
  4826                         anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0];
  4824 			anyBitNonZero |= ((unsigned short *)(_myDigits+_index-1))[0];
  4827                         if (anyBitNonZero) {
  4825 			if (anyBitNonZero) {
  4828                             RETURN (true);
  4826 			    RETURN (true);
  4829                         }
  4827 			}
  4830                         _index += 2;
  4828 			_index += 2;
  4831                     }
  4829 		    }
  4832                     /* last odd index */
  4830 		    /* last odd index */
  4833                     if (_index <= _len1) {
  4831 		    if (_index <= _len1) {
  4834                         anyBitNonZero |= _myDigits[_index - 1];;
  4832 			anyBitNonZero |= _myDigits[_index - 1];;
  4835                         if (anyBitNonZero) {
  4833 			if (anyBitNonZero) {
  4836                             RETURN (true);
  4834 			    RETURN (true);
  4837                         }
  4835 			}
  4838                         _index++;
  4836 			_index++;
  4839                     }
  4837 		    }
  4840                     RETURN (anyBitNonZero ? true : false);
  4838 		    RETURN (anyBitNonZero ? true : false);
  4841                 }
  4839 		}
  4842                 _borrow = 1;
  4840 		_borrow = 1;
  4843                 /* _diff += 0x10000; */
  4841 		/* _diff += 0x10000; */
  4844 
  4842 
  4845                 ((unsigned short *)(_myDigits+_index-1))[0] = _diff;
  4843 		((unsigned short *)(_myDigits+_index-1))[0] = _diff;
  4846                 anyBitNonZero |= (_diff & 0xFFFF);
  4844 		anyBitNonZero |= (_diff & 0xFFFF);
  4847                 _index += 2;
  4845 		_index += 2;
  4848             }
  4846 	    }
  4849         }
  4847 	}
  4850 #endif
  4848 #endif
  4851         /*
  4849 	/*
  4852          * subtract byte-wise
  4850 	 * subtract byte-wise
  4853          */
  4851 	 */
  4854         while (_index <= _len2) {
  4852 	while (_index <= _len2) {
  4855             /* do not combine the expression below (may lead to unsigned result on some machines */
  4853 	    /* do not combine the expression below (may lead to unsigned result on some machines */
  4856             _diff = _myDigits[_index - 1];
  4854 	    _diff = _myDigits[_index - 1];
  4857             _diff -= _otherDigits[_index - 1];
  4855 	    _diff -= _otherDigits[_index - 1];
  4858             _diff -= _borrow;
  4856 	    _diff -= _borrow;
  4859             if (_diff >= 0) {
  4857 	    if (_diff >= 0) {
  4860                 _borrow = 0;
  4858 		_borrow = 0;
  4861             } else {
  4859 	    } else {
  4862                 _borrow = 1;
  4860 		_borrow = 1;
  4863                 /* _diff += 0x100; */
  4861 		/* _diff += 0x100; */
  4864             }
  4862 	    }
  4865             _myDigits[_index - 1] = _diff;
  4863 	    _myDigits[_index - 1] = _diff;
  4866             anyBitNonZero |= (_diff & 0xFF);
  4864 	    anyBitNonZero |= (_diff & 0xFF);
  4867             _index++;
  4865 	    _index++;
  4868         }
  4866 	}
  4869 
  4867 
  4870         while (_index <= _len1) {
  4868 	while (_index <= _len1) {
  4871             /* do not combine the expression below (may lead to unsigned result on some machines */
  4869 	    /* do not combine the expression below (may lead to unsigned result on some machines */
  4872             _diff = _myDigits[_index - 1];
  4870 	    _diff = _myDigits[_index - 1];
  4873             _diff -= _borrow;
  4871 	    _diff -= _borrow;
  4874             if (_diff >= 0) {
  4872 	    if (_diff >= 0) {
  4875                 /* _borrow = 0; */
  4873 		/* _borrow = 0; */
  4876                 _myDigits[_index - 1] = _diff;
  4874 		_myDigits[_index - 1] = _diff;
  4877                 anyBitNonZero |= (_diff & 0xFF);
  4875 		anyBitNonZero |= (_diff & 0xFF);
  4878                 _index++;
  4876 		_index++;
  4879                 while (_index <= _len1) {
  4877 		while (_index <= _len1) {
  4880                     anyBitNonZero |= _myDigits[_index - 1];
  4878 		    anyBitNonZero |= _myDigits[_index - 1];
  4881                     if (anyBitNonZero) {
  4879 		    if (anyBitNonZero) {
  4882                         RETURN (true);
  4880 			RETURN (true);
  4883                     }
  4881 		    }
  4884                     _index++;
  4882 		    _index++;
  4885                 }
  4883 		}
  4886                 break;
  4884 		break;
  4887             }
  4885 	    }
  4888             _borrow = 1;
  4886 	    _borrow = 1;
  4889             /* _diff += 0x100; */
  4887 	    /* _diff += 0x100; */
  4890 
  4888 
  4891             _myDigits[_index - 1] = _diff;
  4889 	    _myDigits[_index - 1] = _diff;
  4892             anyBitNonZero |= (_diff & 0xFF);
  4890 	    anyBitNonZero |= (_diff & 0xFF);
  4893             _index++;
  4891 	    _index++;
  4894         }
  4892 	}
  4895         RETURN (anyBitNonZero ? true : false);
  4893 	RETURN (anyBitNonZero ? true : false);
  4896     }
  4894     }
  4897 %}.
  4895 %}.
  4898 
  4896 
  4899     index := 1.
  4897     index := 1.
  4900     borrow := 0.
  4898     borrow := 0.
  4901 
  4899 
  4902     [index <= len1] whileTrue:[
  4900     [index <= len1] whileTrue:[
  4903         diff := borrow.
  4901 	diff := borrow.
  4904         diff := diff + (digitByteArray basicAt:index).
  4902 	diff := diff + (digitByteArray basicAt:index).
  4905         index <= len2 ifTrue:[
  4903 	index <= len2 ifTrue:[
  4906             diff := diff - (otherDigitByteArray basicAt:index).
  4904 	    diff := diff - (otherDigitByteArray basicAt:index).
  4907         ].
  4905 	].
  4908 
  4906 
  4909         "/ workaround for
  4907 	"/ workaround for
  4910         "/ gcc code generator bug
  4908 	"/ gcc code generator bug
  4911 
  4909 
  4912         (diff >= 0) ifTrue:[
  4910 	(diff >= 0) ifTrue:[
  4913             borrow := 0
  4911 	    borrow := 0
  4914         ] ifFalse:[
  4912 	] ifFalse:[
  4915             borrow := -1.
  4913 	    borrow := -1.
  4916             diff := diff + 16r100
  4914 	    diff := diff + 16r100
  4917         ].
  4915 	].
  4918         diff ~~ 0 ifTrue:[
  4916 	diff ~~ 0 ifTrue:[
  4919             notZero := true
  4917 	    notZero := true
  4920         ].
  4918 	].
  4921         digitByteArray basicAt:index put:diff.
  4919 	digitByteArray basicAt:index put:diff.
  4922         index := index + 1
  4920 	index := index + 1
  4923     ].
  4921     ].
  4924 
  4922 
  4925     ^ notZero
  4923     ^ notZero
  4926 
  4924 
  4927     "Created: / 5.11.1996 / 16:23:47 / cg"
  4925     "Created: / 5.11.1996 / 16:23:47 / cg"
  4929     "Modified: / 27.4.1999 / 18:08:23 / stefan"
  4927     "Modified: / 27.4.1999 / 18:08:23 / stefan"
  4930 !
  4928 !
  4931 
  4929 
  4932 div2
  4930 div2
  4933     "private helper for division:
  4931     "private helper for division:
  4934        destructively divide the receiver by 2.
  4932        destructively divide the receiver by 2."
  4935        may leave the receiver unnormalized (i.e. with a leftover 0 high-byte)"
       
  4936 
  4933 
  4937     |prevBit|
  4934     |prevBit|
  4938 
  4935 
  4939 %{  /* NOCONTEXT */
  4936 %{  /* NOCONTEXT */
  4940     OBJ __digits = __INST(digitByteArray);
  4937     OBJ __digits = __INST(digitByteArray);
  4941 
  4938 
  4942     if (__isByteArray(__digits)) {
  4939     if (__isByteArray(__digits)) {
  4943         int __nBytes = __byteArraySize(__digits);
  4940 	int __nBytes = __byteArraySize(__digits);
  4944         unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
  4941 	unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
  4945         unsigned INT __this, __next;
  4942 	unsigned INT __this, __next;
  4946         int __idx;
  4943 	int __idx;
  4947 
  4944 
  4948         if (__nBytes == 1) {
  4945 	if (__nBytes == 1) {
  4949             __bp[0] >>= 1;
  4946 	    __bp[0] >>= 1;
  4950             RETURN (self);
  4947 	    RETURN (self);
  4951         }
  4948 	}
  4952 
  4949 
  4953         __idx = 1;
  4950 	__idx = 1;
  4954 
  4951 
  4955 #if defined(__LSBFIRST__) 
  4952 #if defined(__LSBFIRST__) && (__POINTER_SIZE__ == 8)
  4956 # if (__POINTER_SIZE__ == 8)
  4953 	if (sizeof(unsigned INT) == 8) {
  4957         if (sizeof(unsigned INT) == 8) {
  4954 	    int __endIndex = __nBytes - 8;
  4958             int __endIndex = __nBytes - 8;
  4955 
  4959 
  4956 	    if (__idx < __endIndex) {
  4960             if (__idx < __endIndex) {
  4957 		__this = ((unsigned INT *)__bp)[0];
  4961                 __this = ((unsigned INT *)__bp)[0];
  4958 
  4962 
  4959 		while (__idx < __endIndex) {
  4963                 while (__idx < __endIndex) {
  4960 		    __next = ((unsigned INT *)__bp)[1];
  4964                     __next = ((unsigned INT *)__bp)[1];
  4961 		    __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
  4965                     __this = (__this >> 1) /* & 0x7FFFFFFFFFFFFFF */;
  4962 		    __this |= __next << 63;
  4966                     __this |= __next << 63;
  4963 		    ((unsigned INT *)__bp)[0] = __this;
  4967                     ((unsigned INT *)__bp)[0] = __this;
  4964 		    __this = __next;
  4968                     __this = __next;
  4965 		    __bp += 8;
  4969                     __bp += 8;
  4966 		    __idx += 8;
  4970                     __idx += 8;
  4967 		}
  4971                 }
  4968 	    }
  4972             }
  4969 	}
  4973 
  4970 #else
  4974             if (__idx < (__nBytes - 4)) {
  4971 # if defined(__LSBFIRST__)
  4975                 __this = ((unsigned int *)__bp)[0];
  4972 	if (sizeof(unsigned int) == 4) {
  4976 
  4973 	    int __endIndex = __nBytes - 4;
  4977                 __next = ((unsigned int *)__bp)[1];
  4974 
  4978                 __this = (__this >> 1) /* & 0x7FFFFFF */;
  4975 	    if (__idx < __endIndex) {
  4979                 __this |= __next << 31;
  4976 		__this = ((unsigned INT *)__bp)[0];
  4980                 ((unsigned int *)__bp)[0] = __this;
  4977 
  4981                 __this = __next;
  4978 # if 0
  4982                 __bp += 4;
  4979 		__idx += 4;
  4983                 __idx += 4;
  4980 		while (__idx < __endIndex) {
  4984             }
  4981 		    __next = ((unsigned int *)__bp)[1];
  4985             if (__idx < (__nBytes - 2)) {
  4982 		    __this = (__this >> 1) /* & 0x7FFFFFF */;
  4986                 __this = ((unsigned short *)__bp)[0];
  4983 		    __this |= __next << 31;
  4987 
  4984 		    ((unsigned int *)__bp)[0] = __this;
  4988                 __next = ((unsigned short *)__bp)[1];
  4985 		    __this = __next;
  4989                 __this = (__this >> 1) /* & 0x7FFFFFF */;
  4986 
  4990                 __this |= __next << 15;
  4987 		    __next = ((unsigned int *)__bp)[2];
  4991                 ((unsigned short *)__bp)[0] = __this;
  4988 		    __this = (__this >> 1) /* & 0x7FFFFFF */;
  4992                 __this = __next;
  4989 		    __this |= __next << 31;
  4993                 __bp += 2;
  4990 		    ((unsigned int *)__bp)[1] = __this;
  4994                 __idx += 2;
  4991 		    __this = __next;
  4995             }
  4992 
  4996         }
  4993 		    __bp += 8;
  4997 # else
  4994 		    __idx += 8;
  4998         if (sizeof(unsigned int) == 4) {
  4995 		}
  4999             int __endIndex = __nBytes - 4;
  4996 		__idx -= 4;
  5000 
  4997 # endif
  5001             if (__idx < __endIndex) {
  4998 		while (__idx < __endIndex) {
  5002                 __this = ((unsigned int *)__bp)[0];
  4999 		    __next = ((unsigned int *)__bp)[1];
  5003 
  5000 		    __this = (__this >> 1) /* & 0x7FFFFFF */;
  5004                 while (__idx < __endIndex) {
  5001 		    __this |= __next << 31;
  5005                     __next = ((unsigned int *)__bp)[1];
  5002 		    ((unsigned int *)__bp)[0] = __this;
  5006                     __this = (__this >> 1) /* & 0x7FFFFFF */;
  5003 		    __this = __next;
  5007                     __this |= __next << 31;
  5004 		    __bp += 4;
  5008                     ((unsigned int *)__bp)[0] = __this;
  5005 		    __idx += 4;
  5009                     __this = __next;
  5006 		}
  5010                     __bp += 4;
  5007 	    }
  5011                     __idx += 4;
  5008 	}
  5012                 }
       
  5013             }
       
  5014         }
       
  5015 # endif
  5009 # endif
  5016 #endif
  5010 #endif
  5017 
  5011 
  5018         __this = __bp[0];
  5012 	__this = __bp[0];
  5019         while (__idx < __nBytes) {
  5013 	while (__idx < __nBytes) {
  5020             __next = __bp[1];
  5014 	    __next = __bp[1];
  5021             __this >>= 1;
  5015 	    __this >>= 1;
  5022             __this |= __next << 7;
  5016 	    __this |= __next << 7;
  5023             __bp[0] = __this;
  5017 	    __bp[0] = __this;
  5024             __this = __next;
  5018 	    __this = __next;
  5025             __bp++;
  5019 	    __bp++;
  5026             __idx++;
  5020 	    __idx++;
  5027         }
  5021 	}
  5028         __bp[0] = __this >> 1;
  5022 	__bp[0] = __this >> 1;
  5029         RETURN (self);
  5023 	RETURN (self);
  5030     }
  5024     }
  5031 %}.
  5025 %}.
  5032 
  5026 
  5033     prevBit := 0.
  5027     prevBit := 0.
  5034     digitByteArray size to:1 by:-1 do:[:idx |
  5028     digitByteArray size to:1 by:-1 do:[:idx |
  5035         |thisByte|
  5029 	|thisByte|
  5036 
  5030 
  5037         thisByte := digitByteArray at:idx.
  5031 	thisByte := digitByteArray at:idx.
  5038         digitByteArray at:idx put:((thisByte bitShift:-1) bitOr:prevBit).
  5032 	digitByteArray at:idx put:((thisByte bitShift:-1) bitOr:prevBit).
  5039         prevBit := (thisByte bitAnd:1) bitShift:7.
  5033 	prevBit := (thisByte bitAnd:1) bitShift:7.
  5040     ].
  5034     ].
  5041 
  5035 
  5042     "
  5036     "
  5043      100000 asLargeInteger div2
  5037      100000 asLargeInteger div2
  5044      1000000000000000000000000000 div2
  5038      1000000000000000000000000000 div2
  5058 
  5052 
  5059     nBytes := digitByteArray size.
  5053     nBytes := digitByteArray size.
  5060 
  5054 
  5061     b := digitByteArray at:nBytes.
  5055     b := digitByteArray at:nBytes.
  5062     (b bitAnd:16r80) ~~ 0 ifTrue:[
  5056     (b bitAnd:16r80) ~~ 0 ifTrue:[
  5063         "/ need another byte
  5057 	"/ need another byte
  5064         nBytes := nBytes + 1.
  5058 	nBytes := nBytes + 1.
  5065         t := ByteArray uninitializedNew:nBytes.
  5059 	t := ByteArray uninitializedNew:nBytes.
  5066         t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
  5060 	t replaceFrom:1 to:nBytes-1 with:digitByteArray startingAt:1.
  5067         t at:nBytes put:0.
  5061 	t at:nBytes put:0.
  5068         digitByteArray := t.
  5062 	digitByteArray := t.
  5069     ].
  5063     ].
  5070 
  5064 
  5071 %{
  5065 %{
  5072     OBJ __digits = __INST(digitByteArray);
  5066     OBJ __digits = __INST(digitByteArray);
  5073 
  5067 
  5074     if (__isByteArray(__digits)) {
  5068     if (__isByteArray(__digits)) {
  5075         int __nBytes = __intVal(nBytes);
  5069 	int __nBytes = __intVal(nBytes);
  5076         unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
  5070 	unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element;
  5077         unsigned INT __carry = 0, __newCarry;
  5071 	unsigned INT __carry = 0, __newCarry;
  5078 
  5072 
  5079 #if defined(__LSBFIRST__)
  5073 #if defined(__LSBFIRST__)
  5080 # if (__POINTER_SIZE__ == 8)
  5074 # if (__POINTER_SIZE__ == 8)
  5081         if (sizeof(unsigned INT) == 8) {
  5075 	if (sizeof(unsigned INT) == 8) {
  5082             while (__nBytes >= 8) {
  5076 	    while (__nBytes >= 8) {
  5083                 unsigned INT __this;
  5077 		unsigned INT __this;
  5084 
  5078 
  5085                 __this = ((unsigned INT *)__bp)[0];
  5079 		__this = ((unsigned INT *)__bp)[0];
  5086                 __newCarry = (__this >> 63) /* & 1 */;
  5080 		__newCarry = (__this >> 63) /* & 1 */;
  5087                 ((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
  5081 		((unsigned INT *)__bp)[0] = (__this << 1) | __carry;
  5088                 __carry = __newCarry;
  5082 		__carry = __newCarry;
  5089                 __bp += 8;
  5083 		__bp += 8;
  5090                 __nBytes -= 8;
  5084 		__nBytes -= 8;
  5091             }
  5085 	    }
  5092         }
  5086 	}
  5093 # endif
  5087 # endif
  5094         if (sizeof(unsigned int) == 4) {
  5088 	if (sizeof(unsigned int) == 4) {
  5095             while (__nBytes >= 4) {
  5089 	    while (__nBytes >= 4) {
  5096                 unsigned int __this;
  5090 		unsigned int __this;
  5097 
  5091 
  5098                 __this = ((unsigned int *)__bp)[0];
  5092 		__this = ((unsigned int *)__bp)[0];
  5099                 __newCarry = (__this >> 31) /* & 1 */;
  5093 		__newCarry = (__this >> 31) /* & 1 */;
  5100                 ((unsigned int *)__bp)[0] = (__this << 1) | __carry;
  5094 		((unsigned int *)__bp)[0] = (__this << 1) | __carry;
  5101                 __carry = __newCarry;
  5095 		__carry = __newCarry;
  5102                 __bp += 4;
  5096 		__bp += 4;
  5103                 __nBytes -= 4;
  5097 		__nBytes -= 4;
  5104             }
  5098 	    }
  5105         }
  5099 	}
  5106         if (__nBytes >= 2) {
       
  5107             unsigned short __this;
       
  5108 
       
  5109             __this = ((unsigned short *)__bp)[0];
       
  5110             __newCarry = (__this >> 15) /* & 1 */;
       
  5111             ((unsigned short *)__bp)[0] = (__this << 1) | __carry;
       
  5112             __carry = __newCarry;
       
  5113             __bp += 2;
       
  5114             __nBytes -= 2;
       
  5115         }
       
  5116 #endif /* LSBFIRST */
  5100 #endif /* LSBFIRST */
  5117         while (__nBytes) {
  5101 	while (__nBytes) {
  5118             unsigned char __this;
  5102 	    unsigned char __this;
  5119 
  5103 
  5120             __this = __bp[0];
  5104 	    __this = __bp[0];
  5121             __newCarry = (__this >> 7) /* & 1 */;
  5105 	    __newCarry = (__this >> 7) /* & 1 */;
  5122             __bp[0] = (__this << 1) | __carry;
  5106 	    __bp[0] = (__this << 1) | __carry;
  5123             __carry = __newCarry;
  5107 	    __carry = __newCarry;
  5124             __bp++;
  5108 	    __bp++;
  5125             __nBytes--;
  5109 	    __nBytes--;
  5126         }
  5110 	}
  5127         RETURN (self);
  5111 	RETURN (self);
  5128     }
  5112     }
  5129 %}.
  5113 %}.
  5130 
  5114 
  5131     prevBit := 0.
  5115     prevBit := 0.
  5132     1 to:digitByteArray size do:[:idx |
  5116     1 to:digitByteArray size do:[:idx |
  5133         |thisByte|
  5117 	|thisByte|
  5134 
  5118 
  5135         thisByte := digitByteArray at:idx.
  5119 	thisByte := digitByteArray at:idx.
  5136         digitByteArray at:idx put:(((thisByte bitShift:1) bitAnd:16rFF) bitOr:prevBit).
  5120 	digitByteArray at:idx put:(((thisByte bitShift:1) bitAnd:16rFF) bitOr:prevBit).
  5137         prevBit := (thisByte bitShift:-7) bitAnd:1.
  5121 	prevBit := (thisByte bitShift:-7) bitAnd:1.
  5138     ].
  5122     ].
  5139 
  5123 
  5140     "
  5124     "
  5141      100000 asLargeInteger mul2
  5125      100000 asLargeInteger mul2
  5142      16r7FFFFFFFFFFF copy mul2 hexPrintString
  5126      16r7FFFFFFFFFFF copy mul2 hexPrintString
  5220 ! !
  5204 ! !
  5221 
  5205 
  5222 !LargeInteger class methodsFor:'documentation'!
  5206 !LargeInteger class methodsFor:'documentation'!
  5223 
  5207 
  5224 version
  5208 version
  5225     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.210 2013-05-27 08:13:50 cg Exp $'
  5209     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.209 2013-05-21 20:44:47 cg Exp $'
  5226 !
  5210 !
  5227 
  5211 
  5228 version_CVS
  5212 version_CVS
  5229     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.210 2013-05-27 08:13:50 cg Exp $'
  5213     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.209 2013-05-21 20:44:47 cg Exp $'
  5230 ! !
  5214 ! !
  5231 
  5215