C语言实现LFSR遇位域操作异常问题求助
解决LFSR位域操作全位翻转的问题
嘿,我一眼就瞅出问题出在哪了——你在union里定义位域的方式完全搞错了!
问题根源
你把每个触发器位域都声明成了unsigned short : 1,这意味着ff_0、ff_1……ff_f每个都是独立的unsigned short类型的单个位,但因为它们在union里共享同一块内存空间,这些位域其实全部重叠在了同一个位置上!不管你修改哪一个位域,都是在操作同一个位;而给ff(整个unsigned short)赋值时,你误以为所有位域都变了,本质是因为你的位域布局逻辑完全错误。
正确的位域写法
要让每个位域对应unsigned short的不同位,你需要把它们打包成同一个结构体的连续位域,或者直接在union里定义连续的位域序列:
方法1:结构体嵌套位域
struct lfsr{ union{ struct { unsigned short ff_0 : 1; unsigned short ff_1 : 1; // 依次定义到 ff_f : 1(共16个位) unsigned short : 0; // 可选,强制对齐到short边界 }; unsigned short ff; }flip_flops; };
方法2:连续位域声明
struct lfsr{ union{ unsigned short ff_0 : 1, ff_1 : 1, // ... 依次定义到 ff_f : 1 ff_f : 1; unsigned short ff; }flip_flops; };
这样修改后,所有位域会依次占据同一个unsigned short的不同位(通常从最低位开始,具体取决于编译器,但只要你保持逻辑一致就不影响LFSR功能)。现在测试你的代码:
gen.flip_flops.ff = 0x0001只会把ff_0设为1,其他位都是0;gen.flip_flops.ff_0 = 1也只会修改第0位,不会影响其他位。
更可靠的替代方案:掩码操作
位域的布局可能受编译器端序和规则影响,如果你需要精确控制每个位的位置(LFSR对反馈位位置要求严格),直接用掩码操作会更可移植:
// 定义每个位的掩码 #define FF_0_MASK 0x0001 #define FF_1_MASK 0x0002 #define FF_2_MASK 0x0004 // ... 依次定义到 FF_F_MASK 0x8000 struct lfsr{ unsigned short ff; }; // 设置ff_0为1 gen.ff |= FF_0_MASK; // 清空ff_0 gen.ff &= ~FF_0_MASK; // 获取ff_0的值 int ff0_val = (gen.ff & FF_0_MASK) ? 1 : 0;
这种方式完全避开了位域的编译器依赖问题,对于LFSR来说是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Grey
相关产品推荐
相关产品推荐

