aboutsummaryrefslogtreecommitdiff
path: root/div.c
blob: 9ee232d2533143d90dbe5085f8a72f601375e189 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <stdio.h>
#include <stdlib.h>

/*
example: 10 / 3

num   denom   quotient    result
10    3       1           0
10    6       2           2
4     3       1           3
*/

/*
	// working, let's simplify it.
int divide(int num, int denom) {
	int result = 0, quotient = 1, newdenom;
	fprintf(stderr, "\tdivide(%d, %d)\n", num, denom);
	do {
		fprintf(stderr, "outer loop\n");
		newdenom = denom;
		quotient = 1;
		if(newdenom > num) {
			fprintf(stderr, "%d > %d: quotient = 0;\n", newdenom, num);
			quotient = 0;
			num = 0;
			// return result;
		} else if(newdenom == num) {
			fprintf(stderr, "%d == %d: quotient = 1;\n", newdenom, num);
			quotient = 1;
			num = 0;
			// return ++result;
		} else {
			while(newdenom <= num) {
				fprintf(stderr, "inner loop %d %d %d\n", num, newdenom, quotient);
				newdenom <<= 1;
				quotient <<= 1;
			}
			newdenom >>= 1;
			num -= newdenom;
			quotient >>= 1;
		}
		result += quotient;
		fprintf(stderr, "num==%d, newdenom==%d, quotient==%d, result==%d\n", num, newdenom, quotient, result);
	} while(num);
	return result;
}
*/

int divide(int num, int denom) {
	int result, quotient, newdenom, halfnum;

	result = 0;
outerloop:
	newdenom = denom;
	quotient = 1;

	if(newdenom < num)
		goto innerprep;
	if(newdenom == num)
		goto innerprep;

	quotient = 0;
	num = 0;
	goto addquot;

innerprep:
	halfnum = num >> 1;

innerloop:
	if(newdenom > halfnum)
		goto innerdone;
	newdenom <<= 1;
	quotient <<= 1;
	goto innerloop;

innerdone:
	num -= newdenom;

addquot:
	result += quotient;
	if(num) goto outerloop;

	return result;
}

/*
	// working, but recursive, doesn't lend itself well to
	// rewriting in asm.
int divide(int num, int denom) {
	int quotient = 1, olddenom = denom;
	fprintf(stderr, "\tdivide(%d, %d)\n", num, denom);
	if(denom > num) return 0;
	if(denom == num) return 1;
	while(denom <= num) {
		denom <<= 1;
		quotient <<= 1;
		fprintf(stderr, "num==%d, denom==%d, quotient==%d\n", num, denom, quotient);
	}
	num -= (denom >> 1);
	return ((quotient >> 1) + divide(num, olddenom));
}
*/

int main(int argc, char **argv) {
	int num = 100, denom = 10, result1, result2;

	if(argc > 1) num = atoi(argv[1]);
	if(argc > 2) denom = atoi(argv[2]);
	result1 = num / denom;
	result2 = divide(num, denom);
	printf("%d / %d == %d\n", num, denom, result1);
	printf("divide(%d, %d) == %d\n", num, denom, result2);
	if(result1 == result2) {
		puts("OK");
		return 0;
	}
	puts("FAIL");
	return 1;
}