示例#1
0
        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());
        }
示例#2
0
        public static OmgNum Div(OmgNum left, OmgNum right, OmgNum mod)
        {
            var divMod = DivMod(left, right, mod);

            divMod.mod.Release();
            return(divMod.div);
        }
示例#3
0
 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));
 }
示例#4
0
        private static OmgNum _Negative(RawNum raw)
        {
            var result = new OmgNum(raw);

            result.IsNegative = true;

            return(result);
        }
示例#5
0
        private static OmgNum _Positive(RawNum raw)
        {
            var result = new OmgNum(raw);

            result.IsNegative = false;

            return(result);
        }
示例#6
0
        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);
        }
示例#7
0
        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)));
        }
示例#8
0
        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));
        }
示例#9
0
        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);
        }
示例#10
0
        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)));
        }
示例#11
0
        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);
        }
示例#12
0
 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));
 }
示例#13
0
        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();
        }
示例#14
0
        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)));
        }
示例#15
0
 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)));
 }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#19
0
        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);
        }
示例#20
0
        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);
        }
示例#21
0
        public static OmgNum Copy(this OmgNum num)
        {
            var copy = new OmgNum(num);

            return(copy);
        }
示例#22
0
        public static string EncodeToBase64(this OmgNum num)
        {
            var bytes = num.ToByteArray();

            return(Convert.ToBase64String(bytes));
        }
示例#23
0
 public OmgNum(OmgNum other)
 {
     this.Raw = OmgPool.GetRawZero();
     this.Raw.CopyFrom(other.Raw);
     this.IsNegative = other.IsNegative;
 }
示例#24
0
 public Eq(OmgNum a, OmgNum b, OmgNum m)
 {
     A = a; B = b; M = m;
 }
示例#25
0
 public static bool Less(OmgNum left, OmgNum right, OmgNum mod)
 {
     return(_WithModded(left, right, mod, (l, r) => Less(l, r)));;
 }
示例#26
0
 private static OmgNum _AbsShell(OmgNum number)
 {
     return(new OmgNum(number.Raw));
 }
示例#27
0
 public static OmgNum Mod(OmgNum left, OmgNum right)
 {
     return(m_divider.Mod(left, right));
 }
示例#28
0
 public static OmgNum Multiply(OmgNum left, OmgNum right, OmgNum mod)
 {
     return(_BinaryModded(left, right, mod, Multiply));
 }
示例#29
0
 public static OmgNum Subtract(OmgNum left, OmgNum right, OmgNum mod)
 {
     return(_BinaryModded(left, right, mod, Subtract));
 }
示例#30
0
 public static OmgNum Add(OmgNum left, OmgNum right, OmgNum mod)
 {
     return(_BinaryModded(left, right, mod, Add));
 }