5

Currently I am using the Long integer type. I used the following to convert from/to binary/number:

Convert.ToInt64(BinaryString, 2); // Convert binary string of base 2 to number
Convert.ToString(LongNumber, 2); // Convert long number to binary string of base 2

Now the numbers I am using have exceeded 64 bit, so it has started using BigInteger. I can't seem to find the equivalent of the code above.

How can I convert from a BinaryString that have over 64bits to a BigInteger number and vice versa?


The references in the answer contains the answer I want, but I am having some trouble in the conversion from Number to Binary.

I have used the following code which is available in the first reference:

    public static string ToBinaryString(this BigInteger bigint)
    {
        var bytes = bigint.ToByteArray();
        var idx = bytes.Length - 1;

        // Create a StringBuilder having appropriate capacity.
        var base2 = new StringBuilder(bytes.Length * 8);

        // Convert first byte to binary.
        var binary = Convert.ToString(bytes[idx], 2);

        // Ensure leading zero exists if value is positive.
        if (binary[0] != '0' && bigint.Sign == 1)
        {
            base2.Append('0');
        }

        // Append binary string to StringBuilder.
        base2.Append(binary);

        // Convert remaining bytes adding leading zeros.
        for (idx--; idx >= 0; idx--)
        {
            base2.Append(Convert.ToString(bytes[idx], 2).PadLeft(8, '0'));
        }

        return base2.ToString();
    }

The result I got was wrong:

100001000100000000000100000110000100010000000000000000000000000000000000 ===>  2439583056328331886592
2439583056328331886592 ===> 0100001000100000000000100000110000100010000000000000000000000000000000000

If you put the resulted binary string under each other, you will notice that the conversion is correct and that the problem is that there is a leading zero from the left:

100001000100000000000100000110000100010000000000000000000000000000000000
0100001000100000000000100000110000100010000000000000000000000000000000000

I tried reading the explanation provided in the code and changing it, but no luck.

I was later able to solve it by changing the following in the code:

        // Ensure leading zero exists if value is positive.
        if (binary[0] != '0' && bigint.Sign == 1)
        {
            base2.Append('0');

            // Append binary string to StringBuilder.
            base2.Append(binary);
        }

4 Answers 4

6

Unfortunately, there is nothing built-in in the .NET framework.

Fortunately, the Stack Overflow community has already solved both problems:

Sign up to request clarification or add additional context in comments.

1 Comment

I updated the question. Please take a look at the problem i am facing
0

There is a good reference on MSDN about BigIntegers;

BigInteger Struct

Also there is a post to convert from binary to biginteger: Conversion of a binary representation stored in a list of integers (little endian) into a Biginteger

This example is from MSDN.

string positiveString = "91389681247993671255432112000000";
string negativeString = "-90315837410896312071002088037140000";
BigInteger posBigInt = 0;
BigInteger negBigInt = 0;

try {
   posBigInt = BigInteger.Parse(positiveString);
   Console.WriteLine(posBigInt);
}
catch (FormatException)
{
   Console.WriteLine("Unable to convert the string '{0}' to a BigInteger value.",
                     positiveString);
}

if (BigInteger.TryParse(negativeString, out negBigInt))
  Console.WriteLine(negBigInt);
else
   Console.WriteLine("Unable to convert the string '{0}' to a BigInteger value.",
                      negativeString);

// The example displays the following output:
//   9.1389681247993671255432112E+31
//   -9.0315837410896312071002088037E+34

2 Comments

Those are not strings of binary digits. The question is pretty specific to dealing with "string of base 2"
There is an answer in this post, is this what you want? stackoverflow.com/questions/22947412/…
0

This might be useful.

Usage:

string someString = "-1101010001"; // More examples: 1_1111_0101, +100101101
bool success = TryParseBinary(someString, out BigInteger outBigInt);

The Function:

static bool TryParseBinary(ReadOnlySpan<char> input, out BigInteger result)
{
    int inputLen = input.Length;

    byte[] bytes = new byte[(inputLen + 7) / 8];
    int outputBitPosition = 0; // The current bit we 
                               // are writing to.

    // If it starts with a '-' then set 
    // negative rawValue to zero.
    bool isNeg = input[0] == '-'; // 0x2D;

    // If starting with a - or + then 
    // set headPosition to 1.
    int headPosition = isNeg | input[0] == '+' ? 1 : 0;

    int tailPosition = inputLen - 1;
    for (; tailPosition >= headPosition; tailPosition--)
    {
        switch (input[tailPosition])
        {
            case '1':
                bytes[outputBitPosition >> 3] |= 
                    (byte)(1 << (outputBitPosition & 0x7));
                goto case '0';

            case '0':
                outputBitPosition++;
                break;

            // Allow commas, '_' (i.e., 1111_1111_0000), 
            // and spaces
            case ',' or '_' or ' ':  
                break;

            default:
                result = new BigInteger(0);
                return false; // Function was not successful - 
                              // unsupported char found
        }
    }

    // If the number is negative, let's perform 
    // two's complement: (1) invert the 
    // bits (2) add 1
    if (isNeg)
    {
        int byteCount = bytes.Length;

        //   (1) Invert the bits
        for (int i = 0; i < byteCount; i++)
        {
            bytes[i] ^= 0xff;
        }

        //   (2) Increment the LSB and increment more 
        //       significant bytes as needed.
        bytes[0]++;
        for (int i = 0; bytes[i] == 0; i++)
        {
            if (i + 1 >= byteCount)
            {
                break;
            }

            bytes[i + 1]++;
        }
    }

    result = new(bytes, !isNeg);

    // Return true if success. If no 0/1 bits 
    // found then return false.
    return outputBitPosition != 0;
}

Comments

0

Since .net9.0 you can do the following:

BigInteger.Parse("00001000", NumberStyles.AllowBinarySpecifier) // returns 8

Be careful with the first digit though. The parser assumes two's complement. So "1" will be parsed as -1. If you don't want this, you could just always prepend a "0" to your input:

BigInteger.Parse('0' + input, NumberStyles.AllowBinarySpecifier) // never negative

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.