Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

This based on this question in StackOverflow. The accepted answer uses Convert.ToString(int, base) to get the binary string, reverses it and converts it back to int. Nice trick!

I have very little experience with bit twidling (using Flags is about it :p ) so I decided to try and code the solution to this problema without using Convert.

I came up with the following solution. I'd like to know easier ways to do this as there are probably many much better than the one I found.

public static IEnumerable<bool> ToBinary(this int n)
{
    for (int i = 0; i < 32; i++)
    {
        yield return (n & (1 << i)) != 0;
    }
}

public static int ToInt(this IEnumerable<bool> b)
{
    var n = 0;
    var counter = 0;

    foreach (var i in b.Trim().Take(32))
    {
        n = n | (i ? 1 : 0) << counter;
        counter++
    }

    return n;
}

private static IEnumerable<bool> Trim(this IEnumerable<bool> list)
{
    bool trim = true;

    foreach (var i in list)
    {
        if (i)
        {
            trim = false;
        }

        if (!trim)
        {
            yield return i;
        }
    }
}

And now you'd use it like this:

var reversed = n.ToBinary().Reverse().ToInt();
share|improve this question

2 Answers 2

up vote 6 down vote accepted

You could use while loop instead of the for loop.
Thus you don't need to trim zero bits, because it will continue to loop only while there is at least one significant bit in a value.
Another advantage of this approach is that the result can be calculated using integer arithmetics only without using any kind of collections.

static int Reverse(int input)
{
    uint x = unchecked((uint)input);
    uint y = 0;
    while (x != 0)
    {
        y <<= 1;    // Shift accumulated result left
        y |= x & 1; // Set the least significant bit if it is set in the input value
        x >>= 1;    // Shift input value right
    }
    return unchecked((int)y);
}

Usage example:

int t = 0x103;
Console.WriteLine(Convert.ToString(t, 2));
Console.WriteLine(Convert.ToString(Reverse(t), 2));

Result:

100000011
110000001
share|improve this answer
    
Adding more detail on why it works better would be better, but, that's about the same answer I would give. –  rolfl yesterday
1  
For a negative x the loop seems to be infinite. –  vnp yesterday
    
@vnp Fixed. Thank you. –  Dmitry yesterday
    
Thanks! This is 10 times better...and faster :) –  InBetween 15 hours ago

Dmitry's answer is probably better, but I'll provide another option. If you wish to stick to using collections, you can replace the loops with LINQ to increase conciseness, readability, and safety.

public static IEnumerable<bool> ToBinary(this int n)
{
    return Enumerable.Range(0, 32).Select(x => (n & (1 << x)) != 0);
}

public static int ToInt(this IEnumerable<bool> b)
{
    return b.Trim().Take(32).Select((x, i) => (x ? 1 : 0) << i).Sum();
}

private static IEnumerable<bool> Trim(this IEnumerable<bool> list)
{
    return list.SkipWhile(x => !x);
}
share|improve this answer
    
Thanks for the input. That does look a lot better. –  InBetween 19 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.