/* math.c */ int * sintable; int * tantable; int * sqrttable; int nsqrt; create() { sintable = ({ 0, 0, 1, 17, 2, 34, 3, 52, 4, 69, 5, 87, 6, 104, 7, 121, 8, 139, 9, 156, 10, 173, 11, 190, 12, 207, 13, 224, 14, 241, 15, 258, 16, 275, 17, 292, 18, 309, 19, 325, 20, 342, 21, 358, 22, 374, 23, 390, 24, 406, 25, 422, 26, 438, 27, 453, 28, 469, 29, 484, 30, 500, 31, 515, 32, 529, 33, 544, 34, 559, 35, 573, 36, 587, 37, 601, 38, 615, 39, 629, 40, 642, 41, 656, 42, 669, 43, 681, 44, 694, 45, 707, 46, 719, 47, 731, 48, 743, 49, 754, 50, 766, 51, 777, 52, 788, 53, 798, 54, 809, 55, 819, 56, 829, 57, 838, 58, 848, 59, 857, 60, 866, 61, 874, 62, 882, 63, 891, 64, 898, 65, 906, 66, 913, 67, 920, 68, 927, 69, 933, 70, 939, 71, 945, 72, 951, 73, 956, 74, 961, 75, 965, 76, 970, 77, 974, 78, 978, 79, 981, 80, 984, 81, 987, 82, 990, 83, 992, 84, 994, 85, 996, 86, 997, 87, 998, 88, 999, 89, 999, 90, 1000 }); tantable = ({ 0, 0, 1, 17, 2, 34, 3, 52, 4, 69, 5, 87, 6, 105, 7, 122, 8, 140, 9, 158, 10, 176, 11, 194, 12, 212, 13, 230, 14, 249, 15, 267, 16, 286, 17, 305, 18, 324, 19, 344, 20, 363, 21, 383, 22, 404, 23, 424, 24, 445, 25, 466, 26, 487, 27, 509, 28, 531, 29, 554, 30, 577, 31, 600, 32, 624, 33, 649, 34, 674, 35, 700, 36, 726, 37, 753, 38, 781, 39, 809, 40, 839, 41, 869, 42, 900, 43, 932, 44, 965, 45, 1000, 46, 1035, 47, 1072, 48, 1110, 49, 1150, 50, 1191, 51, 1234, 52, 1279, 53, 1327, 54, 1376, 55, 1428, 56, 1482, 57, 1539, 58, 1600, 59, 1664, 60, 1732, 61, 1804, 62, 1880, 63, 1962, 64, 2050, 65, 2144, 66, 2246, 67, 2355, 68, 2475, 69, 2605, 70, 2747, 71, 2904, 72, 3077, 73, 3270, 74, 3487, 75, 3732, 76, 4010, 77, 4331, 78, 4704, 79, 5144, 80, 5671, 81, 6313, 82, 7115, 83, 8144, 84, 9514, 85, 11430, 86, 14300, 87, 19081, 88, 28636, 89, 57289 }); sqrttable = ({ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }); nsqrt = sizeof(sqrttable); } string repeat_str(string ch, int n) { int i; string tmp; if (n<0) return ""; tmp = ""; for (i=0;i<n;i++) tmp += ch; return tmp; } int sin(int theta) { int sign; /* this returns the sin of an agnle * 1000 */ while(theta>360) theta -= 360; while(theta<0) theta += 360; if (theta > 180) { sign=-1; theta -= 180; } else sign = 1; if (theta>90) theta = 180 - theta; return sign * sintable[theta*2+1]; } int asin(int ratio) { int sign; int up, down, current; if (ratio>1000 || ratio < -1000) { throw("asin: illegal argument"); return 0; } if (ratio>=0) sign = 1; else { sign = -1; ratio = -ratio; } up = 90; down = 0; current = (up+down)/2; /* a binary search - worse case would take only 9 loops */ while(current!=up && current!=down) { int tmp; if ((tmp=sintable[current*2+1]) == ratio) return sign * current; if (tmp < ratio) down = current; else up = current; current = (up+down)/2; } return sign*current; } int atan(int ratio) { int sign; int up, down,current; sign = 1; if (ratio<0) { sign = -1; ratio = -ratio; } up = 90; down = 0; current = (up+down)/2; /* a binary search - worse case would take only 9 loops */ while(current!=up && current!=down) { int tmp; if ((tmp=tantable[current*2+1]) == ratio) return sign * current; if (tmp < ratio) down = current; else up = current; current = (up+down)/2; } return sign*current; } /* 0 <= atan2 <= 2 PI */ int atan2(int x,int y) { int ret; if (!x) { if (y>=0) return 90; else return 270; } ret=atan(y*1000/x)+(x>0? 0 : 180) ; return ret; } int cos(int theta) { return sin(theta + 90); } int tan(int theta) { int sign; /* this returns the sin of an agnle * 1000 */ while(theta>180) theta -= 180; while(theta<0) theta += 180; if (theta==90) { throw("tan: division by zero"); /* chuckle */ return 0; } sign = 1; if (theta > 90) { sign = -1; theta = 180 - theta; } return sign * tantable[theta*2+1]; } int sqrt(int num) { int len, up, down, current; string numstr; if (num<0) { throw("sqrt: negative"); return 0; } if (!num) return 0; if (num<nsqrt) return sqrttable[num]; /* make an educated guess */ numstr=""+num; len = strlen(numstr); if (len/2*2==len) { /* even number of digits */ sscanf(repeat_str("9",len/2),"%d",up); sscanf("1"+repeat_str("0",len/2-1),"%d",down); } else { sscanf(repeat_str("9",len/2+1),"%d",up); sscanf("1"+repeat_str("0",len/2),"%d",down); } /* do a binary search within the 2 limits */ current = (up+down)/2; while(current!=up && current!=down) { int tmp; tmp = current*current; if (tmp==num) return current; if (tmp < num) down = current; else up = current; current = (up+down)/2; } return current; }