Gama C Library
Gama C API Documentation
math.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef GM_MATH
4#define GM_MATH
5#endif
6
7/**
8 * @def PI
9 * @brief The mathematical constant Pi (π).
10 */
11#define PI 3.14159265358979324
12/**
13 * @def M_PI
14 * @brief Alias for the mathematical constant Pi (π).
15 */
16#define M_PI PI
17/**
18 * @def EPS
19 * @brief A small epsilon value used for floating-point comparisons.
20 */
21#define EPS 1e-17
22/**
23 * @def ln10
24 * @brief The natural logarithm of 10.
25 */
26#define ln10 2.30258509299404590109
27/**
28 * @def INF
29 * @brief Represents positive infinity for double-precision floating-point numbers.
30 */
31#define INF 1.0 / 0.0
32/**
33 * @def NAN
34 * @brief Represents "Not a Number" for double-precision floating-point numbers.
35 */
36#define NAN 0.0 / 0.0
37/**
38 * @def MAX_double
39 * @brief The maximum representable value for a double-precision floating-point number.
40 */
41#define MAX_double 1.7976931348623158e308
42
43/**
44 * @internal
45 * @brief Structure to represent a double in scientific notation components.
46 */
47struct special {
48 int sign;
49 double mantisa;
50 double pow;
51 int e;
52};
53
54// Function declarations (forward declarations for custom implementations)
55double tan(double x);
56double cos(double x);
57double sin(double x);
58double ceil(double x);
59double floor(double x);
60double atan(double x);
61double acos(double x);
62double asin(double x);
63double fmod(double x, double y);
64double exp(double x);
65double log(double x);
66double sqrt(double x);
67double pow(double base, double exp);
68double fabs(double x);
69
70/**
71 * @internal
72 * @brief Translates a double-precision float into its scientific notation components.
73 * @param x The double to translate.
74 * @param _special Pointer to a `special` struct to store the components.
75 */
76void translate(double x, struct special *_special);
77/**
78 * @internal
79 * @brief Helper for atan, specifically for values between -1 and 1.
80 */
81double atan_1_1(double x);
82/**
83 * @internal
84 * @brief Helper function to normalize an angle to the range [-PI, PI].
85 * @param x The angle in radians.
86 * @return The normalized angle.
87 */
88double delete (double x); // Note: 'delete' is a C++ keyword, consider renaming.
89/**
90 * @internal
91 * @brief Helper for log, for values outside [0, 2).
92 */
93double log_other(double x);
94/**
95 * @internal
96 * @brief Helper for log, for values between [0, 2).
97 */
98double log_0_2(double x);
99
100/**
101 * @brief Calculates the cosine of an angle (in radians).
102 * @param x The angle in radians.
103 * @return The cosine of x.
104 */
105double cos(double x) {
106 x = delete (x);
107 return sin(PI / 2 - x);
108}
109
110/**
111 * @internal
112 * @brief Helper function to normalize an angle to the range [-PI, PI].
113 * @param x The angle in radians.
114 * @return The normalized angle.
115 */
116double delete (double x) {
117 while (x > PI || x < -PI) {
118 x += x > PI ? -2 * PI : 2 * PI;
119 }
120 return x;
121}
122
123/**
124 * @brief Calculates the sine of an angle (in radians).
125 * @param x The angle in radians.
126 * @return The sine of x.
127 */
128double sin(double x) {
129 x = delete (x);
130 double result = x, temp = x;
131 double i = 1.;
132 while (fabs(result) > EPS) {
133 result = -1 * result * x * x / (2 * i * (2 * i + 1));
134 i += 1.;
135 temp += result;
136 }
137 return temp;
138}
139
140/**
141 * @brief Calculates the tangent of an angle (in radians).
142 * @param x The angle in radians.
143 * @return The tangent of x, or NAN if x is an odd multiple of PI/2.
144 */
145double tan(double x) {
146 struct special _special;
147 double temp, c = cos(x);
148 translate(c, &_special);
149 ;
150 temp = _special.sign * sin(x) / _special.mantisa;
151 temp /= _special.pow;
152 return (x != -PI / 2 && x != PI / 2) ? temp : NAN;
153}
154
155/**
156 * @brief Calculates the smallest integer value greater than or equal to x.
157 * @param x The floating-point value.
158 * @return The ceiling of x.
159 */
160double ceil(double x) {
161 int i;
162 double temp = x < 0 ? -x : x;
163 for (i = 0; i < temp; i++) {
164 }
165 return x < 0 ? -i + 1 : i;
166}
167
168/**
169 * @brief Calculates the largest integer value less than or equal to x.
170 * @param x The floating-point value.
171 * @return The floor of x.
172 */
173double floor(double x) {
174 int i;
175 double temp = x < 0 ? -x : x;
176 for (i = 0; i < temp; i++) {
177 }
178 return x < 0 ? -i : x == 0 ? 0 : i - 1;
179}
180
181/**
182 * @brief Calculates the arctangent of x.
183 * @param x The floating-point value.
184 * @return The arctangent of x in radians, in the range [-PI/2, PI/2].
185 */
186double atan(double x) {
187 double temp = 0;
188 temp = (x < 1 && x > -1) ? atan_1_1(x) : temp;
189 temp = x == 1 ? PI / 4 : x == -1 ? -PI / 4 : x == 0 ? 0 : temp;
190 temp = x > 1 ? PI / 2 - atan_1_1(1 / x)
191 : x < -1 ? -PI / 2 - atan_1_1(1 / x)
192 : temp;
193 return temp;
194}
195
196/**
197 * @internal
198 * @brief Helper for atan, specifically for values between -1 and 1.
199 * @param x The value.
200 * @return The arctangent of x.
201 */
202double atan_1_1(double x) {
203 double result = x, temp = x, i = 1;
204 while (fabs(result) > EPS) {
205 result = -1 * result * x * x * (2 * i - 1) / (2 * i + 1);
206 i += 1;
207 temp += result;
208 }
209 return temp;
210}
211
212/**
213 * @brief Calculates the arccosine of x.
214 * @param x The floating-point value, expected to be in the range [-1, 1].
215 * @return The arccosine of x in radians, in the range [0, PI], or NAN if x is out of range.
216 */
217double acos(double x) {
218 return (x <= 1 && x >= -1)
219 ? fabs(x) == 1 ? PI * (1 - x) / 2 : PI / 2. - asin(x)
220 : NAN;
221}
222
223/**
224 * @brief Calculates the arcsine of x.
225 * @param x The floating-point value, expected to be in the range [-1, 1].
226 * @return The arcsine of x in radians, in the range [-PI/2, PI/2], or NAN if x is out of range.
227 */
228double asin(double x) {
229 double result = x, temp = x;
230 double i = 1;
231 while (fabs(result) > EPS) {
232 if (x < -1 || x > 1) {
233 temp = NAN;
234 break;
235 }
236 if (x == 1 || x == -1) {
237 temp = PI / 2 * x;
238 break;
239 }
240 result *=
241 x * x * (2 * i - 1) * (2 * i) * (2 * i - 1) / ((2 * i + 1) * 4 * i * i);
242 i += 1;
243 temp += result;
244 }
245 return temp;
246}
247
248/**
249 * @brief Calculates the floating-point remainder of x/y.
250 * @param x The numerator.
251 * @param y The denominator.
252 * @return The remainder with the same sign as x.
253 */
254double fmod(double x, double y) {
255 double result = fabs(x);
256 y = fabs(y);
257 int i = 1;
258 while (result > y) {
259 result = fabs(x) - y * i;
260 i++;
261 }
262 return x < 0 ? -result : result;
263}
264
265/**
266 * @brief Calculates the base-e exponential of x (e^x).
267 * @param x The exponent.
268 * @return The value of e raised to the power of x.
269 */
270double exp(double x) {
271 double result = 1, temp = 1;
272 double i = 1;
273 int flag = 0;
274 if (x < 0) {
275 x *= -1;
276 flag = 1;
277 }
278 while (fabs(result) > EPS) {
279 result *= x / i;
280 i += 1;
281 temp += result;
282 if (temp > MAX_double) {
283 temp = INF;
284 break;
285 }
286 }
287 temp = flag == 1 ? temp > MAX_double ? 0 : 1. / temp : temp;
288 return temp = temp > MAX_double ? INF : temp;
289}
290
291/**
292 * @brief Calculates the natural logarithm of x (ln(x)).
293 * @param x The floating-point value.
294 * @return The natural logarithm of x, or NAN if x is negative, or -INF if x is zero.
295 */
296double log(double x) {
297 double temp;
298 return temp = (x > 0 && x < 2) ? log_0_2(x) : log_other(x);
299}
300
301/**
302 * @internal
303 * @brief Helper for log, for values between [0, 2).
304 * @param x The value.
305 * @return The natural logarithm of x.
306 */
307double log_0_2(double x) {
308 x--;
309 double result = x, temp = x;
310 double i = 2;
311 while (fabs(result) > EPS) {
312 result *= -x * (i - 1) / i;
313 i += 1;
314 temp += result;
315 }
316 return temp;
317}
318
319/**
320 * @internal
321 * @brief Helper for log, for values outside [0, 2).
322 * @param x The value.
323 * @return The natural logarithm of x.
324 */
325double log_other(double x) {
326 struct special _special;
327 translate(x, &_special);
328 x = _special.mantisa * _special.sign / 10;
329 double result;
330 result = x < 0 ? -NAN : x == 0 ? -INF : log_0_2(x) + (_special.e + 1) * ln10;
331 return result;
332}
333
334/**
335 * @brief Calculates the square root of x.
336 * @param x The non-negative floating-point value.
337 * @return The square root of x, or NAN if x is negative.
338 */
339double sqrt(double x) {
340 double result = 4, temp = 0;
341 while (fabs(result - temp) > EPS) {
342 if (x < 0) {
343 result = -NAN;
344 break;
345 }
346 temp = result;
347 result = (temp + x / temp) / 2;
348 }
349 return result;
350}
351
352/**
353 * @brief Calculates the base raised to the power of the exponent (base^exp).
354 * @param base The base value.
355 * @param vexp The exponent value.
356 * @return The result of base raised to the power of exp.
357 */
358double pow(double base, double vexp) {
359 double result;
360 result = exp(vexp * log(base));
361 return result;
362}
363
364/**
365 * @brief Calculates the absolute value of a double.
366 * @param x The floating-point value.
367 * @return The absolute value of x.
368 */
369double fabs(double x) { return x < 0 ? x *= -1. : x; }
370
371/**
372 * @internal
373 * @brief Translates a double-precision float into its scientific notation components.
374 * @param x The double to translate.
375 * @param _special Pointer to a `special` struct to store the components.
376 */
377void translate(double x, struct special *_special) {
378 double i = 1;
379 int es = 0;
380 _special->sign = x < 0 ? -1 : 1;
381 x *= _special->sign;
382 if (x >= 10) {
383 while (x >= 10) {
384 x /= 10.;
385 i *= 10;
386 es++;
387 }
388 } else if (x < 1 && x > 0) {
389 while (x < 1) {
390 x *= 10;
391 i /= 10;
392 es--;
393 }
394 }
395 _special->mantisa = x;
396 _special->pow = i;
397 _special->e = es;
398}
399
400/**
401 * @brief Returns the smaller of two integer values.
402 * @param a The first integer.
403 * @param b The second integer.
404 * @return The smaller of a and b.
405 */
406int min(int a, int b) { return a > b ? b : a; }
407/**
408 * @brief Returns the smaller of two double values.
409 * @param a The first double.
410 * @param b The second double.
411 * @return The smaller of a and b.
412 */
413double fmin(double a, double b) { return a > b ? b : a; }
414
415/**
416 * @brief Returns the larger of two integer values.
417 * @param a The first integer.
418 * @param b The second integer.
419 * @return The larger of a and b.
420 */
421int max(int a, int b) { return a < b ? b : a; }
422/**
423 * @brief Returns the larger of two double values.
424 * @param a The first double.
425 * @param b The second double.
426 * @return The larger of a and b.
427 */
428double fmax(double a, double b) { return a < b ? b : a; }
double log_other(double x)
Definition math.h:325
#define INF
Represents positive infinity for double-precision floating-point numbers.
Definition math.h:31
double fmin(double a, double b)
Returns the smaller of two double values.
Definition math.h:413
double atan(double x)
Calculates the arctangent of x.
Definition math.h:186
double ceil(double x)
Calculates the smallest integer value greater than or equal to x.
Definition math.h:160
#define ln10
The natural logarithm of 10.
Definition math.h:26
double log_0_2(double x)
Definition math.h:307
double fmax(double a, double b)
Returns the larger of two double values.
Definition math.h:428
double fmod(double x, double y)
Calculates the floating-point remainder of x/y.
Definition math.h:254
double atan_1_1(double x)
Definition math.h:202
#define PI
The mathematical constant Pi (π).
Definition math.h:11
double cos(double x)
Calculates the cosine of an angle (in radians).
Definition math.h:105
double floor(double x)
Calculates the largest integer value less than or equal to x.
Definition math.h:173
#define EPS
A small epsilon value used for floating-point comparisons.
Definition math.h:21
#define NAN
Represents "Not a Number" for double-precision floating-point numbers.
Definition math.h:36
double pow(double base, double exp)
Calculates the base raised to the power of the exponent (base^exp).
Definition math.h:358
double fabs(double x)
Calculates the absolute value of a double.
Definition math.h:369
double tan(double x)
Calculates the tangent of an angle (in radians).
Definition math.h:145
double asin(double x)
Calculates the arcsine of x.
Definition math.h:228
double sin(double x)
Calculates the sine of an angle (in radians).
Definition math.h:128
double sqrt(double x)
Calculates the square root of x.
Definition math.h:339
int min(int a, int b)
Returns the smaller of two integer values.
Definition math.h:406
#define MAX_double
The maximum representable value for a double-precision floating-point number.
Definition math.h:41
double log(double x)
Calculates the natural logarithm of x (ln(x)).
Definition math.h:296
double exp(double x)
Calculates the base-e exponential of x (e^x).
Definition math.h:270
void translate(double x, struct special *_special)
Definition math.h:377
double acos(double x)
Calculates the arccosine of x.
Definition math.h:217
int max(int a, int b)
Returns the larger of two integer values.
Definition math.h:421
Definition math.h:47
double pow
Definition math.h:50
int sign
Definition math.h:48
int e
Definition math.h:51
double mantisa
Definition math.h:49