1 //===-- flang/unittests/Runtime/Complex.cpp ---------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
8 #include "gmock/gmock.h"
9 #include "gtest/gtest-matchers.h"
13 #pragma clang diagnostic ignored "-Wc99-extensions"
16 #include "flang/Common/Fortran.h"
17 #include "flang/Runtime/cpp-type.h"
18 #include "flang/Runtime/entry-names.h"
25 typedef float _Complex float_Complex_t
;
26 typedef double _Complex double_Complex_t
;
28 struct float_Complex_t
{
32 struct double_Complex_t
{
38 extern "C" float_Complex_t
RTNAME(cpowi
)(
39 float_Complex_t base
, std::int32_t exp
);
41 extern "C" double_Complex_t
RTNAME(zpowi
)(
42 double_Complex_t base
, std::int32_t exp
);
44 extern "C" float_Complex_t
RTNAME(cpowk
)(
45 float_Complex_t base
, std::int64_t exp
);
47 extern "C" double_Complex_t
RTNAME(zpowk
)(
48 double_Complex_t base
, std::int64_t exp
);
50 static std::complex<float> cpowi(std::complex<float> base
, std::int32_t exp
) {
51 float_Complex_t cbase
{*(float_Complex_t
*)(&base
)};
52 float_Complex_t cres
{RTNAME(cpowi
)(cbase
, exp
)};
53 return *(std::complex<float> *)(&cres
);
56 static std::complex<double> zpowi(std::complex<double> base
, std::int32_t exp
) {
57 double_Complex_t cbase
{*(double_Complex_t
*)(&base
)};
58 double_Complex_t cres
{RTNAME(zpowi
)(cbase
, exp
)};
59 return *(std::complex<double> *)(&cres
);
62 static std::complex<float> cpowk(std::complex<float> base
, std::int64_t exp
) {
63 float_Complex_t cbase
{*(float_Complex_t
*)(&base
)};
64 float_Complex_t cres
{RTNAME(cpowk
)(cbase
, exp
)};
65 return *(std::complex<float> *)(&cres
);
68 static std::complex<double> zpowk(std::complex<double> base
, std::int64_t exp
) {
69 double_Complex_t cbase
{*(double_Complex_t
*)(&base
)};
70 double_Complex_t cres
{RTNAME(zpowk
)(cbase
, exp
)};
71 return *(std::complex<double> *)(&cres
);
74 MATCHER_P(ExpectComplexFloatEq
, c
, "") {
75 using namespace testing
;
76 return ExplainMatchResult(
77 AllOf(Property(&std::complex<float>::real
, FloatEq(c
.real())),
78 Property(&std::complex<float>::imag
, FloatEq(c
.imag()))),
79 arg
, result_listener
);
82 MATCHER_P(ExpectComplexDoubleEq
, c
, "") {
83 using namespace testing
;
84 return ExplainMatchResult(AllOf(Property(&std::complex<double>::real
,
85 DoubleNear(c
.real(), 0.00000001)),
86 Property(&std::complex<double>::imag
,
87 DoubleNear(c
.imag(), 0.00000001))),
88 arg
, result_listener
);
91 #define EXPECT_COMPLEX_FLOAT_EQ(val1, val2) \
92 EXPECT_THAT(val1, ExpectComplexFloatEq(val2))
94 #define EXPECT_COMPLEX_DOUBLE_EQ(val1, val2) \
95 EXPECT_THAT(val1, ExpectComplexDoubleEq(val2))
97 using namespace std::literals::complex_literals
;
99 TEST(Complex
, cpowi
) {
100 EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f
+ 4if, 0), 1.f
+ 0if);
101 EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f
+ 4if, 1), 3.f
+ 4if);
103 EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f
+ 4if, 2), -7.f
+ 24if);
104 EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f
+ 4if, 3), -117.f
+ 44if);
105 EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f
+ 4if, 4), -527.f
- 336if);
107 EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f
+ 4if, -2), -0.0112f
- 0.0384if);
108 EXPECT_COMPLEX_FLOAT_EQ(cpowi(2.f
+ 1if, 10), -237.f
- 3116if);
109 EXPECT_COMPLEX_FLOAT_EQ(cpowi(0.5f
+ 0.6if, -10), -9.322937f
- 7.2984829if);
111 EXPECT_COMPLEX_FLOAT_EQ(cpowi(2.f
+ 1if, 5), -38.f
+ 41if);
112 EXPECT_COMPLEX_FLOAT_EQ(cpowi(0.5f
+ 0.6if, -5), -1.121837f
+ 3.252915if);
114 EXPECT_COMPLEX_FLOAT_EQ(
115 cpowi(0.f
+ 1if, std::numeric_limits
<std::int32_t>::min()), 1.f
+ 0if);
118 TEST(Complex
, cpowk
) {
119 EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f
+ 4if, 0), 1.f
+ 0if);
120 EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f
+ 4if, 1), 3.f
+ 4if);
121 EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f
+ 4if, 2), -7.f
+ 24if);
122 EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f
+ 4if, 3), -117.f
+ 44if);
123 EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f
+ 4if, 4), -527.f
- 336if);
125 EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f
+ 4if, -2), -0.0112f
- 0.0384if);
126 EXPECT_COMPLEX_FLOAT_EQ(cpowk(2.f
+ 1if, 10), -237.f
- 3116if);
127 EXPECT_COMPLEX_FLOAT_EQ(cpowk(0.5f
+ 0.6if, -10), -9.322937f
- 7.2984829if);
129 EXPECT_COMPLEX_FLOAT_EQ(cpowk(2.f
+ 1if, 5), -38.f
+ 41if);
130 EXPECT_COMPLEX_FLOAT_EQ(cpowk(0.5f
+ 0.6if, -5), -1.121837f
+ 3.252915if);
132 EXPECT_COMPLEX_FLOAT_EQ(
133 cpowk(0.f
+ 1if, std::numeric_limits
<std::int64_t>::min()), 1.f
+ 0if);
136 TEST(Complex
, zpowi
) {
137 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i
, 0), 1. + 0i
);
138 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i
, 1), 3. + 4i
);
139 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i
, 2), -7. + 24i
);
140 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i
, 3), -117. + 44i
);
141 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i
, 4), -527. - 336i
);
143 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i
, -2), -0.0112 - 0.0384i
);
144 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i
, 10), -237. - 3116i
);
145 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i
, -10), -9.32293628 - 7.29848564i
);
147 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i
, 5), -38. + 41i
);
148 EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i
, -5), -1.12183773 + 3.25291503i
);
150 EXPECT_COMPLEX_DOUBLE_EQ(
151 zpowi(0. + 1i
, std::numeric_limits
<std::int32_t>::min()), 1. + 0i
);
154 TEST(Complex
, zpowk
) {
155 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i
, 0), 1. + 0i
);
156 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i
, 1), 3. + 4i
);
157 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i
, 2), -7. + 24i
);
158 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i
, 3), -117. + 44i
);
159 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i
, 4), -527. - 336i
);
161 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i
, -2), -0.0112 - 0.0384i
);
162 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(2. + 1i
, 10), -237. - 3116i
);
163 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(0.5 + 0.6i
, -10), -9.32293628 - 7.29848564i
);
165 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(2. + 1i
, 5l), -38. + 41i
);
166 EXPECT_COMPLEX_DOUBLE_EQ(zpowk(0.5 + 0.6i
, -5), -1.12183773 + 3.25291503i
);
168 EXPECT_COMPLEX_DOUBLE_EQ(
169 zpowk(0. + 1i
, std::numeric_limits
<std::int64_t>::min()), 1. + 0i
);