Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | |||
29 | /** @file | ||
30 | * @brief Basic arithmetic utilities optimized for GATE types | ||
31 | * @ingroup gatecore_cpp | ||
32 | */ | ||
33 | |||
34 | #ifndef GATE_MATHEMATICS_HPP_INCLUDED | ||
35 | #define GATE_MATHEMATICS_HPP_INCLUDED | ||
36 | |||
37 | #include "gate/gate_core_api.hpp" | ||
38 | #include "gate/gatetypes.hpp" | ||
39 | #include "gate/typetraits.hpp" | ||
40 | #include "gate/mathematics.h" | ||
41 | |||
42 | namespace gate | ||
43 | { | ||
44 | |||
45 | namespace math | ||
46 | { | ||
47 | |||
48 | GATE_CORE_CPP_API extern real64_t const PI; | ||
49 | GATE_CORE_CPP_API extern real64_t const E; | ||
50 | |||
51 | |||
52 | /// @brief | ||
53 | /// @tparam T | ||
54 | /// @param num | ||
55 | /// @return | ||
56 | 3 | template<class T> bool_t isZero(T num) | |
57 | { | ||
58 | 3 | return num == T(0); | |
59 | } | ||
60 | |||
61 | |||
62 | /// @brief | ||
63 | /// @param num | ||
64 | /// @return | ||
65 | GATE_CORE_CPP_API bool_t isZero(real32_t num); | ||
66 | |||
67 | |||
68 | /// @brief | ||
69 | /// @param num | ||
70 | /// @return | ||
71 | GATE_CORE_CPP_API bool_t isZero(real64_t num); | ||
72 | |||
73 | |||
74 | /// @brief | ||
75 | /// @tparam T | ||
76 | /// @param num | ||
77 | /// @return | ||
78 | 1 | template<class T> bool_t isNan(T num) | |
79 | { | ||
80 | 1 | return !traits::IsNumeric<T>::value; | |
81 | } | ||
82 | |||
83 | |||
84 | /// @brief | ||
85 | /// @param num | ||
86 | /// @return | ||
87 | GATE_CORE_CPP_API bool_t isNan(real32_t num); | ||
88 | |||
89 | |||
90 | /// @brief | ||
91 | /// @param num | ||
92 | /// @return | ||
93 | GATE_CORE_CPP_API bool_t isNan(real64_t num); | ||
94 | |||
95 | |||
96 | /// @brief | ||
97 | /// @tparam T | ||
98 | /// @param num | ||
99 | /// @return | ||
100 | 1 | template<class T> bool_t isInfinite(T num) | |
101 | { | ||
102 | 1 | return false; | |
103 | } | ||
104 | |||
105 | |||
106 | /// @brief | ||
107 | /// @param num | ||
108 | /// @return | ||
109 | GATE_CORE_CPP_API bool_t isInfinite(real32_t num); | ||
110 | |||
111 | |||
112 | /// @brief | ||
113 | /// @param num | ||
114 | /// @return | ||
115 | GATE_CORE_CPP_API bool_t isInfinite(real64_t num); | ||
116 | |||
117 | |||
118 | /// @brief | ||
119 | /// @tparam T | ||
120 | /// @param num | ||
121 | /// @return | ||
122 | template<class T> int signum(T num) | ||
123 | { | ||
124 | return isZero(num) ? 0 : ((num < T(0)) ? -1 : 1); | ||
125 | } | ||
126 | |||
127 | |||
128 | /// @brief | ||
129 | /// @param num | ||
130 | /// @return | ||
131 | GATE_CORE_CPP_API int signum(int8_t num); | ||
132 | |||
133 | |||
134 | /// @brief | ||
135 | /// @param num | ||
136 | /// @return | ||
137 | GATE_CORE_CPP_API int signum(int16_t num); | ||
138 | |||
139 | |||
140 | /// @brief | ||
141 | /// @param num | ||
142 | /// @return | ||
143 | GATE_CORE_CPP_API int signum(int32_t num); | ||
144 | |||
145 | |||
146 | /// @brief | ||
147 | /// @param num | ||
148 | /// @return | ||
149 | GATE_CORE_CPP_API int signum(int64_t num); | ||
150 | |||
151 | |||
152 | /// @brief | ||
153 | /// @param num | ||
154 | /// @return | ||
155 | GATE_CORE_CPP_API int signum(real32_t num); | ||
156 | |||
157 | |||
158 | /// @brief | ||
159 | /// @param num | ||
160 | /// @return | ||
161 | GATE_CORE_CPP_API int signum(real64_t num); | ||
162 | |||
163 | |||
164 | /// @brief | ||
165 | /// @param num | ||
166 | /// @return | ||
167 | GATE_CORE_CPP_API int8_t abs(int8_t num); | ||
168 | |||
169 | |||
170 | /// @brief | ||
171 | /// @param num | ||
172 | /// @return | ||
173 | GATE_CORE_CPP_API int16_t abs(int16_t num); | ||
174 | |||
175 | |||
176 | /// @brief | ||
177 | /// @param num | ||
178 | /// @return | ||
179 | GATE_CORE_CPP_API int32_t abs(int32_t num); | ||
180 | |||
181 | |||
182 | /// @brief | ||
183 | /// @param num | ||
184 | /// @return | ||
185 | GATE_CORE_CPP_API int64_t abs(int64_t num); | ||
186 | |||
187 | |||
188 | /// @brief | ||
189 | /// @param num | ||
190 | /// @return | ||
191 | GATE_CORE_CPP_API real32_t abs(real32_t num); | ||
192 | |||
193 | |||
194 | /// @brief | ||
195 | /// @param num | ||
196 | /// @return | ||
197 | GATE_CORE_CPP_API real64_t abs(real64_t num); | ||
198 | |||
199 | |||
200 | #if !defined(GATE_COMPILER_SUPPORTS_CPP_PARTIAL_TEMPLATE_SPECIALIZATION) | ||
201 | |||
202 | template<class T> T abs(T num) | ||
203 | { | ||
204 | if (num < T(0)) | ||
205 | { | ||
206 | return -num; | ||
207 | } | ||
208 | return num; | ||
209 | } | ||
210 | |||
211 | #else | ||
212 | |||
213 | namespace | ||
214 | { | ||
215 | |||
216 | template<class T, bool SIGN> struct AbsImpl; | ||
217 | |||
218 | template<class T> struct AbsImpl<T, true> | ||
219 | { | ||
220 | static T abs(T num) | ||
221 | { | ||
222 | if (num < T(0)) | ||
223 | { | ||
224 | return -num; | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | return num; | ||
229 | } | ||
230 | } | ||
231 | }; | ||
232 | template<class T> struct AbsImpl<T, false> | ||
233 | { | ||
234 | 1 | static T abs(T num) | |
235 | { | ||
236 | 1 | return num; | |
237 | } | ||
238 | }; | ||
239 | } // end of anonymous namespace | ||
240 | |||
241 | |||
242 | /// @brief | ||
243 | /// @tparam T | ||
244 | /// @param num | ||
245 | /// @return | ||
246 | 1 | template<class T> T abs(T num) | |
247 | { | ||
248 | 1 | return AbsImpl<T, gate::traits::IsSigned<T>::value>::abs(num); | |
249 | } | ||
250 | #endif | ||
251 | |||
252 | /// @brief | ||
253 | /// @tparam T | ||
254 | /// @param num1 | ||
255 | /// @param num2 | ||
256 | /// @return | ||
257 | 1 | template<class T> T minimum(T num1, T num2) | |
258 | { | ||
259 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | return num1 < num2 ? num1 : num2; |
260 | } | ||
261 | |||
262 | |||
263 | /// @brief | ||
264 | /// @tparam T | ||
265 | /// @param num1 | ||
266 | /// @param num2 | ||
267 | /// @return | ||
268 | 1 | template<class T> T maximum(T num1, T num2) | |
269 | { | ||
270 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | return num1 < num2 ? num2 : num1; |
271 | } | ||
272 | |||
273 | |||
274 | /// @brief | ||
275 | /// @tparam T | ||
276 | /// @param num | ||
277 | /// @return | ||
278 | template<class T> uint8_t decimal_length(T num); | ||
279 | GATE_CORE_CPP_API real32_t decimal_length(real32_t num); | ||
280 | GATE_CORE_CPP_API real64_t decimal_length(real64_t num); | ||
281 | |||
282 | |||
283 | /// @brief | ||
284 | /// @tparam T | ||
285 | /// @param num | ||
286 | /// @return | ||
287 | template<class T> T cos(T num); | ||
288 | GATE_CORE_CPP_API real32_t cos(real32_t num); | ||
289 | GATE_CORE_CPP_API real64_t cos(real64_t num); | ||
290 | |||
291 | |||
292 | /// @brief | ||
293 | /// @tparam T | ||
294 | /// @param num | ||
295 | /// @return | ||
296 | template<class T> T sin(T num); | ||
297 | GATE_CORE_CPP_API real32_t sin(real32_t num); | ||
298 | GATE_CORE_CPP_API real64_t sin(real64_t num); | ||
299 | |||
300 | |||
301 | /// @brief | ||
302 | /// @tparam T | ||
303 | /// @param num | ||
304 | /// @return | ||
305 | template<class T> T tan(T num); | ||
306 | GATE_CORE_CPP_API real32_t tan(real32_t num); | ||
307 | GATE_CORE_CPP_API real64_t tan(real64_t num); | ||
308 | |||
309 | |||
310 | /// @brief | ||
311 | /// @tparam T | ||
312 | /// @param num | ||
313 | /// @return | ||
314 | template<class T> T acos(T num); | ||
315 | GATE_CORE_CPP_API real32_t acos(real32_t num); | ||
316 | GATE_CORE_CPP_API real64_t acos(real64_t num); | ||
317 | |||
318 | |||
319 | /// @brief | ||
320 | /// @tparam T | ||
321 | /// @param num | ||
322 | /// @return | ||
323 | template<class T> T asin(T num); | ||
324 | GATE_CORE_CPP_API real32_t asin(real32_t num); | ||
325 | GATE_CORE_CPP_API real64_t asin(real64_t num); | ||
326 | |||
327 | |||
328 | /// @brief | ||
329 | /// @tparam T | ||
330 | /// @param num | ||
331 | /// @return | ||
332 | template<class T> T atan(T num); | ||
333 | GATE_CORE_CPP_API real32_t atan(real32_t num); | ||
334 | GATE_CORE_CPP_API real64_t atan(real64_t num); | ||
335 | |||
336 | |||
337 | /// @brief | ||
338 | /// @tparam T | ||
339 | /// @param y | ||
340 | /// @param x | ||
341 | /// @return | ||
342 | template<class T> T atan2(T y, T x); | ||
343 | GATE_CORE_CPP_API real32_t atan2(real32_t y, real32_t x); | ||
344 | GATE_CORE_CPP_API real64_t atan2(real64_t y, real64_t x); | ||
345 | |||
346 | |||
347 | /// @brief | ||
348 | /// @tparam T | ||
349 | /// @param num | ||
350 | /// @return | ||
351 | template<class T> T cosh(T num); | ||
352 | GATE_CORE_CPP_API real32_t cosh(real32_t num); | ||
353 | GATE_CORE_CPP_API real64_t cosh(real64_t num); | ||
354 | |||
355 | |||
356 | /// @brief | ||
357 | /// @tparam T | ||
358 | /// @param num | ||
359 | /// @return | ||
360 | template<class T> T sinh(T num); | ||
361 | GATE_CORE_CPP_API real32_t sinh(real32_t num); | ||
362 | GATE_CORE_CPP_API real64_t sinh(real64_t num); | ||
363 | |||
364 | |||
365 | /// @brief | ||
366 | /// @tparam T | ||
367 | /// @param num | ||
368 | /// @return | ||
369 | template<class T> T tanh(T num); | ||
370 | GATE_CORE_CPP_API real32_t tanh(real32_t num); | ||
371 | GATE_CORE_CPP_API real64_t tanh(real64_t num); | ||
372 | |||
373 | |||
374 | /// @brief | ||
375 | /// @tparam T | ||
376 | /// @param num | ||
377 | /// @return | ||
378 | template<class T> T acosh(T num); | ||
379 | GATE_CORE_CPP_API real32_t acosh(real32_t num); | ||
380 | GATE_CORE_CPP_API real64_t acosh(real64_t num); | ||
381 | |||
382 | |||
383 | |||
384 | /// @brief | ||
385 | /// @tparam T | ||
386 | /// @param num | ||
387 | /// @return | ||
388 | template<class T> T asinh(T num); | ||
389 | GATE_CORE_CPP_API real32_t asinh(real32_t num); | ||
390 | GATE_CORE_CPP_API real64_t asinh(real64_t num); | ||
391 | |||
392 | |||
393 | |||
394 | /// @brief | ||
395 | /// @tparam T | ||
396 | /// @param num | ||
397 | /// @return | ||
398 | template<class T> T atanh(T num); | ||
399 | GATE_CORE_CPP_API real32_t atanh(real32_t num); | ||
400 | GATE_CORE_CPP_API real64_t atanh(real64_t num); | ||
401 | |||
402 | |||
403 | /// @brief | ||
404 | /// @tparam T | ||
405 | /// @param num | ||
406 | /// @return | ||
407 | template<class T> T exp(T num); | ||
408 | GATE_CORE_CPP_API real32_t exp(real32_t num); | ||
409 | GATE_CORE_CPP_API real64_t exp(real64_t num); | ||
410 | |||
411 | |||
412 | /// @brief | ||
413 | /// @tparam T | ||
414 | /// @param num | ||
415 | /// @param exp | ||
416 | /// @return | ||
417 | template<class T> T frexp(T num, int* exp); | ||
418 | GATE_CORE_CPP_API real32_t frexp(real32_t num, int* exp); | ||
419 | GATE_CORE_CPP_API real64_t frexp(real64_t num, int* exp); | ||
420 | |||
421 | |||
422 | /// @brief | ||
423 | /// @tparam T | ||
424 | /// @param num | ||
425 | /// @param exp | ||
426 | /// @return | ||
427 | template<class T> T ldexp(T num, int exp); | ||
428 | GATE_CORE_CPP_API real32_t ldexp(real32_t num, int exp); | ||
429 | GATE_CORE_CPP_API real64_t ldexp(real64_t num, int exp); | ||
430 | |||
431 | |||
432 | /// @brief | ||
433 | /// @tparam T | ||
434 | /// @param num | ||
435 | /// @return | ||
436 | template<class T> T log(T num); | ||
437 | GATE_CORE_CPP_API real32_t log(real32_t num); | ||
438 | GATE_CORE_CPP_API real64_t log(real64_t num); | ||
439 | |||
440 | |||
441 | |||
442 | /// @brief | ||
443 | /// @tparam T | ||
444 | /// @param num | ||
445 | /// @return | ||
446 | template<class T> T log10(T num); | ||
447 | GATE_CORE_CPP_API real32_t log10(real32_t num); | ||
448 | GATE_CORE_CPP_API real64_t log10(real64_t num); | ||
449 | |||
450 | |||
451 | /// @brief | ||
452 | /// @tparam T | ||
453 | /// @param num | ||
454 | /// @param exp | ||
455 | /// @return | ||
456 | template<class T> T modf(T num, T* exp); | ||
457 | GATE_CORE_CPP_API real32_t modf(real32_t num, real32_t* exp); | ||
458 | GATE_CORE_CPP_API real64_t modf(real64_t num, real64_t* exp); | ||
459 | |||
460 | |||
461 | /// @brief | ||
462 | /// @tparam T | ||
463 | /// @param num | ||
464 | /// @param exp | ||
465 | /// @return | ||
466 | template<class T> T pow(T num, T exp); | ||
467 | GATE_CORE_CPP_API real32_t pow(real32_t num, real32_t exp); | ||
468 | GATE_CORE_CPP_API real64_t pow(real64_t num, real64_t exp); | ||
469 | |||
470 | |||
471 | /// @brief | ||
472 | /// @tparam T | ||
473 | /// @param num | ||
474 | /// @return | ||
475 | template<class T> T sqrt(T num); | ||
476 | GATE_CORE_CPP_API real32_t sqrt(real32_t num); | ||
477 | GATE_CORE_CPP_API real64_t sqrt(real64_t num); | ||
478 | |||
479 | |||
480 | /// @brief | ||
481 | /// @tparam T | ||
482 | /// @param num | ||
483 | /// @return | ||
484 | template<class T> T ceil(T num); | ||
485 | GATE_CORE_CPP_API real32_t ceil(real32_t num); | ||
486 | GATE_CORE_CPP_API real64_t ceil(real64_t num); | ||
487 | |||
488 | |||
489 | /// @brief | ||
490 | /// @tparam T | ||
491 | /// @param num | ||
492 | /// @return | ||
493 | template<class T> T floor(T num); | ||
494 | GATE_CORE_CPP_API real32_t floor(real32_t num); | ||
495 | GATE_CORE_CPP_API real64_t floor(real64_t num); | ||
496 | |||
497 | |||
498 | /// @brief | ||
499 | /// @tparam T | ||
500 | /// @param num | ||
501 | /// @return | ||
502 | template<class T> T deg2rad(T num); | ||
503 | GATE_CORE_CPP_API real32_t deg2rad(real32_t num); | ||
504 | GATE_CORE_CPP_API real64_t deg2rad(real64_t num); | ||
505 | |||
506 | |||
507 | /// @brief | ||
508 | /// @tparam T | ||
509 | /// @param num | ||
510 | /// @return | ||
511 | template<class T> T rad2deg(T num); | ||
512 | GATE_CORE_CPP_API real32_t rad2deg(real32_t num); | ||
513 | GATE_CORE_CPP_API real64_t rad2deg(real64_t num); | ||
514 | |||
515 | |||
516 | } // end of namespace math | ||
517 | |||
518 | } // end of namespace gate | ||
519 | |||
520 | #endif | ||
521 |