public static byte[] ToByteArray(this OmgNum num) { if (num.IsZero()) { return(new byte[1]); } var byteList = new List <byte>(); for (int i = 0; i < num.Size; i++) { UInt32 digit = num.Raw.Digits[i]; byteList.Add((byte)(digit & ((1 << 8) - 1))); digit >>= 8; byteList.Add((byte)(digit & ((1 << 8) - 1))); } while (byteList.Count > 0 && byteList[byteList.Count - 1] == 0) { byteList.RemoveAt(byteList.Count - 1); } byteList.Add((num.IsNegative) ? (byte)1 : (byte)0); return(byteList.ToArray()); }
public static OmgNum Div(OmgNum left, OmgNum right, OmgNum mod) { var divMod = DivMod(left, right, mod); divMod.mod.Release(); return(divMod.div); }
public static (OmgNum div, OmgNum mod) DivMod(OmgNum left, OmgNum right) { if (right.IsZero()) { throw new OmgFailException("division by zero"); } return(m_divider.DivMod(left, right)); }
private static OmgNum _Negative(RawNum raw) { var result = new OmgNum(raw); result.IsNegative = true; return(result); }
private static OmgNum _Positive(RawNum raw) { var result = new OmgNum(raw); result.IsNegative = false; return(result); }
public static OmgNum Pow(OmgNum left, OmgNum right, OmgNum mod) { OmgNum moddedLeft = Mod(left, mod); OmgNum moddedPow = _Positive(m_multiplier.Pow(left.Raw, right.Raw, mod.Raw)); moddedLeft.Release(); return(moddedPow); }
public static OmgNum Multiply(OmgNum left, OmgNum right) { if (left.IsNegative == right.IsNegative) { return(_Positive(m_multiplier.Multiply(left.Raw, right.Raw))); } return(_Negative(m_multiplier.Multiply(left.Raw, right.Raw))); }
public static bool Equal(OmgNum left, OmgNum right) { if (left.IsNegative != right.IsNegative) { return(left.IsZero() && right.IsZero()); } return(m_comparer.Equal(left.Raw, right.Raw)); }
private static OmgNum _BinaryModded(OmgNum left, OmgNum right, OmgNum mod, Func <OmgNum, OmgNum, OmgNum> binFunc) { OmgNum res = _WithModded(left, right, mod, binFunc); OmgNum resModded = Mod(res, mod); res.Release(); return(resModded); }
public static OmgNum Pow(OmgNum left, OmgNum right) { bool evenPower = (right.Raw.Digits[0] & 1) == 0; if (evenPower || !left.IsNegative) { return(_Positive(m_multiplier.Pow(left.Raw, right.Raw))); } return(_Negative(m_multiplier.Pow(left.Raw, right.Raw))); }
public static (OmgNum div, OmgNum mod) DivMod(OmgNum left, OmgNum right, OmgNum mod) { var res = _WithModded(left, right, mod, (l, r) => DivMod(l, r)); var divModded = Mod(res.div, mod); var modModded = Mod(res.mod, mod); res.div.Release(); res.mod.Release(); return(divModded, modModded); }
public static bool Less(OmgNum left, OmgNum right) { if (left.IsNegative != right.IsNegative) { return(left.IsNegative); } if (!left.IsNegative && !right.IsNegative) { return(m_comparer.Less(left.Raw, right.Raw)); } return(m_comparer.Less(right.Raw, left.Raw)); }
public static OmgNum Random(OmgNum min, OmgNum max) { if (Less(max, min)) { return(min.Copy()); } if (!min.IsNegative && !max.IsNegative) { return(_Positive(m_randomizer.GetRandom(min.Raw, max.Raw))); } throw new NotImplementedException(); }
public static OmgNum Sqrt(OmgNum left) { if (left.IsZero()) { return(OmgPool.GetZero()); } if (left.IsNegative) { throw new OmgFailException("can't square root negative number"); } return(_Positive(m_rooter.Sqrt(left.Raw))); }
public static OmgNum Subtract(OmgNum left, OmgNum right) { if (!left.IsNegative && !right.IsNegative || left.IsNegative && right.IsNegative ) { return(m_subtracter.Subtract(left, right)); } if (!left.IsNegative && right.IsNegative) { return(_Positive(m_adder.Add(left.Raw, right.Raw))); } return(_Negative(m_adder.Add(left.Raw, right.Raw))); }
public static OmgNum ToOmgNum(this string strNumber, uint _base = 10) { OmgNum result = OmgPool.GetZero(); RawNum rawNumber = result.Raw; result.IsNegative = StartsWithMinus(strNumber); m_converter.InputBase = _base; m_converter.Input = ParseDigits(strNumber); m_converter.Output = rawNumber.Digits; m_converter.Convert(); return(result); }
public static bool TryInverseByMod(OmgNum left, OmgNum mod, out OmgNum inverce) { RawNum gcd = m_gcder.ExtendedGcd(left.Raw, mod.Raw, out OmgNum x, out OmgNum y); y.Release(); bool result = (gcd.Size == 1) && (gcd.Digits[0] == 1); OmgPool.ReleaseNumber(gcd); inverce = (result) ? Mod(x, mod) : null; x.Release(); return(result); }
public static OmgNum FromByteArray(byte[] bytes) { RawNum num = OmgPool.GetRawZero(); for (int i = 0; i < bytes.Length - 1; i += 2) { byte least = bytes[i]; byte elder = (i + 1 < bytes.Length - 1) ? bytes[i + 1] : (byte)0; num.Digits.Add((UInt32)(least | elder << 8)); } OmgNum decoded = new OmgNum(num); decoded.IsNegative = bytes[bytes.Length - 1] > 0; return(decoded); }
private static T _WithModded <T> (OmgNum left, OmgNum right, OmgNum mod, Func <OmgNum, OmgNum, T> func) { if (mod == null) { throw new OmgFailException("mod is null"); } if (mod.IsZero()) { throw new OmgFailException("mod is zero"); } var leftModded = Mod(left, mod); var rightModded = Mod(right, mod); T result = func(leftModded, rightModded); leftModded.Release(); rightModded.Release(); return(result); }
public static OmgNum ToOmgNum(this int number) { OmgNum result = OmgPool.GetZero(); if (number == 0) { return(result); } RawNum rawNumber = result.Raw; result.IsNegative = number < 0; UInt32 absNum = (UInt32)Math.Abs(number); rawNumber.Digits.Add((UInt16)(absNum & ((1 << 16) - 1))); if ((absNum >> 16) > 0) { rawNumber.Digits.Add((UInt16)(absNum >> 16)); } return(result); }
public static OmgNum Copy(this OmgNum num) { var copy = new OmgNum(num); return(copy); }
public static string EncodeToBase64(this OmgNum num) { var bytes = num.ToByteArray(); return(Convert.ToBase64String(bytes)); }
public OmgNum(OmgNum other) { this.Raw = OmgPool.GetRawZero(); this.Raw.CopyFrom(other.Raw); this.IsNegative = other.IsNegative; }
public Eq(OmgNum a, OmgNum b, OmgNum m) { A = a; B = b; M = m; }
public static bool Less(OmgNum left, OmgNum right, OmgNum mod) { return(_WithModded(left, right, mod, (l, r) => Less(l, r)));; }
private static OmgNum _AbsShell(OmgNum number) { return(new OmgNum(number.Raw)); }
public static OmgNum Mod(OmgNum left, OmgNum right) { return(m_divider.Mod(left, right)); }
public static OmgNum Multiply(OmgNum left, OmgNum right, OmgNum mod) { return(_BinaryModded(left, right, mod, Multiply)); }
public static OmgNum Subtract(OmgNum left, OmgNum right, OmgNum mod) { return(_BinaryModded(left, right, mod, Subtract)); }
public static OmgNum Add(OmgNum left, OmgNum right, OmgNum mod) { return(_BinaryModded(left, right, mod, Add)); }