Битовый сдвиг отрицательного числа - C (СИ)

Узнай цену своей работы

Формулировка задачи:

для фильтра нижних частот был написан следующий код :
//       S16             Input                     Function input argument.
//       U16             Filter                  Filter time constant.
//       U16             DT                        Raster time.
//       S32             *FilterState                 Previous filter value.

S32 LPFilter(S16 Input, U16 FilterDelay, U16 DT, S32 *FilterState)
{
    S32 output = 0;
    S16 lpfSubstr =0;
    U16 lpfSmthFac = 0;
    lpfSmthFac = (U16) (((U32) (((U32) DT) << 16)) / ((U16) (DT + FilterDelay)));
    
    lpfSubstr = (S16)(((S32) Input) -  *FilterState);
    output =   ((((S32)lpfSmthFac) * lpfSubstr) >> 16) + *FilterState;
    *utilv_FltState = lpfOutput;
    
    return output;
подскажите какие ошибки в нем есть. особенно смущает момент когда производится правый битовый сдвиг негативного числа.
output =   ((((S32)lpfSmthFac) * lpfSubstr) >> 16) + *FilterState;
Можно ли как то переписать этот фрагмент кода? Зарание спасибо.

Решение задачи: «Битовый сдвиг отрицательного числа»

textual
Листинг программы
S16 a = -93; //1010 0011
U16 b = ((U16)(S16)a);
/*чтоб перевести в U16, делаем второй комплимент
  1010 0011
  0101 1100
                +1
--------------
  0101 1101   = 93 */
  b = 93; //0101 1101
  /*делаем сдвиг вправо*/
  b = b>>1; // 0010 1110;  b = 46  
  
  /*переводим назад в S16, делая опять второй комплимент*/
  
  /*0010 1110
   1101 0001
                +1
-------------
   1101 0010  = -46*/
 
   S16 z = ((S16)(U16) b); // 1101 0010 == -46

Объяснение кода листинга программы

  1. Объявлены две переменные: S16 a = -93; и U16 b = ((U16)(S16)a);
  2. Для того чтобы перевести отрицательное число в U16, необходимо сделать второй комплимент числа.
  3. Выполняется второй комплимент числа -93, получая 0101 1101 = 93.
  4. Значение переменной b становится равным 93.
  5. Делается сдвиг числа 93 вправо на один разряде, получая 0010 1110 = 46.
  6. Для того чтобы перевести полученное значение обратно в S16, необходимо сделать второй комплимент числа.
  7. Выполняется второй комплимент числа 0010 1110, получая 1101 0001 = -46.
  8. Значение переменной z становится равным -46.

Оцени полезность:

13   голосов , оценка 3.769 из 5
Похожие ответы