Aritmética de punto fijo. - Instituto Tecnológico de Morelia
Transcripción
Aritmética de punto fijo. - Instituto Tecnológico de Morelia
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);