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 |
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 |