/* 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;
}