Allegro trae algunas rutinas para trabajar con números de punto fijo, y define el tipo 'fixed' como un entero de 32 bits con signo. La parte alta es usada por el valor del entero y la parte baja es usada por el valor de la fracción, dando un rango de valores de -32768 a 32767 y un detalle de unos 4 o 5 decimales. Los números de punto fijo pueden ser asignados, comparados, añadidos, substraídos, negados y desplazados (para multiplicar o dividir por potencias de 2) usando los operadores de enteros normales, pero tendría que tener cuidado de usar las rutinas de conversión apropiadas cuando combine números de punto fijo con enteros o números de coma flotante. Escribir 'punto_fijo_1 + punto_fijo_2' esta bien, pero 'punto_fijo + entero' no esta bien.
fixed itofix(int x);
Convierte un valor de entero a punto fijo. Esto es lo mismo que x<<16.
int fixtoi(fixed x);
Convierte un valor de punto fijo a entero, redondeando.
int fixfloor(fixed x);
Devuelve el mayor entero menor que x. Esto es, redondea hacia el infinito
negativo.
int fixceil(fixed x);
Devuelve el menor intero mayor que x. Esto es, redondea hacia el infinito
positivo.
fixed ftofix(float x);
Convierte un valor de coma flotante a punto fijo.
float fixtof(fixed x);
Convierte un valor de punto fijo a coma flotante.
fixed fixmul(fixed x, fixed y);
Un valor de punto fijo puede ser multiplicado o dividido por un entero
con los operadores normales '*' y '/'. Sin embargo, para multiplicar dos
valores de punto fijo necesita usar esta función.
Si hay desbordamiento o división por cero, errno será activado y el valor máximo posible será devuelto, pero errno no es limpiado si la operación es realizada con éxito. Esto significa que si va a comprobar un desbordamiento de división, debería poner errno=0 antes de llamar a fixmul().
fixed fixdiv(fixed x, fixed y);
División de valores de punto fijo: mire fixmul().
fixed fixadd(fixed x, fixed y);
A pesar de que los números de punto fijo pueden ser añadidos con el
operador normal de enteros '+', eso no le da protección contra
desbordamientos. Si el desbordamiento es un problema, debería usar esta
función. Es mas lenta que los operadores de enteros, pero si hay un
desbordamiento de división, ajustará el tamaño del resultado en vez de
dejarlo al azar, y activara errno.
fixed fixsub(fixed x, fixed y);
Resta de números en punto fijo: mire fixadd().
Las funciones de raíz cuadrada, seno, coseno, tangente, cosecante y secante están implementadas usando tablas precalculadas, que son muy rápidas pero no muy exactas. Por ahora, la cotangente realiza una búsqueda iterativa en la tabla de la tangente, por lo que es mas lenta que las otras.
Los ángulos están representados en formato binario con 256 siendo igual al círculo completo, 64 es un ángulo recto y así sucesivamente. Esto tiene la ventaja de que un 'and' a nivel de bits puede ser usado para que el ángulo quede entre cero y el círculo completo, eliminando esos tests cansinos 'if (angle >= 360)'.
fixed fixsin(fixed x);
Mira la tabla precalculada del seno.
fixed fixcos(fixed x);
Mira la tabla precalculada del coseno.
fixed fixtan(fixed x);
Mira la tabla precalculada de la tangente.
fixed fixasin(fixed x);
Mira la tabla de la cosecante.
fixed fixacos(fixed x);
Mira la tabla de la secante.
fixed fixatan(fixed x);
Cotangente de punto fijo.
fixed fixatan2(fixed y, fixed x);
Versión de punto fijo de la rutina atan2() de libc.
fixed fixsqrt(fixed x);
Raíz cuadrada de punto fijo.
fixed fixhypot(fixed x, fixed y);
Hypotenusa en punto fijo (devuelve la raíz cuadrada de x*x + y*y).
Si está programando en C++ puede ignorar todo lo de arriba y usar la clase "fija", que sobrecarga muchos operadores para proveer conversión automática desde y hacia valores enteros y de coma flotante, y llama las rutinas de arriba cuando se necesitan. Sin embargo no debería mezclar la clase "fija" con los typedefs de punto fijo, ya que el compilador tratará los valores de punto fijo como enteros regulares e insertará conversiones innecesarias. Por ejemplo, si x es un objeto de clase fija, llamar fixsqrt(x) devolverá un resultado erróneo. Debería usar sqrt(x) o x.swrt() en vez de eso.
Las rutinas de punto fijo antes eran nombradas con el prefijo "f" en lugar de "fix", ej: fixsqrt() antes era fsqrt(), pero tuvieron que ser renombradas por conflictos con algunas implementaciones de la libc. Esto no debería afectar a la mayoría del código existente dado que existen alias de compatibilidad hacia atrás. Estos alias son funciones estáticas inline que enlazan los nombres antiguos con los nuevos, ej: fsqrt() llama a fixsqrt(). Puede desactivar estos alias definiendo la macro de preprocesador ALLEGRO_NO_FIX_ALIASES antes de incluír allegro.h.
Tenga en cuenta que no proveemos estos alias de compatibilidad hacia atrás bajo IRIX ya que requeriría demasiada magia negra.