This repository was archived by the owner on Oct 9, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrigonometry.c
More file actions
306 lines (302 loc) · 14.8 KB
/
Copy pathtrigonometry.c
File metadata and controls
306 lines (302 loc) · 14.8 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*
This is an advanced example of how to embed Assembly
produced by ArithmeticExpressionCompiler
into C programs that can be compiled with GCC and CLANG.
For an introduction into the topic, see:
https://flatassembler.github.io/quadratic.c
*/
int printf(const char*, ...);
/* Because GCC 4.8.5, for some reason that escapes me,
crashes if you try to include "stdio.h" on 64-bit Oracle Linux 7
while setting it to be in 32-bit mode and telling it to compile this program (Seriously!).*/
float result, i, delta, sinArray[314], cosArray[314], pi;
int main() {
printf("rad\tdeg\tsin\tcos\ttan\n");
#ifndef _WIN32
/*
So, this program uses one of the simplest and yet the fastest ways of
approximating the values of trigonometric functions in radians.
It works by sin(0)=0, cos(0)=1, the derivative of sine in radians being equal to the cosine,
and the derivative of cosine being equal to the negative sine.
So, all you need to do to approximate the sine and cosine of a given
angle in radians is to pick some small delta,
and then (angle/delta) times add delta*cosine to the temporary value of sine,
and at the same time keep subtracting delta*sine from the temporary value of cosine.
*/
asm(".intel_syntax\n"
"#Generated by Arithmetic Expression Compiler (http://flatassembler.000webhostapp.com/compiler.html) run in Duktape.\n"
"#delta:=1/100\n"
"finit\n"
"mov dword ptr [result],0x3F800000 #1\n"
"fld dword ptr [result]\n"
"mov dword ptr [result],0x42C80000 #100\n"
"fld dword ptr [result]\n"
"fdivp #st1,st0\n"
"fstp dword ptr [result]\n"
"push dword ptr [result]\n"
"pop dword ptr [delta]\n"
"#i:=0\n"
"finit\n"
"mov dword ptr [result],0x0 #0\n"
"fld dword ptr [result]\n"
"fstp dword ptr [result]\n"
"push dword ptr [result]\n"
"pop dword ptr [i]\n"
"#sinArray[i]:=i\n"
"finit\n"
"fld dword ptr [i]\n"
"fstp dword ptr [result]\n"
"push dword ptr [result]\n"
"fld dword ptr [i]\n"
"fistp dword ptr [result]\n"
"mov ebx, dword ptr [result]\n"
/* Older versions of GAS apparently require you to explicitly denote that "[result]" is a 32-bit pointer,
even when you are explicitly moving what it points to... to a 32-bit register (in this case "ebx").*/
"pop dword ptr [sinArray+4*ebx]\n"
"#cosArray[i]:=1\n"
"finit\n"
"mov dword ptr [result],0x3F800000 #1\n"
"fld dword ptr [result]\n"
"fstp dword ptr [result]\n"
"push dword ptr [result]\n"
"fld dword ptr [i]\n"
"fistp dword ptr [result]\n"
"mov ebx, dword ptr[result]\n"
"pop dword ptr [cosArray+4*ebx]\n"
"#While i<314\n"
"finit\n"
"l628623:\n"
"fld dword ptr [i]\n"
"mov dword ptr [result],0x439D0000 #314\n"
"fld dword ptr [result]\n"
"#fcomip #st1\n" //Older versions of GAS, such as the GAS 2.27, one shipped with Oracle Linux 7, apparently don't support "fcomip".
"fcomi\nfstp dword ptr [result]\n" //Nevertheless, there is an obvious and simple work-around.
"mov dword ptr [sinArray],0\n" //I don't know why this is necessary, apparently "fcomip" isn't the same as "fcomi"+"fstp", however, this appears to fix the issue.
"fstp dword ptr [result]\n"
"jna l280382\n"
"fld1\n"
"jmp l837287\n"
"l280382:\n"
"fldz\n"
"l837287:\n"
"fistp dword ptr [result]\n"
"mov eax,dword ptr [result]\n"
"test eax,eax\n"
"je l467414\n"
"#i:=i+1\n"
"finit\n"
"fld dword ptr [i]\n"
"mov dword ptr [result],0x3F800000 #1\n"
"fld dword ptr [result]\n"
"faddp #st1,st0\n"
"fstp dword ptr [result]\n"
"push dword ptr [result]\n"
"pop dword ptr [i]\n"
"#sinArray[i]:=sinArray(i-1)+delta*cosArray(i-1)\n"
"finit\n"
"fld dword ptr [i]\n"
"mov dword ptr [result],0x3F800000 #1\n"
"fld dword ptr [result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [result]\n"
"mov ebx,dword ptr [result]\n"
"fld dword ptr [cosArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
/*GAS, unlike FlatAssembler, takes care of the differences between 32-bit and 64-bit here,
you don't need to do anything in this case.*/
"fld dword ptr [delta]\n"
"fxch\n"
"fmulp #st1,st0\n"
"fld dword ptr [i]\n"
"mov dword ptr [result],0x3F800000 #1\n"
"fld dword ptr [result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [result]\n"
"mov ebx, dword ptr [result]\n"
"fld dword ptr [sinArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
"fxch\n"
"faddp #st1,st0\n"
"fstp dword ptr [result]\n"
"push dword ptr [result]\n"
"fld dword ptr [i]\n"
"fistp dword ptr [result]\n"
"mov ebx, dword ptr [result]\n"
"pop dword ptr [sinArray+4*ebx]\n"
"#cosArray[i]:=cosArray(i-1)-delta*sinArray(i-1)\n"
"finit\n"
"fld dword ptr [i]\n"
"mov dword ptr [result],0x3F800000 #1\n"
"fld dword ptr [result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [result]\n"
"mov ebx, dword ptr [result]\n"
"fld dword ptr [sinArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
"fld dword ptr [delta]\n"
"fxch\n"
"fmulp #st1,st0\n"
"fld dword ptr [i]\n"
"mov dword ptr [result],0x3F800000 #1\n"
"fld dword ptr [result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [result]\n"
"mov ebx,dword ptr [result]\n"
"fld dword ptr [cosArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
"fxch\n"
"fsubp #st1,st0\n"
"fstp dword ptr [result]\n"
"push dword ptr [result]\n"
"fld dword ptr [i]\n"
"fistp dword ptr [result]\n"
"mov ebx,dword ptr [result]\n"
"pop dword ptr [cosArray+4*ebx]\n"
"#EndWhile\n"
"finit\n"
"jmp l628623\n"
"l467414:\n"
".att_syntax\n");
#else //So, what follows is a code that can be compiled with a fairly recent version of GCC, TDM-GCC 5.1.0, running on Windows.
asm(".intel_syntax\n"
"#Generated by Arithmetic Expression Compiler (http://flatassembler.000webhostapp.com/compiler.html) run in Duktape.\n"
"#delta:=1/100\n"
"finit\n"
"mov dword ptr [_result],0x3F800000 #1\n"
"fld dword ptr [_result]\n"
"mov dword ptr [_result],0x42C80000 #100\n"
"fld dword ptr [_result]\n"
"fdivp #st1,st0\n"
"fstp dword ptr [_result]\n"
"push dword ptr [_result]\n"
"pop dword ptr [_delta]\n"
"#i:=0\n"
"finit\n"
"mov dword ptr [_result],0x0 #0\n"
"fld dword ptr [_result]\n"
"fstp dword ptr [_result]\n"
"push dword ptr [_result]\n"
"pop dword ptr [_i]\n"
"#sinArray[i]:=i\n"
"finit\n"
"fld dword ptr [_i]\n"
"fstp dword ptr [_result]\n"
"push dword ptr [_result]\n"
"fld dword ptr [_i]\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"pop dword ptr [_sinArray+4*ebx]\n"
"#cosArray[i]:=1\n"
"finit\n"
"mov dword ptr [_result],0x3F800000 #1\n"
"fld dword ptr [_result]\n"
"fstp dword ptr [_result]\n"
"push dword ptr [_result]\n"
"fld dword ptr [_i]\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"pop dword ptr [_cosArray+4*ebx]\n"
"#While i<314\n"
"finit\n"
"l628623:\n"
"fld dword ptr [_i]\n"
"mov dword ptr [_result],0x439D0000 #314\n"
"fld dword ptr [_result]\n"
"fcomip #st1\n"
"fstp dword ptr [_result]\n"
"jna l280382\n"
"fld1\n"
"jmp l837287\n"
"l280382:\n"
"fldz\n"
"l837287:\n"
"fistp dword ptr [_result]\n"
"mov eax,[_result]\n"
"test eax,eax\n"
"je l467414\n"
"#i:=i+1\n"
"finit\n"
"fld dword ptr [_i]\n"
"mov dword ptr [_result],0x3F800000 #1\n"
"fld dword ptr [_result]\n"
"faddp #st1,st0\n"
"fstp dword ptr [_result]\n"
"push dword ptr [_result]\n"
"pop dword ptr [_i]\n"
"#sinArray[i]:=sinArray(i-1)+delta*cosArray(i-1)\n"
"finit\n"
"fld dword ptr [_i]\n"
"mov dword ptr [_result],0x3F800000 #1\n"
"fld dword ptr [_result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"fld dword ptr [_cosArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
"fld dword ptr [_delta]\n"
"fxch\n"
"fmulp #st1,st0\n"
"fld dword ptr [_i]\n"
"mov dword ptr [_result],0x3F800000 #1\n"
"fld dword ptr [_result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"fld dword ptr [_sinArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
"fxch\n"
"faddp #st1,st0\n"
"fstp dword ptr [_result]\n"
"push dword ptr [_result]\n"
"fld dword ptr [_i]\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"pop dword ptr [_sinArray+4*ebx]\n"
"#cosArray[i]:=cosArray(i-1)-delta*sinArray(i-1)\n"
"finit\n"
"fld dword ptr [_i]\n"
"mov dword ptr [_result],0x3F800000 #1\n"
"fld dword ptr [_result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"fld dword ptr [_sinArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
"fld dword ptr [_delta]\n"
"fxch\n"
"fmulp #st1,st0\n"
"fld dword ptr [_i]\n"
"mov dword ptr [_result],0x3F800000 #1\n"
"fld dword ptr [_result]\n"
"fsubp #st1,st0\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"fld dword ptr [_cosArray+4*ebx] #In case the program is supposed to be 16-bit, simply replace 'ebx' with 'bx'. In case it's 64-bit, replace the 'mov' in the last directive with 'movsx' and 'ebx' with 'rbx' in both this and the last directive.\n"
"fxch\n"
"fsubp #st1,st0\n"
"fstp dword ptr [_result]\n"
"push dword ptr [_result]\n"
"fld dword ptr [_i]\n"
"fistp dword ptr [_result]\n"
"mov ebx,[_result]\n"
"pop dword ptr [_cosArray+4*ebx]\n"
"#EndWhile\n"
"finit\n"
"jmp l628623\n"
"l467414:\n"
".att_syntax\n");
#endif
asm(".intel_syntax\n"
"fldpi\n"
#ifdef _WIN32
"fstp dword ptr [_pi]\n"
#else
"fstp dword ptr [pi]\n"
#endif
".att_syntax"
); /*I am not sure what would be a more portable way of getting
the value of pi between different C compilers,
especially if you have access to x86 assembly.*/
int i;
for (i = 0; i < 314; i++) {
printf("%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n",
(float) i / 100,
(float) i / 100 * (180 / pi),
sinArray[i],
cosArray[i],
sinArray[i] / cosArray[i]);
}
}