How do you randomly zero a bit in an integer?

后端 未结 13 2076
無奈伤痛
無奈伤痛 2021-02-05 10:11

Updated with newer answer and better test

Let\'s say I have the number 382 which is 101111110.

How could I randomly turn a bit which is not 0 to

13条回答
  •  半阙折子戏
    2021-02-05 10:56

    static Random random = new Random();
    
    public static int Perturb(int data)
    {
        if (data == 0) return 0;
    
        // attempt to pick a more narrow search space
        int minBits = (data & 0xFFFF0000) == 0 ? 16 : 32;
    
        // int used = 0; // Uncomment for more-bounded performance
        int newData = data;
        do
        {
            // Unbounded performance guarantees
            newData &= ~(1 << random.Next(minBits));
    
            // // More-bounded performance:
            // int bit = 1 << random.Next(minBits);
            // if ((used & bit) == bit) continue;
            // used |= bit;
            // newData &= ~bit;
        } while (newData == data); // XXX: we know we've inverted at least one 1
                                   // when the new value differs
    
        return newData;
    }
    

    Update: added code above which can be used for more-bounded performance guarantees (or less unbounded if you want to think of it that way). Interestingly enough this performs better than the original uncommented version.

    Below is an alternate approach that is fast but without bounded performance guarantees:

    public static int FastPerturb(int data)
    {
        if (data == 0) return 0;
    
        int bit = 0;
        while (0 == (data & (bit = 1 << random.Next(32))));
    
        return data & ~bit;
    }
    

提交回复
热议问题