简体   繁体   中英

Converting UInt64 to a binary array

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM