2015-09-08 6 views
-1

Как и выше, я создал LFSR, чтобы попытаться сгенерировать некоторые числа, однако он не работает должным образом.LFSR не работает должным образом

работы с этим:

unsigned int lfsr = 0x000001 
while(1) 
{ 
    lfsr >>= 1 
    unsigned int lsb1 = lfsr & 1; 
    unsigned int lsb2 = lfsr & 2; 

    if (lsb1 == 1 && lsb2 == 1 || lsb1 == 0 && lsb2 == 0) 
    lfsr |= 0x000000; 
    else 
    lfsr |= 0x800000; 
} 

Однако это не сработало, с lsb2 сравнявшись 2, поэтому после некоторых отводом о я в настоящее время получил это:

unsigned int lfsr = 0x000001 
while(1) 
{ 
    lfsr >>= 1 
    lfsr |= ((((unsigned int)((lfsr<<31)>>31))^((unsigned int)((lfsr<<30)>>31))) << 24); 
} 

Это создает 2^21 - 1 число, тогда как я пытаюсь получить то, что генерирует 2^24.

Я пропустил что-то очевидное? Любая помощь будет оценена, спасибо.

+0

'int' не гарантирует 32 бит. Вместо этого используйте 'stdint.h' типы! – Olaf

+1

Что вы хотите выполнить с помощью 'lfsr | = 0x000000;'? – Olaf

+0

Я думаю, что LFSR означает [Линейный регистр сдвига обратной связи] (https://en.wikipedia.org/wiki/Linear_feedback_shift_register). В статье, посвященной WIkipedia, описываются периоды, которые меньше 1 степени 2. Почему вы ожидаете период 2^24? (Пожалуйста, разместите ссылку, объясняющую теорию) – anatolyg

ответ

1

Эти примеры LFSR будут циклически проходить через (2^24) -1 числа (все 2^24 числа, но ноль). Первый пример - Galois LFSR, который затем сдвигает xor с (полином обратной связи). Второй пример - Galois LFSR, который сдвигается затем на xor с (полином обратной связи >> 1). Третий пример - LFSR Фибоначчи. Обратите внимание, что с start_state 0x000001 значение бит для всех трех примеров следует за одним и тем же шаблоном, хотя Galois LFSR и Fibonacci LFSR будут следовать различным шаблонам. 0x100001b - наименьший обратный полином, а 0x1c20001 - наибольший 4-кратный ответный полином для циклов (2^24) -1.

В этом примере следует вики Galios LFSR пример с исключающего сделал первый:

int main(int argc, char *argv[]) 
{ 
unsigned int period, bit, lfsr, start_state; 
    period = 0; 
    lfsr = start_state = 0x000001; 
    do 
    { 
     bit = lfsr&1;    /* get bit */ 
     lfsr ^= (0-bit)&0x100001b; /* toggle taps if bit was 1 */ 
     lfsr >>= 1;     /* shift lfsr */ 
     ++period; 
    }while(lfsr != start_state); 
    printf("%x\n", period);   /* period will == 0xffffff */ 
    return(0); 
} 

В этом примере следует вики-Galios LFSR пример с сдвига сделал первый:

int main(int argc, char *argv[]) 
{ 
unsigned int period, bit, lfsr, start_state; 
    period = 0; 
    lfsr = start_state = 0x000001; 
    do 
    { 
     bit = lfsr & 1;    /* get bit */ 
     lfsr >>= 1;     /* shift lfsr */ 
     lfsr ^= (0-bit)&0x80000d; /* toggle taps if bit was 1 */ 
     ++period; 
    } while (lfsr != start_state); 
    printf("%x\n", period);   /* period will == 0xffffff */ 
    return(0); 
} 

Этот пример следует за wiki Fibonacci Пример LFSR:

int main(int argc, char *argv[]) 
{ 
unsigned int period, bit, lfsr, start_state; 
    period = 0; 
    lfsr = start_state = 0x000001; 
    do 
    { 
     /* taps: 24 4 3 1 */ 
     /* feedback polynomial: x^24 + x^4 + x^3 + x + 1 = 0x100001b */ 
     bit = ((lfsr>>(24-24))^(lfsr>>(24-4))^(lfsr>>(24-3))^(lfsr>>(24-1)))&1; 
     lfsr = (lfsr >> 1) | (bit << 23); 
     ++period; 
    } while (lfsr != start_state); 
    printf("%x\n", period);   /* period will == 0xffffff */ 
    return(0); 
} 
+0

Спасибо, это, безусловно, работает, собирается немного почитать, чтобы понять, почему, поскольку он, похоже, не коррелирует с pdf, который @anatolyg связан в своем комментарии к моему вопросу. – GeorgeStorm

+0

@GeorgeStorm - я обновил свой ответ, первые два примера используют [Galois LFSR] (http://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs). В первом примере xor перед сдвигом отображает полиномиальную обратную связь 25 бит (0x100001b). Второй пример следует примеру кода вики. В третьем примере используется Fibonacci LFSR с одним и тем же полиномом обратной связи, аналогичным тому, что делал ваш пример кода. 0x100001b - самый маленький poly, а 0x1c20001 - самый большой 4-кратный поли для циклов (2^24) -1. – rcgldr

0

Неверный код: lsb2 == 1 никогда не верно

unsigned int lsb2 = lfsr & 2; 
... 
if (lsb1 == 1 && lsb2 == 1 .... // bad 

Вероятно, должно быть

if (lsb1 && lsb2 .... // better 

Согласен с @Olaf, рассмотрим uint32_t.

+0

Так что мне нужно будет сдвинуть результат на один? Мне действительно не нужны 32 бита, только нужно 24, но подумал, что не будет вреда в использовании 32, поскольку все из них слева от 24 будут равны 0 и не будут влиять на генерируемые числа. – GeorgeStorm

+0

@GeorgeStorm 1) Да, альтернативой может быть 'unsigned int lsb2 = (lfsr & 2) >> 1;' или '= !! (lfsr & 2);' или другие. 2) Относительно 32 против 24 бит: 'unsigned '- это всего лишь минус 16 бит. Таким образом, предлагается использовать целое число, гарантированное для удовлетворения вашей ширины бита 32/24. – chux

0
unsigned int lfsr = 0x000001 // actually int is 4 bytes so result is 0x00000001 
while(1) 
{ 
    lfsr >>= 1     // now lfsr = 0 
    unsigned int lsb1 = lfsr & 1; // == 0 
    unsigned int lsb2 = lfsr & 2; // == 0 

    // the following line will 'work' however, it is always better/clearer 
    // to force the correct precedence via parens 
    // and lsb2 will be 0 or 2, never 1 
    if (lsb1 == 1 && lsb2 == 1 || lsb1 == 0 && lsb2 == 0) 
    lfsr |= 0x000000; // this will always be executed and makes no change to the value in 'lfsr' 
    else 
    lfsr |= 0x800000; // unsigned int is 4 bytes, so this is actually 0x00800000 
} 
Смежные вопросы