internal static bool Equal(LongIntBase A, bool AisPositive, LongIntBase B, bool BisPositive) { if (A.IsZero() && B.IsZero()) return true; if (AisPositive != BisPositive) return false; return LongMath.Equal(A, B); }
internal static bool Equal(LongIntBase A, bool AisPositive, short b) { if (b == 0) return A.IsZero(); bool bSign = (b >= 0); if (AisPositive != bSign) return false; if (b < 0) b *= -1; return LongMath.Equal(A, (ushort)b); }
internal static bool Equal(LongIntBase A, ushort b) { if (b == 0) return A.IsZero(); if (A.Size > 2 || A.Size < 1) return false; int index = 0; uint Base = A.Base; do { if (A[index] != (ushort)(b % Base)) return false; b = (ushort)(b / Base); ++index; } while (b != 0); return true; }
internal static LongIntBase Multiply(LongIntBase A, bool AisPositive, short b, out bool resultSign) { if (A.IsZero() || (b == 0)) { resultSign = true; return new LongIntBase(0, A.Base, A.CoefLength); } resultSign = !(AisPositive ^ (b >= 0)); if (b < 0) b *= -1; if (b == 1) return new LongIntBase(A, ConstructorMode.Copy); return new LongIntBase(LongMath.UShortMul(A, (ushort)b), ConstructorMode.Assign); }
internal static LongIntBase Multiply(LongIntBase A, bool AisPositive, LongIntBase B, bool BisPositive, out bool resultSign) { if (A.IsZero() || B.IsZero()) { resultSign = true; return new LongIntBase(0, A.Base, A.CoefLength); } resultSign = !(AisPositive ^ BisPositive); return new LongIntBase(LongMath.Multiply(A, B), ConstructorMode.Assign); }
internal static LongIntBase Divide(LongIntBase A, bool AisPositive, short b, out bool resultSign) { if (A.IsZero()) { resultSign = true; return new LongIntBase(A); } resultSign = !((b >= 0) ^ AisPositive); if (b < 0) b *= -1; if (b == 1) return new LongIntBase(A, ConstructorMode.Copy); ushort r = 0; LongIntBase Q = new LongIntBase(A.Base); LongMath.UShortDiv(A, (ushort)b, out Q, out r); return new LongIntBase(Q, ConstructorMode.Assign); }
internal static LongIntBase Divide(LongIntBase A, bool AisPositive, LongIntBase B, bool BisPositive, out bool resultSign) { if (A.IsZero()) { resultSign = true; return new LongIntBase(A); } LongIntBase Q = new LongIntBase(A.Base); LongIntBase R = new LongIntBase(B.Base); LongMath.Divide(A, B, out Q, out R, true, false); resultSign = !(AisPositive ^ BisPositive); return new LongIntBase(Q, ConstructorMode.Assign); }
internal static void Divide(LongIntBase A, LongIntBase B, out LongIntBase Q, out LongIntBase R, bool useResultMaxSize, bool useRemainingMaxSize) { if (B.IsZero()) throw new DivideByZeroException("Cannot divide by zero!"); int Base = (int)A.Base; if (LongMath.Less(A, B)) { Q = new LongIntBase(A.Base, A.CoefLength); R = new LongIntBase(A); return; } if (B.Size == 1) { ushort tempR = 0; R = new LongIntBase(A.Base, B.CoefLength); UShortDiv(A, B[0], out Q, out tempR); R[0] = tempR; R.Size = 1; return; } //LongIntBase A = new LongIntBase(inputA, (uint)inputA.Size + 1); //LongIntBase B = new LongIntBase(inputB, (uint)inputB.Size + 1); Q = new LongIntBase(A.Base, (useResultMaxSize ? A.CoefLength : (uint)A.Size + 1) ); R = new LongIntBase(B.Base, (useRemainingMaxSize ? B.CoefLength : (uint)B.Size + 1) ); /* * create temporaty LongNUmber U, that is * equivalent to A * Maximum U size is greater than A size, * if we will advance A while normalizing */ LongIntBase U = new LongIntBase(A, (uint)A.Size + 1); //U[A.Size] = 0; int n = B.Size; int m = U.Size - B.Size; int uJ, vJ, i; long temp1, temp2, temp; //normalization coeficient int scale; //guessed number for remaining long qGuess, r; //carries int borrow, carry; scale = (Base / ((int)B[n - 1] + 1)); if (scale > 1) { UShortMulSafe(ref U, (ushort)scale); UShortMulSafe(ref B, (ushort)scale); } /* * Main loop in dividing * Every iteration gets next remaining digit * vJ - current shift from U, that is used for substraction * (index of next digit in result) * uJ - index of current U digit */ for (vJ = m, uJ = n + vJ; vJ >= 0; --vJ, --uJ) { long numerator = U[uJ]*(long)Base + (long)U[uJ - 1]; qGuess = numerator / B[n - 1]; r = numerator - qGuess*B[n - 1]; while (r < Base) { temp2 = B[n - 2]*qGuess; temp1 = r*Base + U[uJ - 2]; if ((temp2 > temp1) || (qGuess == Base)) { --qGuess; r += B[n - 1]; } else break; } /* * Now qGuess is correct part or is advanced with 1 to q * Calculate divisor B, multiplied on qGuess from U * from position vJ + i */ carry = 0; borrow = 0; //LongIntBase uShift = U; //unsigned short *uShift = u + vJ; //looping on B digits for (i = 0; i < n; ++i) { //try to get digit of product B*qGuess temp1 = B[i]*qGuess + carry; carry = (int)(temp1 / Base); temp1 -= ((long)carry*Base); //substract it from U temp2 = U[i + vJ] - temp1 + borrow; if (temp2 < 0) { U[i + vJ] = (ushort)(temp2 + Base); borrow = -1; } else { U[i + vJ] = (ushort)temp2; borrow = 0; } } /* * maybe, B that is multiplied on qQuess became bigger * if yes, after multiplying carry was unused * it must be substracted also */ temp2 = U[i + vJ] - carry + borrow; if (temp2 < 0) { U[i + vJ] = (ushort)(temp2 + Base); borrow = -1; } else { U[i + vJ] = (ushort)temp2; borrow = 0; } //if division was ok, than if (borrow == 0) { Q[vJ] = (ushort)qGuess; } else { Q[vJ] = (ushort)(qGuess - 1); //add one substraction carry = 0; for (i = 0; i < n; ++i) { temp = U[i + vJ] + B[i] + carry; if (temp >= Base) { U[i + vJ] = (ushort)(temp - Base); carry = 1; } else { U[i + vJ] = (ushort)temp; carry = 0; } } U[i + vJ] = (ushort)(U[i + vJ] + carry - Base); } i = U.Size - 1; if (i > 0) while (U[i] == 0) { --i; if (i == 0) break; } U.Size = i + 1; } if (m > 0) while (Q[m] == 0) { --m; if (m == 0) break; } Q.Size = m + 1; if (scale > 1) { ushort junk = 0; UShortDivSafe(B, (ushort)scale, ref B, ref junk); LongIntBase tempR = null; UShortDiv(U, (ushort)scale, out tempR, out junk); R = new LongIntBase(tempR, (useRemainingMaxSize ? LongIntBase.MaxRange : (uint)tempR.Size + 1)); } else R.AssignBase(U);// = U; }