7

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.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
snotyak
  • 3,709
  • 6
  • 35
  • 52

2 Answers2

13

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);
Douglas
  • 53,759
  • 13
  • 140
  • 188
  • I'm not quite sure what's going on. Would there be a simple way to add implementation for hex? (to parse big hex strings) – snotyak Dec 26 '12 at 13:19
  • @BackpackOnHead why would you add an implementation for hex when you can use the built-in Parse method? It's very unlikely that you'll improve over Microsoft's implementation. – phoog Dec 26 '12 at 14:11
  • @phoog - I asked this then I jumped into bed for a bit and facepalmed, haha. – snotyak Dec 26 '12 at 18:43
3

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]);
}
phoog
  • 42,068
  • 6
  • 79
  • 117