internal static bool Greater(LongIntBase A, LongIntBase B) { if (A.Base != B.Base) throw new DifferentBasesException("Attempt to compare two numbers with different bases!"); if (A.Size < B.Size) return false; if (A.Size > B.Size) return true; int i = A.Size - 1; while (A[i] == B[i]) { --i; if (i < 0) break; } if (i < 0) return false; return (A[i] > B[i]); }
internal static LongIntBase Add(LongIntBase A, LongIntBase B) { LongIntBase What = A, To = B; if (A.Size < B.Size) { What = B; To = A; } LongIntBase C = new LongIntBase(What.Base, System.Math.Max(What.CoefLength, To.CoefLength)); int Base = (int)What.Base; int carry = 0; int temp; int i; for (i = 0; i < To.Size; ++i) { temp = (int)What[i] + (int)To[i] + carry; if (temp >= Base) { C[i] = (ushort)(temp - Base); carry = 1; } else { C[i] = (ushort)temp; carry = 0; } } for (; i < What.Size; ++i) { temp = What[i] + carry; if (temp >= Base) { C[i] = (ushort)(temp - Base); carry = 1; } else { C[i] = (ushort)temp; carry = 0; } } if (carry != 0) { C[i] = (ushort)carry; C.Size = What.Size + 1; } else C.Size = What.Size; return C; }
public static void Divide(ULongIntD A, ULongIntD B, out ULongIntD Q, out ULongIntD R) { LongIntBase QNumber = new LongIntBase(A.Base); LongIntBase RNumber = new LongIntBase(B.Base); LongMath.Divide(A, B, out QNumber, out RNumber, true, true); Q = new ULongIntD(QNumber, ConstructorMode.Assign); R = new ULongIntD(RNumber, ConstructorMode.Assign); }
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, LongIntBase B) { if (A.Base != B.Base) return false; if (A.Size != B.Size) return false; int i = 0; while (A[i] == B[i]) { ++i; if (i >= A.Size) break; } return (i == A.Size); }
internal static LongIntBase Add(LongIntBase A, ushort b) { LongIntBase C = new LongIntBase(A); uint Base = A.Base; int index = 0; uint carry = 0; uint temp = (uint)C[0] + (uint)b; if (temp >= Base) { C[0] = (ushort)(temp - Base); carry = 1; } else { C[0] = (ushort)temp; carry = 0; } ++index; while (carry != 0) { temp = C[index] + carry; if (temp >= Base) { C[index] = (ushort)(temp - Base); carry = 1; } else { C[index] = (ushort)temp; carry = 0; } ++index; } if (index > A.Size) C.Size = index; else C.Size = A.Size; return C; }
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 bool Greater(LongIntBase A, ushort b) { LongIntBase temp = new LongIntBase(b, A.Base, 2); return Greater(A, temp); }
internal static void UShortMulSafe(ref LongIntBase A, ushort B) { uint Base = A.Base; int i = 0; long temp, carry = 0; long b = B; for (i = 0; i < A.Size; ++i) { temp = A[i]*b + carry; carry = temp / Base; A[i] = (ushort)(temp - (carry*Base)); } if (carry != 0) { A[i] = (ushort)carry; A.Size++; } }
internal static LongIntBase UShortMul(LongIntBase A, ushort B) { LongIntBase C = new LongIntBase(A.Base, A.CoefLength + 1); uint Base = A.Base; int i = 0; long temp, carry = 0; long b = B; for (i = 0; i < A.Size; ++i) { temp = A[i]*b + carry; carry = temp / Base; C[i] = (ushort)(temp - (carry*Base)); } if (carry != 0) { C[i] = (ushort)carry; C.Size = A.Size + 1; } else C.Size = A.Size; return C; }
internal static LongIntBase Multiply(LongIntBase A, LongIntBase B) { LongIntBase C = new LongIntBase(A.Base, System.Math.Max(A.CoefLength, B.CoefLength) + 1); uint Base = A.Base; int i, j; long temp, carry; for (i = 0; i < A.Size; ++i) { carry = 0; for (j = 0; j < B.Size; ++j) { temp = A[i]; temp *= B[j]; temp += C[i + j] + carry; carry = temp / Base; C[i + j] = (ushort)(temp - (carry * Base)); } C[i + j] = (ushort)carry; } i = A.Size + B.Size - 1; if (i > 0) while (C[i] == 0) { --i; if (i == 0) break; } C.Size = i + 1; return C; }
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 InnerPower(LongIntBase A, ulong n) { LongIntBase X = new LongIntBase(A); LongIntBase R = new LongIntBase(A.Base, X.CoefLength); R[0] = 1; while (n != 0) { if ((n & 1) == 1) R = Multiply(R, X); n >>= 1; X = InnerSqr(X); } return R; }
internal static bool Less(LongIntBase A, bool AisPositive, short b) { bool bSign = (b >= 0); if (b < 0) b *= -1; if (AisPositive == bSign) { if (AisPositive) return LongMath.Less(A, (ushort)b); else return LongMath.Greater(A, (ushort)b); } if (AisPositive) return false; return true; }
internal static LongIntBase SubstractSafe(LongIntBase From, ushort What) { LongIntBase C = new LongIntBase(From); int Base = (int)From.Base; int i = 0; int carry = 0; int temp = From[0] - (int)What; if (temp < 0) { C[0] = (ushort)(temp + Base); carry = -1; } else { C[0] = (ushort)temp; carry = 0; } ++i; while (carry != 0) { temp = From[i] + carry; if (temp < 0) { C[i] = (ushort)(temp + Base); carry = -1; } else { C[i] = (ushort)temp; carry = 0; } ++i; } i = From.Size - 1; if (i > 0) while (C[i] == 0) { --i; if (i == 0) break; } C.Size = i + 1; return C; }
internal static LongIntBase SubstractSafe(LongIntBase From, LongIntBase What) { LongIntBase C = new LongIntBase(From.Base, System.Math.Max(From.CoefLength, What.CoefLength)); uint Base = From.Base; int i; int temp; int carry = 0; for (i = 0; i < What.Size; ++i) { temp = From[i] - What[i] + carry; if (temp < 0) { C[i] = (ushort)(temp + Base); carry = -1; } else { C[i] = (ushort)temp; carry = 0; } } for (; i < From.Size; ++i) { temp = From[i] + carry; if (temp < 0) { C[i] = (ushort)(temp + Base); carry = -1; } else { C[i] = (ushort)temp; carry = 0; } } i = From.Size - 1; if (i > 0) while (C[i] == 0) { --i; if (i == 0) break; } C.Size = i + 1; return C; }
internal static LongIntBase Substract(LongIntBase A, bool AisPositive, short b, out bool resultSign) { bool BisPositive = (b >= 0); if (b < 0) b *= -1; if (AisPositive != BisPositive) { // (A + B) or (-A - B) == -(A + B) resultSign = AisPositive; return new LongIntBase(LongMath.Add(A, (ushort)b), ConstructorMode.Assign); } else { /* * Possible variants: * (A - B) == * * A > B -> A - B * A == B -> 0 * A < B -> -(B - A) */ resultSign = true; if (LongMath.Equal(A, (ushort)b)) return new LongIntBase(0, A.Base, LongIntBase.MaxRange); if (AisPositive == false) resultSign = !resultSign; if (Greater(A, (ushort)b)) return new LongIntBase(LongMath.SubstractSafe(A, (ushort)b), ConstructorMode.Assign); resultSign = false; if (AisPositive == false) resultSign = !resultSign; return new LongIntBase(LongMath.SubstractSafe((ushort)b, A), ConstructorMode.Assign); } }
internal static LongIntBase Substract(LongIntBase A, bool AisPositive, LongIntBase B, bool BisPositive, out bool resultSign) { if (AisPositive != BisPositive) { // (A + B) or (-A - B) == -(A + B) resultSign = AisPositive; return new LongIntBase(LongMath.Add(A, B), ConstructorMode.Assign); } else { /* * Possible variants: * (A - B) == * * A > B -> A - B * A == B -> 0 * A < B -> -(B - A) */ resultSign = true; if (LongMath.Equal(A, B)) return new LongIntBase(0, A.Base, LongIntBase.MaxRange); resultSign = AisPositive; if (Greater(A, B)) return new LongIntBase(LongMath.SubstractSafe(A, B), ConstructorMode.Assign); resultSign = !AisPositive; return new LongIntBase(LongMath.SubstractSafe(B, A), ConstructorMode.Assign); } }
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 bool Less(LongIntBase A, ushort b) { LongIntBase temp = new LongIntBase(b, A.Base, 2); return Less(A, temp); }
internal static bool Less(LongIntBase A, bool AisPositive, LongIntBase B, bool BisPositive) { if (AisPositive == BisPositive) { if (AisPositive) return LongMath.Less(A, B); else return LongMath.Greater(A, B); } if (AisPositive) return false; return true; }
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 UShortDiv(LongIntBase A, ushort B, out LongIntBase Q, out ushort R) { // division with new result uint Base = A.Base; Q = new LongIntBase(A.Base, A.CoefLength); long r = 0; int i; long temp, b = B; for (i = A.Size - 1; i >= 0; --i) { temp = (r * Base) + A[i]; Q[i] = (ushort)(temp / b); r = temp - Q[i]*b; } //r - remaining from division R = (ushort)r; i = A.Size - 1; if (i > 0) while (Q[i] == 0) { --i; if (i == 0) break; } Q.Size = i + 1; }
internal static void UShortDivSafe(LongIntBase A, ushort B, ref LongIntBase Q, ref ushort R) { // division in place uint Base = A.Base; long r = 0; int i; long temp, b = B; for (i = A.Size - 1; i >= 0; --i) { temp = (r * Base) + A[i]; Q[i] = (ushort)(temp / b); r = temp - Q[i]*b; } //r - remaining from division R = (ushort)r; i = A.Size - 1; if (i > 0) while (Q[i] == 0) { --i; if (i == 0) break; } Q.Size = i + 1; }
internal static void Increment(ref LongIntBase A, ushort incrementValue) { int index = 0; int carry = 0; uint Base = A.Base; int temp = A[0] + incrementValue + carry; if (temp >= Base) { A[0] = (ushort)(temp - Base); carry = 1; } else { A[0] = (ushort)temp; carry = 0; } ++index; while (carry != 0) { temp = A[index] + carry; if (temp >= Base) { A[index] = (ushort)(temp - Base); carry = 1; } else { A[index] = (ushort)temp; carry = 0; } ++index; } if (index > A.Size) A.Size = index; }
internal static LongIntBase Mod(LongIntBase A, LongIntBase B) { LongIntBase Q = new LongIntBase(A.Base); LongIntBase R = new LongIntBase(B.Base); LongMath.Divide(A, B, out Q, out R, false, true); return new LongIntBase(R, ConstructorMode.Assign); }
internal static LongIntBase SubstractSafe(ushort From, LongIntBase What) { LongIntBase C = new LongIntBase(What); int temp = From - C[0]; C[0] = (ushort)temp; return C; }
internal static ushort Mod(LongIntBase A, ushort b) { ushort r = 0; LongIntBase Q = new LongIntBase(A.Base); LongMath.UShortDiv(A, b, out Q, out r); return r; }