summaryrefslogtreecommitdiff
path: root/src/inc/complex.h
blob: 159c81d04bc297f37daf013406e8db1d4aa4dde4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// complex.h
// 

// 
// Defines a basic complex number data type.  We cannot use the standard C++ library's
// complex implementation, because the CLR links to the wrong CRT.
//

#ifndef _COMPLEX_H_
#define _COMPLEX_H_

#include <math.h>

//
// Default compilation mode is /fp:precise, which disables fp intrinsics. This causes us to pull in FP stuff (sqrt,etc.) from
// The CRT, and increases our download size.  We don't need the extra precision this gets us, so let's switch to 
// the intrinsic versions.
//
#ifdef _MSC_VER
#pragma float_control(precise, off, push)
#endif


class Complex
{
public:
    double r;
    double i;

    Complex() : r(0), i(0) {}
    Complex(double real) : r(real), i(0) {}
    Complex(double real, double imag) : r(real), i(imag) {}
    Complex(const Complex& other) : r(other.r), i(other.i) {}
};

inline Complex operator+(Complex left, Complex right)
{
    LIMITED_METHOD_CONTRACT;
    return Complex(left.r + right.r, left.i + right.i);
}

inline Complex operator-(Complex left, Complex right)
{
    LIMITED_METHOD_CONTRACT;
    return Complex(left.r - right.r, left.i - right.i);
}

inline Complex operator*(Complex left, Complex right)
{
    LIMITED_METHOD_CONTRACT;
    return Complex(
        left.r * right.r - left.i * right.i,
        left.r * right.i + left.i * right.r);
}

inline Complex operator/(Complex left, Complex right)
{
    LIMITED_METHOD_CONTRACT;
    double denom = right.r * right.r + right.i * right.i;
    return Complex(
        (left.r * right.r + left.i * right.i) / denom,
        (-left.r * right.i + left.i * right.r) / denom);
}

inline double abs(Complex c)
{
    LIMITED_METHOD_CONTRACT;
    return sqrt(c.r * c.r + c.i * c.i);
}

#ifdef _MSC_VER
#pragma float_control(pop)
#endif


#endif //_COMPLEX_H_