public bool MillerRabin(Int64 n, Int64 accuracy = 100)
        {
            if (n < 1)
            {
                throw new ArgumentException("The number must be natural");
            }

            if (n == 1 || n == 2)
            {
                return(true);
            }

            if (n % 2 == 0)
            {
                return(false);
            }

            Tuple <Int64, Int64> tAnds = FindT(n);

            Random rnd = new Random();

            for (Int64 i = 1; i <= accuracy; ++i)
            {
                Int64 a = rnd.Next(2, (int)n - 2);
                Int64 x = BinaryMath.PowByModulo(a, tAnds.Item1, n);

                if (x == 1 || x == n - 1)
                {
                    continue;
                }

                bool isCont = false;
                for (Int64 j = 0; j < tAnds.Item2 - 1; ++j)
                {
                    x = (x * x) % n;
                    if (x == 1)
                    {
                        return(false);
                    }

                    if (x == n - 1)
                    {
                        isCont = true;
                    }
                }
                if (isCont)
                {
                    continue;
                }
                return(false);
            }
            return(true);
        }
        private Tuple <Int64, Int64> FindT(Int64 n)
        {
            Tuple <Int64, Int64> res;

            for (Int64 i = 60; i >= 1; --i)
            {
                if ((n - 1) % BinaryMath.Pow(2, i) == 0)
                {
                    return(new Tuple <Int64, Int64>((n - 1) / BinaryMath.Pow(2, i), i));
                }
            }
            return(null);
        }