BitArray在范围内改变位

时间:2014-04-23 15:42:28

标签: c# genetic-algorithm mutation

如何确保在从BitArray更改位时,BitArray值保持在一个范围内。

示例:

  

给定范围[-5.12,5.12]和

     

a = 0100000000000000011000100100110111010010111100011010100111111100(= 2.048)

通过改变随机位置的位,我需要确保新值保持在给定范围内。

4 个答案:

答案 0 :(得分:1)

我不能100%确定您在做什么,而且这个答案假定您当前正在将a存储为64位值(long)。以下代码可能会帮助您指明正确的方向。

const double minValue = -5.12;
const double maxValue = 5.12;

var initialValue = Convert.ToInt64("100000000000000011000100100110111010010111100011010100111111100", 2);
var changedValue = ChangeRandomBit(initialValue); // However you're doing this

var changedValueAsDouble = BitConverter.Int64BitsToDouble(initialValue);
if ((changedValueAsDouble < minValue) || (changedValueAsDouble > maxValue))
{
    // Do something
}

答案 1 :(得分:0)

看起来像double(64位,结果有小数点)。

您可能知道它有符号位,指数和分数,因此您无法更改随机位并且仍然具有该范围内的值,但有一些例外:

    如果您的范围是[-x; + x](相同的x),
  • 符号位可以毫无问题地更改;
  • 更改指数或分数将需要检查新的值范围,但是:
  • 将分数位的指数从1更改为0将使|a|更少。

我不知道你想要实现什么,关心分享?也许您正在尝试验证或更正某些内容,然后您可以查看this

答案 2 :(得分:0)

这是一个扩展方法,如果float的新值超出给定范围,则取消设置位(这只是一个例子,它依赖于BitArray持有没有检查的浮点数,这非常可怕所以只是黑客解决方案,包括改为双倍):

static class Extension
{
    public static void SetFloat(this BitArray array, int index, bool value, float min, float max)
    {
        bool old = array.Get(index);
        array.Set(index, value);
        byte[] bytes = new byte[4];
        array.CopyTo(bytes, 0);
        float f = BitConverter.ToSingle(bytes, 0);
        if (f < min || f > max)
            array.Set(index, old);
    }
}

使用示例:

static void Main(string[] args)
{
    float f = 2.1f;
    byte[] bytes = System.BitConverter.GetBytes(f);
    BitArray array = new BitArray(bytes);
    array.Set(20, true, -5.12f, 5.12f);
}

答案 3 :(得分:0)

如果你实际上可以限制你的精确度,那么这将更容易。例如,给定范围:

[-5.12, 5.12]

如果我将5.12乘以100,我得到

[-512, 512]

二进制中的整数512当然是:

1000000000

现在你知道你可以设置前9位中的任何一位,如果第10位是< 512,你将是0。如果设置第10位,则必须将所有其他位设置为0.只需稍加努力,这可以扩展到处理2的补码负值(尽管我可能只想将它们转换为正值)价值观)

现在,如果你真的需要容纳3 d.p. 2.048的{​​{1}},那么您需要将所有值乘以1000,而这将更加困难,因为二进制中的51201010000000000

如果MSB为0,你知道除了最高位(MSB)之外你可以做任何你想要的事情。在这种情况下,如果MSB是1,但接下来的2位是0,你可以做任何事情你想要剩下的比特。

直接处理IEEE-754浮点格式中的数字所涉及的逻辑可能是折磨的。

或者您可以选择“改变值然后测试它”的方法,如果超出范围,请返回并重试。这可能是合适的(在实践中),但不能保证退出。

最后的想法,根据你正在做的事情,你可能还想看Gray Codes。格雷码的想法是使每个值仅翻转1位。对于自然编码的二进制,MSB的翻转对最终值的影响比对LSB的翻转有更大的影响。