baron_P писал(а):Спасибо.
появился еще вопрос.
Левая часть в итоге будет типа unsigned long. Справа, исходно, unsigned char, которое, перед проведением операции "И", превращается в unsigned long. Т.е. 0xd0000001u превратится в 31 ноль и единицу в младшем разряде.
Неверно. Двоичное значение hex-константы
0xD0000001U равно 1101 0000 0000 0000 0000 0000 0000 0001.
С точки зрения стандарта последовательность действий следующая.
1.
Поскольку переменная
lfsr имеет тип
unsigned long, второй операнд операции "побитовое И" (константа
1U типа
unsigned int) сначала будет "продвинут" до более "широкого" типа
unsigned long и превратится в
1UL. Затем Будет произведена собственно операция "И". В зависимости от значения переменной
lfsr результатом операции будет либо
0UL (для четных значений), либо
1UL (для нечетных значений).
2.
Результат операция смены знака для беззнакового числа, как уже упоминалось ранее, может выйти за пределы разрядной сетки. Стандарт предписывает в таком случае прибавлять к результату (либо вычитать из него) константу
ULONG_MAX + 1 (= 2^32) до тех пор, пока значение не попадет в допустимые для данного диапазона границы. В нашем случае
-(0UL) оставляет значение тем же самым, а
-(1UL) превратится в
0xFFFFFFFFUL (напоминаю, что побитовое представление отрицательных чисел зависит от реализации, поэтому данный код довольно-таки "грязноват"!).
3.
Наконец, над результатом предыдущих операций выполняется побитовое "И" с константой
0xD0000001U. Поскольку мы уже выяснили, что этот результат может быть либо
0UL, либо
0xFFFFFFFFUL, то все выражение в итоге дает либо
0UL, либо
0xD0000001UL.
Если это действительно не нужно на практике, а взято лишь как пример для изучения, настоятельно рекомендую бросить его (поскольку качество данного кода, мягко говоря, неважное) и взять что-нибудь качественнее.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle