位数组在范围内更改位
本文关键字:数组 范围内 | 更新日期: 2023-09-27 17:59:44
如何确保从位数组更改位时,位数组值保持在某个范围内。
例:
给定范围 [-5.12, 5.12] 和
a = 0100000000000000011000100100110111010010111100011010100111111100 ( = 2.048(
通过在随机位置更改位,我需要确保新值保持在给定范围内。
我不是 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
}
它看起来像double
(64位,结果有小数点(。
如您所知,它具有符号位,指数和分数,因此您不能更改随机位并且仍然在该范围内具有值,但有一些例外:
- 如果您的范围是 [-x;+x](相同的 x(,则可以毫无问题地更改符号位;
- 更改指数或分数将需要检查新的值范围,但:
- 将分数位的指数从
1
更改为0
将使|a|
更少。
我不知道你想达到什么目的,愿意分享吗?也许您正在尝试验证或纠正某些内容,那么您可以看看这个。
这是一个扩展方法,如果浮点数的新值超出给定范围,则撤消设置位(这只是一个例子,它依赖于 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);
}
如果你真的可以限制你的精度,那么这将容易得多。例如,给定范围:
[-5.12, 5.12]
如果我将 5.12 乘以 100,我得到
[-512, 512]
当然,二进制中的整数 512 是:
1000000000
所以现在你知道你可以设置前 9 位中的任何一个,如果第 10 位是0
,你就会< 512
。如果设置第 10 位,则必须将所有其他位设置为 0。通过一点额外的努力,这也可以扩展到处理 2 的补码负值(尽管,我可能倾向于将它们转换为正值(
现在,如果您确实需要容纳 3 d.p. 的 2.048
,那么您需要将所有值乘以 1000
而不是,这会有点困难,因为二进制中的5120
是1010000000000
您知道,如果 MSB 为 0,则可以对除最高有效位 (MSB( 之外的所有内容执行任何操作。在这种情况下,如果 MSB 为 1,但接下来的 2 位为 0,则可以对剩余位执行任何操作。
直接处理IEEE-754浮点格式的数字所涉及的逻辑可能会很痛苦。
或者你可以采用"改变值然后测试它"的方法,如果它超出范围,请返回并重试。这可能适合(在实践中(,但不能保证退出。
最后一个想法,根据你在做什么,你可能还想看看格雷码。格雷码的想法是使每个值仅相拆 1 位。对于自然编码的二进制文件,MSB的翻转对最终值的影响比LSB的翻转大几个数量级。