Aritmética de punto fijo. - Instituto Tecnológico de Morelia

Anuncio
Instituto Tecnológico de Morelia
Aritmética de punto fijo.
Por M.C. Miguelangel Fraga Aguilar
En microcontroladores que carecen de instrucciones de punto flotante, implementar las operaciones de
punto flotante como subrutinas en software requiere de una cantidad significativa de memoria no
volátil y su ejecución suele tomar más tiempo del disponible entre una muestra y otra un filtro digital.
La alternativa es usar aritmética de punto fijo, que usa las mismas operaciones de suma y resta que la
aritmética entera, y solo requiere de pequeñas modificaciones para la multiplicación y división. Como
su nombre lo indica, en esta notación el número de bits usado para representar la parte entera y la parte
fraccional son fijos. Por ejemplo, si se van a usar 16 bits para representar el número de punto fijo, 8 de
estos pueden ser para la parte entera y 8 para la parte fraccionaria. Esto permitirá representar números
en el rango de -2^7 a +(2^15-1)/2^8, aproximadamente +/-128 con una resolución de
1/256=0.00390625. Entre mayor sea el número de bits dedicados a la parte entera, más grande será el
intervalo que se podrá representar. Entre mayor sea el número de bits que se dedica a la parte
fraccional, la resolución será más fina. Si se cuenta con un número fijo de bits para representar cada
número de punto fijo, se tendrá una situación de compromiso entre el rango que puede representarse y
con qué resolución.
Como se mencionó anteriormente, las operaciones de suma y resta son las mismas que para números
enteros. La multiplicación es básicamente una multiplicación entera con signo, pero es necesario que el
resultado se calcule a un número de bits mayor que el de los operandos y después correr a la derecha el
resultado el número de bits de la parte fraccionaria. Para ver la necesidad de hacer estas
modificaciones, lo mejor es un ejemplo. Suponiendo que se usan 8 bits para la parte entera y 8 para la
fraccionaria, el uno se representa como 0x0100. Al multiplicar uno por uno se obtendrá 0x00010000
como resultado a 32 bits. El resultado correcto de multiplicar uno por uno es uno, por lo que se necesita
aplicar el corrimiento mencionado anteriormente, para que el resultado sea 0x0100 a 16 bits. En c, esto
sería así:
Short int a=0x0100, b=0x0100;
Long int producto=(long(a)*long(b))>>8;
Para la división es conveniente hacer un número de corrimientos a la izquierda al dividendo igual al
número de bits de la parte fraccionaria antes de hacer la división. Siguiendo con el ejemplo anterior,
para dividir uno entre uno, el divisor será 0x00010000 en 32 bits. Al dividirlo entre 0x0100 se obtendrá
0x0100 como resultado, lo cual es correcto. En c queda como:
Short int cociente=(long(a)<<8)/b;
Si en un programa que disponga de aritmética de punto flotante se desea convertir un número de punto
flotante a punto fijo, sólo hay que multiplicar por el uno de punto fijo y convertirlo en entero. En c
queda como:
Short fijo=short(-3.15*0x0100);
Descargar