3

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

例子:

给定范围 [-5.12, 5.12] 和

a = 0100000000000000011000100100110111010010111100011010100111111100 (= 2.048)

通过在随机位置进行一些更改,我需要确保新值保持在给定范围内。

4

4 回答 4

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
}
于 2014-04-23T15:59:41.827 回答
0

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

[-5.12, 5.12]

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

[-512, 512]

二进制的整数 512 当然是:

1000000000

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

现在,如果您实际上需要容纳 3 dp 2.048,那么您需要将所有值乘以1000,这会有点困难,因为5120在二进制中是1010000000000

您知道如果 MSB 为 0,除了最高有效位 (MSB) 之外,您可以做任何您想做的事情。在这种情况下,如果 MSB 为 1,但接下来的 2 位为 0,您可以使用剩余位。

直接处理 IEEE-754 浮点格式中的数字所涉及的逻辑可能会很痛苦。

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

最后的想法,取决于你在做什么,你可能还想看看Gray Codes。格雷码的想法是使每个值仅翻转 1 位。对于自然编码的二进制,MSB 的翻转对最终值的影响比 LSB 的翻转要大几个数量级。

于 2014-04-23T17:01:52.057 回答
0

这是一个扩展方法,如果浮点数的新值超出给定范围,则撤消设置位(这只是一个示例,它依赖于 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);
}
于 2014-04-23T16:15:43.037 回答
0

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

你可能知道它有符号位、指数和分数,所以你不能改变随机位并且仍然在范围内有值,但有一些例外:

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

我不知道你想要达到什么目的,愿意分享吗?也许您正在尝试验证或更正某些内容,那么您可以看看这个

于 2014-04-23T16:13:33.323 回答