xref: /llvm-project/flang/unittests/Runtime/Complex.cpp (revision 0cda970ecc8a885acf7298a61370a1368b0ea39b)
1ffc67bb3SDavid Spickett //===-- flang/unittests/Runtime/Complex.cpp ---------------------*- C++ -*-===//
2ffc67bb3SDavid Spickett //
3ffc67bb3SDavid Spickett // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ffc67bb3SDavid Spickett // See https://llvm.org/LICENSE.txt for license information.
5ffc67bb3SDavid Spickett // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ffc67bb3SDavid Spickett //
7ffc67bb3SDavid Spickett //===----------------------------------------------------------------------===//
8ffc67bb3SDavid Spickett #include "gmock/gmock.h"
9ffc67bb3SDavid Spickett #include "gtest/gtest-matchers.h"
10ffc67bb3SDavid Spickett #include <limits>
11ffc67bb3SDavid Spickett 
12ffc67bb3SDavid Spickett #ifdef __clang__
13ffc67bb3SDavid Spickett #pragma clang diagnostic ignored "-Wc99-extensions"
14ffc67bb3SDavid Spickett #endif
15ffc67bb3SDavid Spickett 
16*0cda970eSMichael Kruse #include "flang/Common/Fortran-consts.h"
17ffc67bb3SDavid Spickett #include "flang/Runtime/cpp-type.h"
18ffc67bb3SDavid Spickett #include "flang/Runtime/entry-names.h"
19ffc67bb3SDavid Spickett 
20ffc67bb3SDavid Spickett #include <complex>
21ffc67bb3SDavid Spickett #include <cstdint>
22ffc67bb3SDavid Spickett 
23ffc67bb3SDavid Spickett #ifndef _MSC_VER
24ffc67bb3SDavid Spickett #include <complex.h>
25ffc67bb3SDavid Spickett typedef float _Complex float_Complex_t;
26ffc67bb3SDavid Spickett typedef double _Complex double_Complex_t;
27ffc67bb3SDavid Spickett #else
28ffc67bb3SDavid Spickett struct float_Complex_t {
29ffc67bb3SDavid Spickett   float re;
30ffc67bb3SDavid Spickett   float im;
31ffc67bb3SDavid Spickett };
32ffc67bb3SDavid Spickett struct double_Complex_t {
33ffc67bb3SDavid Spickett   double re;
34ffc67bb3SDavid Spickett   double im;
35ffc67bb3SDavid Spickett };
36ffc67bb3SDavid Spickett #endif
37ffc67bb3SDavid Spickett 
38ffc67bb3SDavid Spickett extern "C" float_Complex_t RTNAME(cpowi)(
39ffc67bb3SDavid Spickett     float_Complex_t base, std::int32_t exp);
40ffc67bb3SDavid Spickett 
41ffc67bb3SDavid Spickett extern "C" double_Complex_t RTNAME(zpowi)(
42ffc67bb3SDavid Spickett     double_Complex_t base, std::int32_t exp);
43ffc67bb3SDavid Spickett 
44ffc67bb3SDavid Spickett extern "C" float_Complex_t RTNAME(cpowk)(
45ffc67bb3SDavid Spickett     float_Complex_t base, std::int64_t exp);
46ffc67bb3SDavid Spickett 
47ffc67bb3SDavid Spickett extern "C" double_Complex_t RTNAME(zpowk)(
48ffc67bb3SDavid Spickett     double_Complex_t base, std::int64_t exp);
49ffc67bb3SDavid Spickett 
50ffc67bb3SDavid Spickett static std::complex<float> cpowi(std::complex<float> base, std::int32_t exp) {
51ffc67bb3SDavid Spickett   float_Complex_t cbase{*(float_Complex_t *)(&base)};
52ffc67bb3SDavid Spickett   float_Complex_t cres{RTNAME(cpowi)(cbase, exp)};
53ffc67bb3SDavid Spickett   return *(std::complex<float> *)(&cres);
54ffc67bb3SDavid Spickett }
55ffc67bb3SDavid Spickett 
56ffc67bb3SDavid Spickett static std::complex<double> zpowi(std::complex<double> base, std::int32_t exp) {
57ffc67bb3SDavid Spickett   double_Complex_t cbase{*(double_Complex_t *)(&base)};
58ffc67bb3SDavid Spickett   double_Complex_t cres{RTNAME(zpowi)(cbase, exp)};
59ffc67bb3SDavid Spickett   return *(std::complex<double> *)(&cres);
60ffc67bb3SDavid Spickett }
61ffc67bb3SDavid Spickett 
62ffc67bb3SDavid Spickett static std::complex<float> cpowk(std::complex<float> base, std::int64_t exp) {
63ffc67bb3SDavid Spickett   float_Complex_t cbase{*(float_Complex_t *)(&base)};
64ffc67bb3SDavid Spickett   float_Complex_t cres{RTNAME(cpowk)(cbase, exp)};
65ffc67bb3SDavid Spickett   return *(std::complex<float> *)(&cres);
66ffc67bb3SDavid Spickett }
67ffc67bb3SDavid Spickett 
68ffc67bb3SDavid Spickett static std::complex<double> zpowk(std::complex<double> base, std::int64_t exp) {
69ffc67bb3SDavid Spickett   double_Complex_t cbase{*(double_Complex_t *)(&base)};
70ffc67bb3SDavid Spickett   double_Complex_t cres{RTNAME(zpowk)(cbase, exp)};
71ffc67bb3SDavid Spickett   return *(std::complex<double> *)(&cres);
72ffc67bb3SDavid Spickett }
73ffc67bb3SDavid Spickett 
74ffc67bb3SDavid Spickett MATCHER_P(ExpectComplexFloatEq, c, "") {
75ffc67bb3SDavid Spickett   using namespace testing;
76ffc67bb3SDavid Spickett   return ExplainMatchResult(
77ffc67bb3SDavid Spickett       AllOf(Property(&std::complex<float>::real, FloatEq(c.real())),
78ffc67bb3SDavid Spickett           Property(&std::complex<float>::imag, FloatEq(c.imag()))),
79ffc67bb3SDavid Spickett       arg, result_listener);
80ffc67bb3SDavid Spickett }
81ffc67bb3SDavid Spickett 
82ffc67bb3SDavid Spickett MATCHER_P(ExpectComplexDoubleEq, c, "") {
83ffc67bb3SDavid Spickett   using namespace testing;
84ffc67bb3SDavid Spickett   return ExplainMatchResult(AllOf(Property(&std::complex<double>::real,
85ffc67bb3SDavid Spickett                                       DoubleNear(c.real(), 0.00000001)),
86ffc67bb3SDavid Spickett                                 Property(&std::complex<double>::imag,
87ffc67bb3SDavid Spickett                                     DoubleNear(c.imag(), 0.00000001))),
88ffc67bb3SDavid Spickett       arg, result_listener);
89ffc67bb3SDavid Spickett }
90ffc67bb3SDavid Spickett 
91ffc67bb3SDavid Spickett #define EXPECT_COMPLEX_FLOAT_EQ(val1, val2) \
92ffc67bb3SDavid Spickett   EXPECT_THAT(val1, ExpectComplexFloatEq(val2))
93ffc67bb3SDavid Spickett 
94ffc67bb3SDavid Spickett #define EXPECT_COMPLEX_DOUBLE_EQ(val1, val2) \
95ffc67bb3SDavid Spickett   EXPECT_THAT(val1, ExpectComplexDoubleEq(val2))
96ffc67bb3SDavid Spickett 
97ffc67bb3SDavid Spickett using namespace std::literals::complex_literals;
98ffc67bb3SDavid Spickett 
99ffc67bb3SDavid Spickett TEST(Complex, cpowi) {
100ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 0), 1.f + 0if);
101ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 1), 3.f + 4if);
102ffc67bb3SDavid Spickett 
103ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 2), -7.f + 24if);
104ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 3), -117.f + 44if);
105ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 4), -527.f - 336if);
106ffc67bb3SDavid Spickett 
107ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, -2), -0.0112f - 0.0384if);
108ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(2.f + 1if, 10), -237.f - 3116if);
109ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(0.5f + 0.6if, -10), -9.322937f - 7.2984829if);
110ffc67bb3SDavid Spickett 
111ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(2.f + 1if, 5), -38.f + 41if);
112ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowi(0.5f + 0.6if, -5), -1.121837f + 3.252915if);
113ffc67bb3SDavid Spickett 
114ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(
115ffc67bb3SDavid Spickett       cpowi(0.f + 1if, std::numeric_limits<std::int32_t>::min()), 1.f + 0if);
116ffc67bb3SDavid Spickett }
117ffc67bb3SDavid Spickett 
118ffc67bb3SDavid Spickett TEST(Complex, cpowk) {
119ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 0), 1.f + 0if);
120ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 1), 3.f + 4if);
121ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 2), -7.f + 24if);
122ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 3), -117.f + 44if);
123ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 4), -527.f - 336if);
124ffc67bb3SDavid Spickett 
125ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, -2), -0.0112f - 0.0384if);
126ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(2.f + 1if, 10), -237.f - 3116if);
127ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(0.5f + 0.6if, -10), -9.322937f - 7.2984829if);
128ffc67bb3SDavid Spickett 
129ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(2.f + 1if, 5), -38.f + 41if);
130ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(cpowk(0.5f + 0.6if, -5), -1.121837f + 3.252915if);
131ffc67bb3SDavid Spickett 
132ffc67bb3SDavid Spickett   EXPECT_COMPLEX_FLOAT_EQ(
133ffc67bb3SDavid Spickett       cpowk(0.f + 1if, std::numeric_limits<std::int64_t>::min()), 1.f + 0if);
134ffc67bb3SDavid Spickett }
135ffc67bb3SDavid Spickett 
136ffc67bb3SDavid Spickett TEST(Complex, zpowi) {
137ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 0), 1. + 0i);
138ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 1), 3. + 4i);
139ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 2), -7. + 24i);
140ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 3), -117. + 44i);
141ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 4), -527. - 336i);
142ffc67bb3SDavid Spickett 
143ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, -2), -0.0112 - 0.0384i);
144ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 10), -237. - 3116i);
145ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
146ffc67bb3SDavid Spickett 
147ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 5), -38. + 41i);
148ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
149ffc67bb3SDavid Spickett 
150ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(
151ffc67bb3SDavid Spickett       zpowi(0. + 1i, std::numeric_limits<std::int32_t>::min()), 1. + 0i);
152ffc67bb3SDavid Spickett }
153ffc67bb3SDavid Spickett 
154ffc67bb3SDavid Spickett TEST(Complex, zpowk) {
155ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 0), 1. + 0i);
156ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 1), 3. + 4i);
157ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 2), -7. + 24i);
158ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 3), -117. + 44i);
159ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 4), -527. - 336i);
160ffc67bb3SDavid Spickett 
161ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, -2), -0.0112 - 0.0384i);
162ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(2. + 1i, 10), -237. - 3116i);
163ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
164ffc67bb3SDavid Spickett 
165ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(2. + 1i, 5l), -38. + 41i);
166ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
167ffc67bb3SDavid Spickett 
168ffc67bb3SDavid Spickett   EXPECT_COMPLEX_DOUBLE_EQ(
169ffc67bb3SDavid Spickett       zpowk(0. + 1i, std::numeric_limits<std::int64_t>::min()), 1. + 0i);
170ffc67bb3SDavid Spickett }
171