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