798fddb263b00c2081b43b6e14f066fe2b84dcf6
[mono.git] / mono / utils / mono-complex.h
1 /*
2 * mono-complex.h: C99 Complex math cross-platform support code
3 *
4 * Author:
5 *       Joao Matos (joao.matos@xamarin.com)
6 *
7 * Copyright 2015 Xamarin, Inc (http://www.xamarin.com)
8 */
9
10 #include <config.h>
11 #include <glib.h>
12
13 #if !defined (HAVE_COMPLEX_H)
14 #include <../../support/libm/complex.h>
15 #else
16 #include <complex.h>
17 #endif
18
19 #define _USE_MATH_DEFINES // needed by MSVC to define math constants
20 #include <math.h>
21
22 #ifdef _MSC_VER
23
24 #define double_complex _C_double_complex
25
26 static inline
27 double_complex mono_double_complex_make(gdouble re, gdouble im)
28 {
29         return _Cbuild (re, im);
30 }
31
32 static inline
33 double_complex mono_double_complex_scalar_div(double_complex c, gdouble s)
34 {
35         return mono_double_complex_make(creal(c) / s, cimag(c) / s);
36 }
37
38 static inline
39 double_complex mono_double_complex_scalar_mul(double_complex c, gdouble s)
40 {
41         return mono_double_complex_make(creal(c) * s, cimag(c) * s);
42 }
43
44 static inline
45 double_complex mono_double_complex_div(double_complex left, double_complex right)
46 {
47         double denom = creal(right) * creal(right) + cimag(right) * cimag(right);
48
49         return mono_double_complex_make(
50                 (creal(left) * creal(right) + cimag(left) * cimag(right)) / denom,
51                 (-creal(left) * cimag(right) + cimag(left) * creal(right)) / denom);
52 }
53
54 static inline
55 double_complex mono_double_complex_sub(double_complex left, double_complex right)
56 {
57         return mono_double_complex_make(creal(left) - creal(right), cimag(left)
58                 - cimag(right));
59 }
60
61 #else
62
63 #define double_complex double complex
64
65 static inline
66 double_complex mono_double_complex_make(gdouble re, gdouble im)
67 {
68         return re + im * I;
69 }
70
71 static inline
72 double_complex mono_double_complex_scalar_div(double_complex c, gdouble s)
73 {
74         return c / s;
75 }
76
77 static inline
78 double_complex mono_double_complex_scalar_mul(double_complex c, gdouble s)
79 {
80         return c * s;
81 }
82
83 static inline
84 double_complex mono_double_complex_div(double_complex left, double_complex right)
85 {
86         return left / right;
87 }
88
89 static inline
90 double_complex mono_double_complex_sub(double_complex left, double_complex right)
91 {
92         return left - right;
93 }
94
95 #endif