我需要在Windows Azure中存储布尔数据。我想让这些空间尽可能小。我所拥有的是十五个字段,其值为false。
field_1 = true;
field_2 = true;
field_a = false;
field_xx = true;
我有一个想法,我可以采取这些,将真和假转换为1和0,然后存储为类似1101的字符串。是否有一种简单的方法,我可以做这个编码,然后在获取数据时解码出来吗?请注意,字段名称都是不同的,因此我不能使用花哨的for循环来遍历字段名称。
答案 0 :(得分:5)
int bits = (field_1 ? 1 : 0) | (field_2 ? 2 : 0) | (field_3 ? 4 : 0) | (field_4 ? 8 : 0) | ...
field_1 = (bits & 1) != 0;
field_2 = (bits & 2) != 0;
field_3 = (bits & 4) != 0;
field_4 = (bits & 8) != 0;
...
答案 1 :(得分:3)
我认为你甚至无法想象我是多么持怀疑态度,这会对任何方式,形状或形式有所帮助。 15个布尔人几乎没什么。
现在,如果您坚持沿着这条路走下去,最好的方法是将它们存储为单个int
并使用&
将其读出并|
来编写它们回来了。
答案 2 :(得分:3)
考虑使用[Flags]属性
的枚举[Flags]
public enum Values
{
Field1 = 1,
Field2 = 2,
Field3 = 4,
Field4 = 8
}
Values obj = Field1 | Field2;
obj.HasValue(Field1); //true
obj.HasValue(Field3); //false
int storage = (int)obj;// 3
答案 3 :(得分:2)
不要打扰。您正在使用布尔值,这些值已经大小(对于单个值),因为您可以得到(我相信1个字节)。而可能能够保存的少量空间不值得增加代码的复杂性,加上开发它所需的时间。
还有一些想法:想想你如何使用这样的结构。目前,如果您查看field_1
并查看值true
,则无需进一步了解实施情况以确定实际值。但是,假设您有以下字符串:“100101011011010”(或整数值19162
,这将更有效)。 field_1
是真的还是假的?它本身并不明显 - 您需要找到实现。当你需要在某个地方支持更多字段时会发生什么?通过坚持你所拥有的东西,你将为自己省去很多心痛。
答案 4 :(得分:2)
您可以使用BitArray将布尔值打包到int
:
BitArray b = new BitArray(new bool[] { field_1, field_2, ..., field_xy });
int[] buffer = new int[1];
b.CopyTo(buffer, 0);
int data = buffer[0];
您可以使用byte
或int
数组。 byte
最多可以容纳8个布尔值,最多可以容纳int
个32个。要容纳多达16个布尔值,你可以使用一个包含两个字节的字节数组,或者一个int
,具体取决于数组的开销或int
中未使用的位是否占用更多空间。您还可以使用BitConverter
类将两个字节的数组转换为short
。
要获得布尔值,请从byte
或int
数组创建一个BitArray:
BitArray b = new BitArray(new int[] { data });
field_1 = b[0];
field_2 = b[1];
...
field_xy = b[14];
答案 5 :(得分:1)
将这些存储为字符将为每个值8或16位。我使用位移操作将它们打包成可用的最长无符号整数数组。
答案 6 :(得分:1)
答案 7 :(得分:0)
查看BitArray课程,它应该完全符合您的需要。
示例:
BitArray bits = new BitArray
(
new bool[]
{
false, true, false, false, true,
false, true, false, true, false,
false, true, false, true, false
}
);
short values = 0;
for( int index = 0; index < bits.Length; index++ )
{
if( bits[ index ] )
values |= ( short )( values | ( 1 << index ) );
}
Console.WriteLine( Convert.ToString( values, 2 ) );
现在,您在一个16位字段中存储了15个bool变量。
答案 8 :(得分:0)
您可以使用int并使用xor http://www.dotnetperls.com/xor
来执行此操作我看到一个大约15年前做过这个项目的项目。但它最终在系统中限制了32个角色(它使用了32位数字)。该产品今天不存在:)
所以不要这样做,将值存储在数组或单独的字段中。
答案 9 :(得分:0)
你可以使用带有flags属性的Enum。你说你有15个字段。所以你可以尝试使用类似的东西 [标志] 枚举Fieldvals { Field1,Field2,.... }
请参阅http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx了解指南
答案 10 :(得分:0)
您可以将标记存储在整数值中。以下是一些辅助方法来实现:
// Sets the given bit position in the UInt32 to the specified boolean value
public static UInt32 Set(UInt32 u, int position, bool newBitValue)
{
UInt32 mask = (UInt32)(1 << position);
if (newBitValue)
return (u | mask)
else
return (u & ~mask);
}
// Gets a bit value from the supplied UInt32
public static bool Get(UInt32 u, int position)
{
return ((u & (UInt32)(1 << position)) != 0);
}