[an error occurred while processing this directive]
|
В написанном ниже (другими авторами) есть рациональное зернышко, которое Вы (наверное) не заметили.
Можно сначала выполнить операцию 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: info@telesys.ru