How do you randomly zero a bit in an integer?

后端 未结 13 2075
無奈伤痛
無奈伤痛 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:44

    You can generalize this by using BitArray.

    public static BitArray FlipRandomTrueBit(BitArray bits)
    {
        List trueBits = new List();
    
        for (int i = 0; i < bits.Count; i++)
            if (bits[i])
                trueBits.Add(i);
    
        if (trueBits.Count > 0)
        {
            int index = rnd.Next(0, trueBits.Count);
            bits[trueBits[index]] = false;
        }
    
        return bits;
    }
    

    However then you will have to write helper functions for simple data types.

    public static int FlipRandomTrueBit(int input)
    {
        BitArray bits = new BitArray(new int[] { input });
        BitArray flipedBits = FlipRandomTrueBit(bits);
    
        byte[] bytes = new byte[4];
        flipedBits.CopyTo(bytes, 0);
    
        int result = BitConverter.ToInt32(bytes, 0);
        return result;
    }
    

    If your using a large bit array you could save memory by iterating twice.

    public static void FlipRandomTrueBitLowMem(ref BitArray bits)
    {
        int trueBits = 0;
    
        for (int i = 0; i < bits.Count; i++)
            if (bits[i])
                trueBits++;
    
        if (trueBits > 0)
        {
            int flip = rnd.Next(0, trueBits);
    
            for (int i = 0; i < bits.Count; i++)
            {
                if (bits[i])
                {
                    if (flip == 0)
                    {
                        bits[i] = false;
                        break;
                    }
    
                    flip--;
                }
            }
        }
    }
    

    Test Program.

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace bitarray
    {
        class Program
        {
            private static Random rnd = new Random((int)DateTime.Now.Ticks);
    
            public static BitArray FlipRandomTrueBit(BitArray bits)
            {
                List trueBits = new List();
    
                for (int i = 0; i < bits.Count; i++)
                    if (bits[i])
                        trueBits.Add(i);
    
                if (trueBits.Count > 0)
                {
                    int index = rnd.Next(0, trueBits.Count);
                    bits[trueBits[index]] = false;
                }
    
                return bits;
            }
    
            public static int FlipRandomTrueBit(int input)
            {
                BitArray bits = new BitArray(new int[] { input });
                BitArray flipedBits = FlipRandomTrueBit(bits);
    
                byte[] bytes = new byte[4];
                flipedBits.CopyTo(bytes, 0);
    
                int result = BitConverter.ToInt32(bytes, 0);
                return result;
            }
    
            static void Main(string[] args)
            {
                int test = 382;
                for (int n = 0; n < 200; n++)
                {
                    int result = FlipRandomTrueBit(test);
                    Console.WriteLine(result);
                }
    
                Console.ReadLine();
            }
        }
    }
    

提交回复
热议问题