Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigInteger Parse Octal String?

In Java, I could do

//Parsing Octal String
BigInteger b = new BigInteger("16304103460644701340432043410021040424210140423204",8);

Then format it as I pleased

b.toString(2); //2 for binary
b.toString(10); //10 for decimal
b.toString(16); //16 for hexadecimal

C#'s BigInteger offers the formatting capabilities shown above but I can't seem to find a way to parse BIIIG (greater than 64 bit, unsigned) Octal values.

like image 788
snotyak Avatar asked Dec 26 '12 12:12

snotyak


2 Answers

This may not be the most efficient solution, but if performance is not a priority, you can construct the BigInteger manually:

string s = "16304103460644701340432043410021040424210140423204";
BigInteger bi = s.Aggregate(new BigInteger(), (b, c) => b * 8 + c - '0');

The above solution also works for any base not greater than 10; just replace the 8 in the above code with your required base.

Edit: For hexadecimal numbers, you should use the Parse method. Prepend with 0 if your number should be interpreted as positive even if its first character is 8F.

string s = "0F20051C5E45F4FD68F8E58905A133BCA";
BigInteger bi = BigInteger.Parse(s, NumberStyles.HexNumber);
like image 110
Douglas Avatar answered Oct 22 '22 12:10

Douglas


A simple implementation for hex (and all bases up to 16); expand it by adding characters to the string constant (credit where credit is due; this is based on Douglas's answer):

private const string digits = "0123456789ABCDEF";
private readonly Dictionary<char, BigInteger> values
    = digits.ToDictionary(c => c, c => (BigInteger)digits.IndexOf(c));
public BigInteger ParseBigInteger(string value, BigInteger baseOfValue)
{
    return value.Aggregate(
        new BigInteger,
        (current, digit) => current * baseOfValue + values[digit]);
}

It is likely that arithmetic where one operand is an int is faster than if both operands are BigInteger. In that case:

private readonly Dictionary<char, int> values
    = digits.ToDictionary(c => c, c => digits.IndexOf(c));
public BigInteger ParseBigInteger(string value, int baseOfValue)
{
    return value.Aggregate(
        new BigInteger,
        (current, digit) => current * baseOfValue + values[digit]);
}
like image 28
phoog Avatar answered Oct 22 '22 12:10

phoog