我应该能够在一个可以从0到3的数据结构中存储一个值。所以我需要2位。这个数据结构我将是2 ^ 16个很棒的位置。所以,我想要2 ^ 16 * 2(位)。在C ++中你是否使用内存中的2位?
答案 0 :(得分:9)
每单位需要两位(而不是三位),因此可以将四个单位打包成一个字节,或将16个单位打包成一个32位整数。
所以你需要一个std::array<uint32_t, 4096>
来容纳2个 16 单位的2位值。
您可以按如下方式访问 n th 值:
unsigned int get(std::size_t n, std::array<uint32_t, 4096> const & arr)
{
const uint32_t u = arr[n / 16];
return (u >> (2 * (n % 16))) & 0x3;
}
或者,您可以使用位域:
struct BF32 {
uint32_t u0 : 2;
uint32_t u1 : 2;
//...
uint32_t uF : 2;
}
然后制作std::array<BF32, 4096>
。
答案 1 :(得分:2)
您不能分配小于1个字节的单个对象(因为1个字节是系统中最小的可寻址单元)。
但是,您可以使用位域使结构的某些部分小于一个字节。您可以创建其中一个来保存8个值,其大小正好是3个字节:
#pragma pack(1) // MSVC requires this
struct three_by_eight {
unsigned value1 : 3;
unsigned value2 : 3;
unsigned value3 : 3;
unsigned value4 : 3;
unsigned value5 : 3;
unsigned value6 : 3;
unsigned value7 : 3;
unsigned value8 : 3;
}
__attribute__ ((packed)) // GCC requires this
;
使用[]
无法访问这些内容可能会很笨拙....最好的方法是创建自己的类,类似于bitset
但是可以工作3位而不是1。
答案 2 :(得分:1)
如果您没有使用嵌入式系统并且资源充足,您可以查看std::bitset<>
,这将使您作为程序员的工作更轻松。
但是如果您正在使用嵌入式系统,那么bitset可能对您不利(您的编译器可能甚至不支持模板)。有许多操作位的技术,每种都有自己的怪癖;这是一篇可能对你有帮助的文章:
&GT; http://www.atmel.com/dyn/resources/prod_documents/avr_3_04.pdf
答案 3 :(得分:0)
0到3有4个可能的值。由于log2(4)== 2,或者因为2 ^ 2 == 4,你需要两位,而不是三位。
您可能想要使用bit fields
答案 4 :(得分:0)
昨晚有discussion on the size allocated to bit-field structs。结构不能小于一个字节,并且大多数机器和编译器将是2或4,具体取决于编译器和字大小。所以,不,你不能得到一个3位结构(实际需要的2位)。但是,您可以将自己打包成一组数组,例如uint64_t
。或者你可以创建一个包含16个2位成员的结构,看看gcc是否使它成为一个4字节的结构,然后使用它们的数组。
答案 5 :(得分:-1)
如果你已经拥有一些数据结构,有一个很老的伎俩可以偷偷摸摸几下。这是非常讨厌的,除非你有充分的理由,否则很可能根本不是一个好主意。我只是指出这一点,以防你真的需要保存几个位。
由于对齐,x86或x64上的指针通常是4的倍数,因此这些指针的两个最低有效位(例如指向int
的指针)总是0
。你可以利用这个并在那里偷偷摸摸你的两个位,但是你必须确保在访问这些指针时删除它们(取决于架构,我在这里不确定)。
同样,这是一个讨厌,危险和漂亮的UB,但也许在你的情况下是值得的。
答案 6 :(得分:-2)
3^5 = 243
并且可以在8位中容纳5个条目。通过这种方式,您可以节省20%的空间来存储大量数据。您只需要查找表进行2次方向查找和操作。