0

I am having problem with this method I wrote to convert UInt64 to a binary array. For some numbers I am getting incorrect binary representation.

Results

Correct 999 = 1111100111

Correct 18446744073709551615 = 1111111111111111111111111111111111111111111111111111111111111111

Incorrect? 18446744073709551614 = 0111111111111111111111111111111111111111111111111111111111111110

According to an online converter the binary value of 18446744073709551614 should be 1111111111111111111111111111111111111111111111111111111111111110

    public static int[] GetBinaryArray(UInt64 n)
    {
        if (n == 0)
        {
            return new int[2] { 0, 0 };
        }

        var val = (int)(Math.Log(n) / Math.Log(2));

        if (val == 0)
            val++;

        var arr = new int[val + 1];

        for (int i = val, j = 0; i >= 0 && j <= val; i--, j++)
        {
            if ((n & ((UInt64)1 << i)) != 0)
                arr[j] = 1;
            else
                arr[j] = 0;

        }
        return arr;
    }

FYI: This is not a homework assignment, I require to convert an integer to binary array for encryption purposes, hence the need for an array of bits. Many solutions I have found on this site convert an integer to string representation of binary number which was useless so I came up with this mashup of various other methods.

An explanation as to why the method works for some numbers and not others would be helpful. Yes I used Math.Log and it is slow, but performance can be fixed later.

EDIT: And yes I do need the line where I use Math.Log because my array will not always be 64 bits long, for example if my number was 4 then in binary it is 100 which is array length 3. It is a requirement of my application to do it this way.

4
  • why int array? you are consuming 4 bytes for each bit of ulong... that means you are consuming 256 bytes while you could use only 8 bytes to represent ulong. also Math.Log is the slowest way. just loop over all bits of ulong. it would be faster. Commented Feb 5, 2016 at 22:57
  • 1
    try bits = new BitArray(BitConverter.GetBytes(longValue)); Commented Feb 5, 2016 at 23:04
  • @M.kazemAkhgary A method that consumes the binary number is expecting an integer array. I cannot change it. Commented Feb 5, 2016 at 23:12
  • @Plutonix I chose to use your suggestion instead of creating my own method, performance was much faster this way. Commented Feb 16, 2016 at 22:27

1 Answer 1

1

It's not the returned array for the input UInt64.MaxValue - 1 which is wrong, it seems like UInt64.MaxValue is wrong.

The array is 65 elements long. This is intuitively wrong because UInt64.MaxValue must fit in 64 bits.

Firstly, instead of doing a natural log and dividing by a log to base 2, you can just do a log to base 2.

Secondly, you also need to do a Math.Ceiling on the returned value because you need the value to fit fully inside the number of bits. Discarding the remainder with a cast to int means that you need to arbitrarily do a val + 1 when declaring the result array. This is only correct for certain scenarios - one of which it is not correct for is... UInt64.MaxValue. Adding one to the number of bits necessary gives a 65-element array.

Thirdly, and finally, you cannot left-shift 64 bits, hence i = val - 1 in the for loop initialization.

Haven't tested this exhaustively...

public static int[] GetBinaryArray(UInt64 n)
{
    if (n == 0)
    {
        return new int[2] { 0, 0 };
    }
    var val = (int)Math.Ceiling(Math.Log(n,2));
    if (val == 0)
        val++;
    var arr = new int[val];
    for (int i = val-1, j = 0; i >= 0 && j <= val; i--, j++)
    {
        if ((n & ((UInt64)1 << i)) != 0)
            arr[j] = 1;
        else
            arr[j] = 0;
    }
    return arr;
}
Sign up to request clarification or add additional context in comments.

1 Comment

You are correct, it was my calculation of the array length that is wrong. It works for small numbers, but not at the 64 bit max which yields one larger than it should be. Thanks for your feedback, I will try it.

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.