C语言实验二——位运算

Posted lfri

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言实验二——位运算相关的知识,希望对你有一定的参考价值。

问题

线性反馈移位寄存器

Linear feedback shift register(LFSR),是指给定前一状态,将该输出的线性函数再用作输入的移位寄存器。异或运算是最常见的单比特线性函数:对寄存器的某些位进行异或操作后作为输入,再对寄存器中的各个比特进行整体移位。

赋给寄存器的初始值叫做“种子”,因为线性反馈移位寄存器的运算是确定的,所以,由寄存器所生成的数据流完全取决于寄存器当时或之前的状态。而且,由于寄存器状态是有限的,它最终肯定会是一个重复的循环。然而,通过本原多项式,线性反馈移位寄存器可以生成循环周期非常长的序列。

Fibonacci LFSRs

例如,16-位 Fibonacci LFSRR

技术图片

 

 其含义是:第11、13、14、16位上的值异或作为第一位,剩下的位后移。

影响下一个状态的比特位的叫做抽头,图中抽头序列为[16, 14, 13, 11]。

有结论:找到合适的抽头,能使得LFSR长度达到最大,最大长度的序列能通过 $2^n-1$ 个内部状态,不包括全零。

实现

模拟一下就好了

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

void lfsr_calculate(uint16_t *reg) 
    uint16_t &x = *reg;
    uint16_t x1 = (x << 15) >> 15;
    uint16_t x2 = (x << 13) >> 15;
    uint16_t x3 = (x << 12) >> 15;
    uint16_t x4 = (x << 10) >> 15;
    uint16_t res = x1 ^ x2 ^ x3 ^ x4;
    x = (x >> 1) + (res << 15);


int main() 
    int8_t *numbers = (int8_t*)malloc(sizeof(int8_t) * 65536);
    if (numbers == NULL) 
        printf("Memory allocation failed!");
        exit(1);
    

    memset(numbers, 0, sizeof(int8_t) * 65536);
    uint16_t reg = 0x1;
    uint32_t count = 0;
    int i;

    do 
        count++;
        numbers[reg] = 1;
        if (count < 24) 
            printf("My number is: %u\\n", reg);
        
        else if (count == 24) 
            printf(" ... etc etc ... \\n");
        

        for (i = 0; i < 32; i++)   //生成一个数要调用32次
            lfsr_calculate(&reg);
     while (numbers[reg] != 1);

    printf("Got %u numbers before cycling!\\n", count);

    if (count == 65535) 
        printf("Congratulations! It works!\\n");
    
    else 
        printf("Did I miss something?\\n");
    

    free(numbers);

    return 0;

 这个程序,能随机产生65535个1~65535中的数,然后再循环。

选取不同的初始值,只是循环的起点不同,循环还是同一个。

 

 

参考链接:

1. 维基百科——线性反馈移位寄存器

2. 题目资源

以上是关于C语言实验二——位运算的主要内容,如果未能解决你的问题,请参考以下文章

结对编程---四则运算

C语言每日一练 —— 第20天:位运算

逍遥自在学C语言 | 位运算符的基础用法

C语言原码反码补码与位运算.

C语言中位移位运算符?

C语言 位运算