ABC
ABC

Reputation: 181

Converting binary to decimal

I have a requirement where I am generating a binary number from a string say "111111" and converting it to a decimal number to store in database. Each digit (ie. 1/0) from this binary number signifies different access rights of user to different modules in the application. As and when the number of modules will increase, the number of digits in this binary number will also increase. By the time when the binary number reached to the length of 64, (ie. 64 times 1s), I was able to convert it to decimal number using

Int64 dec =Convert.ToInt64(binVal,2);

And it worked fine. But when the length increased to 65, it gave an OverFlow Exception : Value was either too large or too small for a UInt64. Can anyone suggest any possible solution where I can convert this binary number of 65 length to decimal or any other form to save it in database.

Thanks in Advance.

Upvotes: 0

Views: 3342

Answers (2)

Oleks
Oleks

Reputation: 32323

To convert a binary number of length 65 or more to decimal/whatever you'll have to write a method like this:

public BigInteger FromBinaryString(string binary)
{
    if (binary == null)
        throw new ArgumentNullException();
    if (!binary.All(c => c == '0' || c == '1'))
        throw new InvalidOperationException();

    BigInteger result = 0;
    foreach (var c in binary)
    {
        result <<= 1;
        result += (c - '0');
    }
    return result;
}

which uses System.Numerics.BigInteger structure to hold big numbers. Then you could explicitly convert it to decimal (or to a byte array) and store it in your database:

var bigInteger = FromBinaryString("100000000000000000000000000000000000000000000000000000000000000000");
// to decimal
var dec = (decimal)bigInteger;
// to byte array
var data = bigInteger.ToByteArray();

EDIT: If you're under NET 3.5, just use decimal instead of BigInteger (also replace left-shift operator << with the multiplication operator * for decimals):

public decimal FromBinaryString(string binary)
{
    if (binary == null)
        throw new ArgumentNullException();
    if (!binary.All(c => c == '0' || c == '1'))
        throw new InvalidOperationException();

    decimal result = 0;
    foreach (var c in binary)
    {
        result *= 2;
        result += (c - '0');
    }
    return result;
}

Upvotes: 2

richardtallent
richardtallent

Reputation: 35363

The normal numeric types are not going to be appropriate for more than 64 bits of data, either in SQL Server or in C#.

Your other alternatives include:

  • A uniqueidentifier (GUID) field, which would provide up to 128 bits.
  • A binary or varbinary field, which could be used for just about as many bits as you can dream up.
  • Individual bit fields for each access right. SQL Server will pack them into bytes automatically. This would be a strong candidate if you'll be querying the data directly rather than just persisting it.
  • A string, as already mentioned, but this would be a terrible waste of space.

Upvotes: 1

Related Questions