[an error occurred while processing this directive]
Поделить (иногда) - это то же самое, что и умножить...
(«Телесистемы»: Конференция «Цифровые сигнальные процессоры (DSP) и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Oleg_0515 20 мая 2003 г. 14:32
В ответ на: Подскажите пожалуйст: деление 32/16 на 54xx - а то встроенная в С 700 тактов жрет ... отправлено Желающий поделить 20 мая 2003 г. 03:56

В написанном ниже (другими авторами) есть рациональное зернышко, которое Вы (наверное) не заметили.
Можно сначала выполнить операцию Tmp=1/Var16, а затем операцию Var32*Tmp...
Подобная хохма, но с аппроксимацией ф-и 1/x Тейлором, приводится в стандартных ДСП ANSI-С демах, например в G.729 (хитрый PDF формат для 32-битных данных применен для "ускорения", на их взгляд, алгоритма на 16 битном умножителе, но важнее идея...):

/*
Function Name : Div_32
Purpose : Fractional integer division of two 32 bit numbers.
L_num / L_denom.

L_num and L_denom must be positive and L_num < L_denom.
L_denom = denom_hi<<16 + denom_lo<<1
denom_hi is a normalize number.
The result is in Q30.

Inputs :

L_num
32 bit long signed integer (Word32) whose value falls in the
range : 0x0000 0000 < L_num < L_denom
L_denom = denom_hi<<16 + denom_lo<<1 (DPF)

denom_hi
16 bit positive normalized integer whose value falls in the
range : 0x4000 < hi < 0x7fff

denom_lo
16 bit positive integer whose value falls in the
range : 0 < lo < 0x7fff

Return Value :
L_div
32 bit long signed integer (Word32) whose value falls in the
range : 0x0000 0000 <= L_div <= 0x7fff ffff.
It's a Q31 value
Algorithm: - find = 1/L_denom.
First approximation: approx = 1 / denom_hi
1/L_denom = approx * (2.0 - L_denom * approx )
- result = L_num * (1/L_denom)
*/

Word32 Div_32(Word32 L_num, Word16 denom_hi, Word16 denom_lo)
{
Word16 approx, hi, lo, n_hi, n_lo;
Word32 L_32;


/* First approximation: 1 / L_denom = 1/denom_hi */

approx = div_s( (Word16)0x3fff, denom_hi); /* result in Q14 */
/* Note: 3fff = 0.5 in Q15 */

/* 1/L_denom = approx * (2.0 - L_denom * approx) */

L_32 = Mpy_32_16(denom_hi, denom_lo, approx); /* result in Q30 */


L_32 = L_sub( (Word32)0x7fffffffL, L_32); /* result in Q30 */

L_Extract(L_32, &hi, &lo);

L_32 = Mpy_32_16(hi, lo, approx); /* = 1/L_denom in Q29 */

/* L_num * (1/L_denom) */

L_Extract(L_32, &hi, &lo);
L_Extract(L_num, &n_hi, &n_lo);
L_32 = Mpy_32(n_hi, n_lo, hi, lo); /* result in Q29 */
L_32 = L_shl(L_32, 2); /* From Q29 to Q31 */

return( L_32 );
}

Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru