简体   繁体   中英

Which bit is on for an integer in Java

I have written this code to check which bits are on of an Integer (if represented in binary) in Java:

public static List<String> list(int val)
{
    List<String> dummyList = new ArrayList<String>();

    int bit = 1;
    int x;

    for(int i=0; i<32; i++)
    {
        x = bit;
        if((x&val)!=0)
            dummyList.add(String.valueOf(i+1));
        bit = bit << 1;
    }

    return dummyList;
}

The above written code works fine. But it has a loop which runs 32 times (In Java integer is 32 bit long). I want to minimize this complexity. Please share the better solution. Thanks in advance.

You could use a bit mask to try to reduce the times through the loop. You add a few operations but potentially do half the looping:

public static List<String> list(int val) {
    List<String> dummyList = new ArrayList<String>();
    int loop = 32;

    // Mask the 16 MSB if all are zero only loop on the 16 LSB
    if((val & 0xFFFF0000) == 0){
        loop = 16;
    }

    int bit = 1;
    int x;

    for (int i = 0; i < loop; i++) {
        x = bit;
        if ((x & val) != 0) {
            dummyList.add(String.valueOf(i + 1));
        }
        bit <<= 1;
    }

    return dummyList;
}

This potentially would increase time depending on the data coming in.

You can also reduce looping in half by doing two bits at a time:

public static List<String> list(int val) {
    List<String> dummyList = new ArrayList<String>();

    int bit = 3;
    int x;

    for (int i = 0; i < 32; i += 2) {
        x = (bit & val);
        switch (x) {
            case 1:
                dummyList.add(String.valueOf(i + 1));
                break;
            case 2:
                dummyList.add(String.valueOf(i+2));
                break;
            case 3:
                dummyList.add(String.valueOf(i+1));
                dummyList.add(String.valueOf(i+2));
                break;
            default:
        }
        val >>= 2;
    }

    return dummyList;
}

The complexity is O(1), so there's not much to "minimize" there.

Your code is okay.. here it is refactored slightly.

public static List<String> list(int val) {
    List<String> dummyList = new ArrayList<String>();
    for (int i = 0; i < 32; i++)
        if ((1 << i & val) != 0)
            dummyList.add("" + (i+1));
    return dummyList;
}

Btw, have you considered using a BitSet ?

32 loops sounds good for this application. You can use a StringBuffer instead of List if you want to collect the digits faster.

public static String list(int val)
{
    StringBuffer dummyList = new StringBuffer();

    int bit = 1;
    int x;

    for(int i=0; i<32; i++)
    {
        x = bit;
        dummyList.append((x&val) ? '1' : '0' );
        bit = bit << 1;
    }

    return dummyList.toString();
}

Improving O(1) code seems trivial but this code is a slight improvement:

public static List<String> list(int val) {
    List<String> dummyList = new ArrayList<String>();
    for (int i=0; val!=0 && i<32; ++i){
        if ((1 << i & val) != 0) {
            dummyList.add("" + (i+1));
            val &= val -1;  // unset the last set bit (current bit)
        }                   // causes loop to end early when all bits are counted
    }
    return dummyList;

Rather then making all 32 bit comparisons, this code will end as soon as the last bit has been counted. It is much more efficient for integers that are sparsely populated with 1 s and no less efficient for integers which are highly populated.

Since you know the exact length of the integer I would recommend using a bool[] instead. There is not much you can do about the complexity though. It is as fast as it can get and the JIT is probably going to unroll the loop of this code anyways.

public static bool[] list(int val)
{
    bool[] a = new bool[32];
    for(int i=0; i<32; i++)
    {
        a[i] = ((1 << i) & val) != 0;
    }
    return a;
}

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