[dsp-l] misterio del FIR

Ignacio Ramirez Paulino nacho en fing.edu.uy
Mar Oct 15 14:46:04 GMT 2002


Hola gente,

Antes que nada advierto que este mail está dirigido sobre todo a la gente
del Martes, que protagonizaron un pequeño problema técnico de nuestra
parte.

También advierto que el contenido de este correo es *muuuuy* volado.

---

Luego de terminado el laboratorio de hoy finalmente comprobé cual era el
verdadero problema con el FIR que hacia que nuestra solución, probada
desde hace tiempo, no anduviera aquí abajo.

No era, sin embargo, la razón que un compañero de ustedes me convenciera
que era durante el laboratorio (lo de la doble dereferencia).

El verdadero problema estaba en el pasaje por valor de los punteros, en
particular, del puntero "coefs" desde fir.c hacia la funcion
fir(SAMPLE*,SAMPLE) de fir_c.c.

El asunto es que el compilador, cuando pasa por valor el *valor* del
puntero propiamente dicho (que en el caso de coefs es la posicion de
memoria del primer coeficiente del filtro), asume, en el proceso de
*copiado* de dicho valor, que el valor original está en memoria Y, no en
X.

Para probarlo, hice lo siguiente:

originalmente tenemos:

coefs = 0x10

si hago printf("coefs = %x\n",coefs) me da, correctamente

"coefs = 10"

luego probé

printf("el valor al que apunta coefs vale:
%f\n",fix_2_float(deref_x(coefs)));

lo que dio

el valor al que apunta coefs vale: 0.000000

lo que está *mal*. porque ese valor debería ser 0.00083

El problema está en como el compilador C implementa la llamada a la
funcion deref_x, porque al pasar coefs
como parametro por valor, la variable temporal utilizada dentro de deref_x
toma el valor de coefs de la memoria Y, no X como debería ser. Esto no
siempre es así y por lo que vimos varía según el contexto en el que se
genere la llamada al código.

Para probar esto, hice lo siguiente:

definí un puntero p_aux

p_aux = (fixed*) deref_x(&coefs);

esto hace que p_aux tome el verdadero valor de coefs, ya que
explícitamente dereferencio la posición en X en donde se almacena coefs.

luego probé:

printf("el valor al que apunta p_aux es:
%f\n",fix_2_float(deref_x(p_aux)));

y dio

el valor al que apunta p_aux es: 0.00083

lo que pasó ahora es que p_aux es una varaible definida en memoria Y, con
el valor de puntero apuntando a X, por lo que al pasarse por valor a
deref_x, la copia de la variable se hace bien.

Perdón si los volví locos.

Nacho.-

P.D.: Digo que no era la solución del compañero (que no recuerdo el nombre
ahora) por lo siguiente (a ver si ahora me explico bien):

1-coefs es un puntero
2-Fcoefs es el simbolo que apunta a la posicion de memoria que almacena su
valor.
3-cuando se pasa cualquier puntero por valor, que es lo mismo que copiarlo
hacia una variable temporal (el argumento de la funcion que lo toma), se
almacena, en la memoria de la variable temporal, el contenido de memoria
de coefs, es decir, el contenido de la pos de memoria apuntada por Fcoefs.
4-Al dereferenciar *una sola vez* coefs, se accede a la posicion de
memoria que apunta coefs, es decir, a la posicion de memoria indicada por
el valor almacenado en la posicion de memoria Fcoefs. O sea que no es
necesario dereferenciar 2 veces. Esto deriva de (6)
6-El símbolo Fcoefs = &coefs por definicion, o sea que la dereferenciacion
doble se hace automaticamente (la primera dereferenciación es la forma
natural de C de acceder al valor del puntero).

Al final de cuentas, si dereferenciabas 2 veces &coefs, andaba bien.




--- dsp-l en iie.edu.uy ------------------------------
por altas y bajas de la lista dirijase al formulario en
la pagina web del curso: http://www.iie.edu.uy/ense/asign/sisdsp/



Más información sobre la lista de distribución dsp-l