[runtime] Implemented cross-platform complex math code.
authorJoao Matos <joao.matos@xamarin.com>
Mon, 1 Jun 2015 09:47:30 +0000 (10:47 +0100)
committerJoao Matos <joao.matos@xamarin.com>
Tue, 2 Jun 2015 09:47:53 +0000 (10:47 +0100)
mono/utils/mono-complex.h [new file with mode: 0644]

diff --git a/mono/utils/mono-complex.h b/mono/utils/mono-complex.h
new file mode 100644 (file)
index 0000000..798fddb
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+* mono-complex.h: C99 Complex math cross-platform support code
+*
+* Author:
+*      Joao Matos (joao.matos@xamarin.com)
+*
+* Copyright 2015 Xamarin, Inc (http://www.xamarin.com)
+*/
+
+#include <config.h>
+#include <glib.h>
+
+#if !defined (HAVE_COMPLEX_H)
+#include <../../support/libm/complex.h>
+#else
+#include <complex.h>
+#endif
+
+#define _USE_MATH_DEFINES // needed by MSVC to define math constants
+#include <math.h>
+
+#ifdef _MSC_VER
+
+#define double_complex _C_double_complex
+
+static inline
+double_complex mono_double_complex_make(gdouble re, gdouble im)
+{
+       return _Cbuild (re, im);
+}
+
+static inline
+double_complex mono_double_complex_scalar_div(double_complex c, gdouble s)
+{
+       return mono_double_complex_make(creal(c) / s, cimag(c) / s);
+}
+
+static inline
+double_complex mono_double_complex_scalar_mul(double_complex c, gdouble s)
+{
+       return mono_double_complex_make(creal(c) * s, cimag(c) * s);
+}
+
+static inline
+double_complex mono_double_complex_div(double_complex left, double_complex right)
+{
+       double denom = creal(right) * creal(right) + cimag(right) * cimag(right);
+
+       return mono_double_complex_make(
+               (creal(left) * creal(right) + cimag(left) * cimag(right)) / denom,
+               (-creal(left) * cimag(right) + cimag(left) * creal(right)) / denom);
+}
+
+static inline
+double_complex mono_double_complex_sub(double_complex left, double_complex right)
+{
+       return mono_double_complex_make(creal(left) - creal(right), cimag(left)
+               - cimag(right));
+}
+
+#else
+
+#define double_complex double complex
+
+static inline
+double_complex mono_double_complex_make(gdouble re, gdouble im)
+{
+       return re + im * I;
+}
+
+static inline
+double_complex mono_double_complex_scalar_div(double_complex c, gdouble s)
+{
+       return c / s;
+}
+
+static inline
+double_complex mono_double_complex_scalar_mul(double_complex c, gdouble s)
+{
+       return c * s;
+}
+
+static inline
+double_complex mono_double_complex_div(double_complex left, double_complex right)
+{
+       return left / right;
+}
+
+static inline
+double_complex mono_double_complex_sub(double_complex left, double_complex right)
+{
+       return left - right;
+}
+
+#endif