/* fixed.h */ /* Simple fixed-point transcendental functions. */ /* Copyright 1997 by Ka-Ping Yee. All rights reserved. */ /* Fixed numbers have an 8-bit integer part and an 8-bit fractional part. */ typedef Short Fixed; /* Convert between fixed and integer. */ #define fint(x) (((x)+127) >> 8) #define intf(x) ((Fixed) (x) << 8) /* Multiply two fixed-point numbers. */ Fixed fmul(Fixed a, Fixed b) { Long result = (Long) a * b; return (result+127) >> 8; } /* Find the cosine of a fixed-point angle given in radians. */ Fixed fcos(Fixed angle) { Fixed result; int neg = 0; /* Normalize to the interval [-pi/2, 3*pi/2]. For example, the */ /* fixed-point number 402 corresponds to 402/256 =~ 1.57 =~ pi/2. */ while (angle < -402) angle += 1608; while (angle > 1206) angle -= 1608; /* Shift the angle into the first quadrant. */ if (angle > 402) { angle -= 804; neg = 1; } if (angle < 0) angle = -angle; /* Special case removes a hiccup. */ if (angle == 263) result = 133; /* Quick answer for the almost linear region. */ else if (angle >= 332 && angle <= 472) result = 402 - angle; /* Remember Taylor series? They actually do come in handy some days... */ else { result = fmul(angle, angle); result = 256 - fmul(result, 256/2 - fmul(result, 256/24)); /* Another fix to remove a hiccup. */ if (angle >= 255 && angle <= 328) result++; } return neg ? -result : result; } /* Find the sine of a fixed-point angle given in radians. */ Fixed fsin(Fixed angle) { return fcos(angle - 402); }