BigIntegerHelper.cs

BigInteger Helper Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
public static class BigIntegerHelper
{
    private static readonly BigInteger Ten   = new BigInteger(10);
    private static readonly BigInteger Three = new BigInteger(3);
    private static readonly BigInteger ONE   = new BigInteger(1);
    private static readonly BigInteger Two   = new BigInteger(2);
    public static BigInteger BigIntegerBase2(this string binaryValue)
    {
        BigInteger res = 0;
        if (binaryValue.Count(b => b == '1') + binaryValue.Count(b => b == '0') != binaryValue.Length) return res;
        foreach (var c in binaryValue)
        {
            res <<= 1;
            res +=  c == '1' ? 1 : 0;
        }
        return res;
    }
    public static BigInteger BigIntegerBase16(this string hexNumber)
    {
        if (string.IsNullOrEmpty(hexNumber))
            throw new Exception("Error: hexNumber cannot be either null or have a length of zero.");
        if (!hexNumber.ContainsOnly("0123456789abcdefABCDEFxX"))
            throw new Exception("Error: hexNumber cannot contain characters other than 0-9,a-f,A-F, or xX");
        hexNumber = hexNumber.ToUpper();
        if (hexNumber.IndexOf("0X", StringComparison.OrdinalIgnoreCase) != -1)
            hexNumber = hexNumber.Substring(2);
        var bytes = Enumerable.Range(0, hexNumber.Length)
            .Where(x => x % 2 == 0)
            .Select(x => Convert.ToByte(hexNumber.Substring(x, 2), 16))
            .ToArray();
        return new BigInteger(bytes.Concat(new byte[] {0}).ToArray());
    }
    public static BigInteger BigIntegerBase10(this string str)
    {
        var number = new BigInteger();
        int i;
        for (i = 0; i < str.Length; i++)
            if (str[i] >= '0' && str[i] <= '9')
                number = number * Ten + long.Parse(str[i].ToString());
        return number;
    }
    private static byte[] HexToByteArray(this string hex)
    {
        return Enumerable.Range(0, hex.Length)
            .Where(x => x % 2 == 0)
            .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
            .ToArray();
    }
    public static BigInteger ToBigInteger(this char ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this byte ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this sbyte ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this short ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this ushort ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this int ul)
    {
        return new BigInteger((ulong) ul);
    }
    public static BigInteger ToBigInteger(this uint ul)
    {
        return new BigInteger((ulong) ul);
    }
    public static BigInteger ToBigInteger(this long ul)
    {
        return new BigInteger((ulong) ul);
    }
    public static BigInteger ToBigInteger(this ulong ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ModPow(this BigInteger n, BigInteger e, BigInteger m)
    {
        var s = ONE;
        var u = e;
        while (!u.IsZero)
        {
            if ((u & ONE) == 1)
                s = s * n % m;
            u >>= 1;
            n =   n * n % m;
        }
        return s;
    }
    public static double ConfidenceToProbability(int confidence)
    {
        var a = Two.Pow(confidence);
        var b = 100.0 / (double) a;
        var c = 100.0 - b;
        return c;
    }
    public static BigInteger Pow(this BigInteger n, BigInteger exp)
    {
        var y = ONE;
        var z = n;
        while (exp != 0)
        {
            if ((exp & 0x1) == 1)
                y *= z;
            exp >>= 1;
            if (exp != 0)
                z *= z;
        }
        return y;
    }
    public static List<BigInteger> GetFactors(this BigInteger n)
    {
        var Factors = new List<BigInteger>();
        var s       = n.Sqrt();
        var a       = Three;
        while (a < s)
        {
            if (n % a == 0)
            {
                Factors.Add(a);
                if (a * a != n)
                    Factors.Add(n / a);
            }
            a += 2;
        }
        return Factors;
    }
    public static BigInteger Gcd(this BigInteger a, BigInteger b)
    {
        while (b > BigInteger.Zero)
        {
            var r = a % b;
            a = b;
            b = r;
        }
        return a;
    }
    public static BigInteger Lcm(this BigInteger a, BigInteger b)
    {
        return a * b / a.Gcd(b);
    }
    public static BigInteger BigIntegerBase2(this BigInteger bi, string binaryValue)
    {
        bi = BigInteger.Zero;
        if (binaryValue.Count(b => b == '1') + binaryValue.Count(b => b == '0') != binaryValue.Length)
            return bi;
        foreach (var c in binaryValue)
        {
            bi <<= 1;
            bi +=  c == '1' ? 1 : 0;
        }
        return bi;
    }
    public static int GetByteWidth(this BigInteger n)
    {
        return GetBitWidth(n) >> 3;
    }
    public static int GetBitWidth(this BigInteger n)
    {
        BigInteger bitWidth = 1;
        var        v        = n;
        while ((v >>= 1) > 0)
            bitWidth++;
        if (bitWidth < 8)
            bitWidth = 8;
        return (int) bitWidth;
    }
    public static BigInteger GetMaxValue(this BigInteger bi, int bitLength)
    {
        if (bi.Sign == -1)
            bitLength -= 1;
        return BigInteger.One << bitLength;
    }
    public static BigInteger GetMaxValue(this BigInteger bi)
    {
        var bitLength = bi.GetBitWidth();
        if (bi.Sign == -1)
            bitLength -= 1;
        return (BigInteger.One << bitLength) - BigInteger.One;
    }
    public static BigInteger GetMaxValueBitWidth(int bitLength)
    {
        return (BigInteger.One << bitLength) - BigInteger.One;
    }
    public static BigInteger BigIntegerBase16(this BigInteger bi, string hexNumber)
    {
        if (string.IsNullOrEmpty(hexNumber))
            throw new Exception("Error: hexNumber cannot be either null or have a length of zero.");
        if (!hexNumber.ContainsOnly("0123456789abcdefABCDEFxX"))
            throw new Exception("Error: hexNumber cannot contain characters other than 0-9,a-f,A-F, or xX");
        hexNumber = hexNumber.ToUpper();
        if (hexNumber.IndexOf("0X", StringComparison.OrdinalIgnoreCase) != -1)
            hexNumber = hexNumber.Substring(2);
        var bytes = Enumerable.Range(0, hexNumber.Length)
            .Where(x => x % 2 == 0)
            .Select(x => Convert.ToByte(hexNumber.Substring(x, 2), 16))
            .ToArray();
        return new BigInteger(bytes.Concat(new byte[] {0}).ToArray());
    }
    public static BigInteger BigIntegerBase10(this BigInteger bi, string str)
    {
        if (str[0] == '-' || str.IndexOf('.') != -1)
            throw new Exception($"Invalid numeric string. Only positive numbers and whole numbers are allowed. Value={str}");
        var number = new BigInteger();
        int i;
        for (i = 0; i < str.Length; i++)
            if (str[i] >= '0' && str[i] <= '9')
                number = number * Ten + long.Parse(str[i].ToString());
        return number;
    }
    public static string ToBinaryString(this BigInteger bigint)
    {
        var bytes  = bigint.ToByteArray();
        var index  = bytes.Length - 1;
        var base2  = new StringBuilder(bytes.Length * 8);
        var binary = Convert.ToString(bytes[index], 2);
        if (binary[0] != '0' && bigint.Sign == 1) base2.Append('0');
        base2.Append(binary);
        for (index--; index >= 0; index--)
            base2.Append(Convert.ToString(bytes[index], 2).PadLeft(8, '0'));
        return base2.ToString();
    }
    public static string ToHexString(this BigInteger bi)
    {
        var bytes = bi.ToByteArray();
        var sb    = new StringBuilder();
        foreach (var b in bytes)
        {
            var hex = b.ToString("X2");
            sb.Append(hex);
        }
        return sb.ToString();
    }
    public static string ToOctalString(this BigInteger bigint)
    {
        var bytes         = bigint.ToByteArray();
        var index         = bytes.Length - 1;
        var base8         = new StringBuilder((bytes.Length / 3 + 1) * 8);
        var rem           = bytes.Length % 3;
        if (rem == 0) rem = 3;
        var base0         = 0;
        while (rem != 0)
        {
            base0 <<= 8;
            base0 +=  bytes[index--];
            rem--;
        }
        var octal = Convert.ToString(base0, 8);
        if (octal[0] != '0' && bigint.Sign == 1) base8.Append('0');
        base8.Append(octal);
        while (index >= 0)
        {
            base0 = (bytes[index] << 16) + (bytes[index - 1] << 8) + bytes[index - 2];
            base8.Append(Convert.ToString(base0, 8).PadLeft(8, '0'));
            index -= 3;
        }
        return base8.ToString();
    }
    /// <summary>
    ///     Approximation
    /// </summary>
    public static BigInteger Sqrt(this BigInteger n)
    {
        var q = BigInteger.One << ((int) BigInteger.Log(n, 2) >> 1);
        var m = BigInteger.Zero;
        while (BigInteger.Abs(q - m) >= 1)
        {
            m = q;
            q = (m + n / m) >> 1;
        }
        return q;
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *