如何生成一组偶数个的枚举

How to generate set of enumerations with even number of ones

本文关键字:枚举 一组 何生成      更新时间:2023-10-16

我知道如何以相对简单的方式防止单个位翻转(由于宇宙辐射或类似的外部诱导事件)导致枚举(enum)从一个定义的值更改为另一个定义值。简单地说,每个值都应该有偶数个1,从二进制的角度来说。如果其中一个翻转,则枚举将是奇数,并保证不会与任何其他枚举匹配。

我不知道如何真正"生成"这样一个序列,以便将其用作枚举值,因为这些值必须是编译时常数。返回集合中第n个元素的宏函数会做得很好。

序列中的前几个数字将是0(000)、3(011)、5(101)、6(110)。我想你现在已经明白了。

感谢非枚举(非编译时)答案,因为它可以帮助我认识到如何自己做。


为了明确起见,我想要一个宏生成枚举中的第n个数字,比特模式中有偶数个1,类似于生成fibbonachi序列的宏。最低比特本质上是奇偶校验比特。


我的大部分内存都由硬件ECC保护,一级缓存是一个例外。L1中的单个比特误差已被测量为每10000小时发生一次,从我的要求来看,这已经足够好了。

然而,VRAM不受保护。在那里,我有大部分RGB(A)光栅,一些通用光栅(如模具)和一些几何图形。RGB光栅对位翻转是不敏感的,因为它只用于可视化。错误的几何图形通常非常明显,非常罕见(很少KB),并且在设计上可以通过用户引导的重新启动来解决。

对于4096x4096x8位模板(~16MB),在我的环境中,平均宇宙辐射的单比特错误率约为每8小时一次,更常见的是在太阳风暴期间。事实上,在我看来,这并没有那么糟糕,但我讨厌填写论文,向我的官员证明为什么这在我的应用程序中是完全可以的,其他人都在使用模板数据,而不考虑数据的使用方式。然而,如果模具值中有奇偶校验位,我将能够检测到大多数错误,并在必要时重新生成模具,希望获得更好的结果。模具可以在不到一秒钟的时间内生成,因此连续发生两次错误的风险很低。

因此,基本上,通过生成一组具有奇偶性的枚举,我避开了当前和未来关于它可能如何影响我的应用程序和其他应用程序的论文和研究。

如果您只是想知道枚举是否有效或某个位是否翻转,您可以使用任何值和奇偶校验位,使总位数相等。(第一个序列与您的示例相同)

0000000 0 = 0
0000001 1 = 3
0000010 1 = 5
0000011 0 = 6
0000100 1 = 9
0000101 0 = 10
0000110 0 = 12
0000111 1 = 15

这可以通过完成

int encode_enum(int e) {
return (e << 1) + (number_of_bits_set(e) % 2);
}

然而,如果你想恢复价值,那么一个简单的方法就是复制;具有该值的多个副本,这些副本稍后可以相互比较。你需要3个副本来恢复它。如果你的值列表很小,你可以把它编码成一个整数。

int encode_enum(int e) {
return (e << 20) | (e << 10) | e;
}

如果e小于2^10,则仅将其复制3次到单个32位整数中。

c++14的constexpr为您解决了这个问题:

#include <iostream>
constexpr int bit_count(int val)
{
int count = 0;
for (int i = 0 ; i < 31 ; ++i) {
if (val & (1 << i))
++count;
}
return count;
}
constexpr int next_bitset(int last)
{
int candidate = last + 1;
if (bit_count(candidate) & 1)
return next_bitset(candidate);
return candidate;
}
enum values
{
a,
b = next_bitset(a),
c = next_bitset(b),
d = next_bitset(c)
};
int main()
{
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
std::cout << "c = " << c << std::endl;
std::cout << "d = " << d << std::endl;
}

预期输出:

a = 0
b = 3
c = 5
d = 6