Panda3D
Loading...
Searching...
No Matches
cmath.I
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file cmath.I
10 * @author drose
11 * @date 2000-05-19
12 */
13
14#ifdef __INTEL_COMPILER
15// see float.h
16#define FPU_CONTROLWORD_WRITEMASK 0xFFFFF // if you look at defn of _CW_DEFAULT, all settings fall within 0xFFFFF
17#define FPU_CONTROLWORD_NEW_SETTING _CW_DEFAULT
18#endif
19
20/**
21 *
22 */
23INLINE float
24csqrt(float v) {
25 return sqrtf(v);
26}
27
28/**
29 *
30 */
31INLINE float
32csin(float v) {
33 return sinf(v);
34}
35
36/**
37 *
38 */
39INLINE float
40ccos(float v) {
41 return cosf(v);
42}
43
44/**
45 *
46 */
47INLINE float ctan(float v) {
48 return tanf(v);
49}
50
51/**
52 *
53 */
54INLINE void
55csincos(float v, float *sin_result, float *cos_result) {
56 // MS VC defines _M_IX86 for x86. gcc should define _X86_
57#if defined(_M_IX86) || defined(_X86_)
58 // #define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb
59 __asm {
60 mov eax, sin_result
61 mov edx, cos_result
62 fld v
63 fsincos
64 fstp DWORD ptr [edx]
65 fstp DWORD ptr [eax]
66 }
67#else //!_X86_
68 *sin_result = sinf(v);
69 *cos_result = cosf(v);
70#endif //!_X86_
71}
72
73/**
74 * Computes sin(x) / x, well-behaved as x approaches 0.
75 */
76INLINE float
77csin_over_x(float v) {
78 if (1.0f + v * v == 1.0f) {
79 return 1.0f;
80 } else {
81 return csin(v) / v;
82 }
83}
84
85/**
86 *
87 */
88INLINE float
89cabs(float v) {
90 return fabs(v);
91}
92
93/**
94 *
95 */
96INLINE float
97catan(float v) {
98 return atanf(v);
99}
100
101/**
102 *
103 */
104INLINE float
105catan2(float y, float x) {
106 return atan2f(y, x);
107}
108
109/**
110 *
111 */
112INLINE float
113casin(float v) {
114 return asinf(v);
115}
116
117/**
118 *
119 */
120INLINE float
121cacos(float v) {
122 return acosf(v);
123}
124
125/**
126 * This is similar to fmod(), but it behaves properly when x is negative: that
127 * is, it always returns a value in the range [0, y), assuming y is positive.
128 */
129INLINE float
130cmod(float x, float y) {
131 return x - floor(x / y) * y;
132}
133
134/**
135 *
136 */
137INLINE float
138cpow(float x, float y) {
139 return powf(x, y);
140}
141
142
143/**
144 *
145 */
146INLINE double
147cfloor(double f) {
148 #ifdef __INTEL_COMPILER
149 // intel floor doesnt work right if fpu mode is not double, so make
150 // double-prec mode is on
151 unsigned int saved_fpu_control_word=_controlfp(0x0,0x0);
152 _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK);
153 double retval=floor(f);
154 _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
155 return retval;
156 #else
157 return floor(f);
158 #endif
159}
160
161/**
162 *
163 */
164INLINE double
165cceil(double f) {
166 #ifdef __INTEL_COMPILER
167 // intel ceil doesnt work right if fpu mode is not double, so make double-
168 // prec mode is on
169 unsigned int saved_fpu_control_word=_controlfp(0x0,0x0);
170 _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK);
171 double retval=ceil(f);
172 _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
173 return retval;
174 #else
175 return ceil(f);
176 #endif
177}
178
179/**
180 * Returns the fractional component of f: f - cfloor(f).
181 */
182INLINE double
183cfrac(double f) {
184 return f - cfloor(f);
185}
186
187/**
188 *
189 */
190INLINE double
191csqrt(double v) {
192 return sqrt(v);
193}
194
195/**
196 *
197 */
198INLINE double
199csin(double v) {
200 return sin(v);
201}
202
203/**
204 *
205 */
206INLINE double
207ccos(double v) {
208 return cos(v);
209}
210
211/**
212 *
213 */
214INLINE double
215ctan(double v) {
216 return tan(v);
217}
218
219/**
220 *
221 */
222INLINE void
223csincos(double v, double *sin_result, double *cos_result) {
224#if defined(_M_IX86) || defined(_X86_)
225 // #define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb
226 __asm {
227 mov eax, sin_result
228 mov edx, cos_result
229 fld v
230 fsincos
231 fstp QWORD ptr [edx]
232 fstp QWORD ptr [eax]
233 }
234#else //!_X86_
235 *sin_result = sin(v);
236 *cos_result = cos(v);
237#endif //!_X86_
238}
239
240/**
241 * Computes sin(x) / x, well-behaved as x approaches 0.
242 */
243INLINE double
244csin_over_x(double v) {
245 if (1.0 + v * v == 1.0) {
246 return 1.0;
247 } else {
248 return csin(v) / v;
249 }
250}
251
252/**
253 *
254 */
255INLINE double
256cabs(double v) {
257 return fabs(v);
258}
259
260/**
261 *
262 */
263INLINE double
264catan(double v) {
265 return atan(v);
266}
267
268/**
269 *
270 */
271INLINE double
272catan2(double y, double x) {
273 return atan2(y, x);
274}
275
276/**
277 *
278 */
279INLINE double
280casin(double v) {
281 return asin(v);
282}
283
284/**
285 *
286 */
287INLINE double
288cacos(double v) {
289 return acos(v);
290}
291
292/**
293 * This is similar to fmod(), but it behaves properly when x is negative: that
294 * is, it always returns a value in the range [0, y), assuming y is positive.
295 */
296INLINE double
297cmod(double x, double y) {
298 return x - cfloor(x / y) * y;
299}
300
301/**
302 *
303 */
304INLINE double
305cpow(double x, double y) {
306 return pow(x, y);
307}
308
309/**
310 *
311 */
312INLINE int
313cpow(int x, int y) {
314 int result = 1;
315
316 if (y >= 0) {
317 for(; y > 0; --y) {
318 result *= x;
319 }
320 return result;
321
322 } else {
323 for(; y < 0; ++y) {
324 result *= x;
325 }
326 return 1 / result;
327 }
328}
329
330/**
331 *
332 */
333INLINE bool
334cnan(float v) {
335#if __FINITE_MATH_ONLY__
336 // GCC's isnan breaks when using -ffast-math.
337 union { float f; uint32_t x; } u = { v };
338 return ((u.x << 1) > 0xff000000u);
339#elif !defined(_WIN32)
340 return std::isnan(v);
341#else
342 return (_isnan(v) != 0);
343#endif
344}
345
346/**
347 *
348 */
349INLINE bool
350cnan(double v) {
351#if __FINITE_MATH_ONLY__
352 // GCC's isnan breaks when using -ffast-math.
353 union { double d; uint64_t x; } u = { v };
354 return ((u.x << 1) > 0xffe0000000000000ull);
355#elif !defined(_WIN32)
356 return std::isnan(v);
357#else
358 return (_isnan(v) != 0);
359#endif
360}
361
362/**
363 *
364 */
365INLINE bool
366cinf(float v) {
367#if __FINITE_MATH_ONLY__
368 // GCC's isinf breaks when using -ffast-math.
369 union { float f; uint32_t x; } u = { v };
370 return ((u.x << 1) == 0xff000000u);
371#elif !defined(_WIN32)
372 return std::isinf(v);
373#else
374 return (_isnan(v) == 0 && _finite(v) == 0);
375#endif
376}
377
378/**
379 *
380 */
381INLINE bool
382cinf(double v) {
383#if __FINITE_MATH_ONLY__
384 // GCC's isinf breaks when using -ffast-math.
385 union { double d; uint64_t x; } u = { v };
386 return ((u.x << 1) == 0xffe0000000000000ull);
387#elif !defined(_WIN32)
388 return std::isinf(v);
389#else
390 return (_isnan(v) == 0 && _finite(v) == 0);
391#endif
392}
393
394/**
395 *
396 */
397INLINE float
398make_nan(float) {
399 return std::numeric_limits<float>::quiet_NaN();
400}
401
402/**
403 *
404 */
405INLINE double
406make_nan(double) {
407 return std::numeric_limits<double>::quiet_NaN();
408}
409
410/**
411 *
412 */
413INLINE float
414make_inf(float) {
415 return std::numeric_limits<float>::infinity();
416}
417
418/**
419 *
420 */
421INLINE double
422make_inf(double) {
423 return std::numeric_limits<double>::infinity();
424}
425
426/**
427 * This is similar to fmod(), but it behaves properly when x is negative: that
428 * is, it always returns a value in the range [0, y), assuming y is positive.
429 *
430 * This integer-valued function is provided since the built-in modulo operator
431 * % does not work properly for negative x.
432 */
433INLINE int
434cmod(int x, int y) {
435 if (x < 0) {
436 return y - 1 - ((-x - 1) % y);
437 } else {
438 return x % y;
439 }
440}
float csin_over_x(float v)
Computes sin(x) / x, well-behaved as x approaches 0.
Definition cmath.I:77
float cmod(float x, float y)
This is similar to fmod(), but it behaves properly when x is negative: that is, it always returns a v...
Definition cmath.I:130
double cfrac(double f)
Returns the fractional component of f: f - cfloor(f).
Definition cmath.I:183