]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/simd/tests/ldexp_scalbn_scalbln_modf.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / simd / tests / ldexp_scalbn_scalbln_modf.cc
1 // Copyright (C) 2020-2022 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 //
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // only: float|double|ldouble * * *
19 // expensive: * [1-9] * *
20 #include "bits/verify.h"
21 #include "bits/metahelpers.h"
22 #include "bits/test_values.h"
23
24 template <typename V>
25 void
26 test()
27 {
28 vir::test::setFuzzyness<float>(0);
29 vir::test::setFuzzyness<double>(0);
30
31 using T = typename V::value_type;
32
33 // See https://sourceware.org/bugzilla/show_bug.cgi?id=18031
34 const bool modf_is_broken = [] {
35 volatile T x = T(5e20) / 7;
36 T tmp;
37 return std::fabs(std::modf(x, &tmp)) >= 1;
38 }();
39 if (modf_is_broken)
40 __builtin_fprintf(stderr,
41 "NOTE: Skipping modf because std::modf is broken.\n");
42
43 test_values<V>(
44 {
45 #ifdef __STDC_IEC_559__
46 std::__quiet_NaN_v<T>,
47 std::__infinity_v<T>,
48 -std::__infinity_v<T>,
49 -0.,
50 std::__denorm_min_v<T>,
51 std::__norm_min_v<T> / 3,
52 -std::__denorm_min_v<T>,
53 -std::__norm_min_v<T> / 3,
54 #endif
55 +0.,
56 +1.3,
57 -1.3,
58 2.1,
59 -2.1,
60 0.99,
61 0.9,
62 -0.9,
63 -0.99,
64 std::__norm_min_v<T>,
65 std::__finite_max_v<T>,
66 -std::__norm_min_v<T>,
67 -std::__finite_max_v<T>},
68 {10000},
69 [](const V input) {
70 for (int exp : {-10000, -100, -10, -1, 0, 1, 10, 100, 10000})
71 {
72 const auto totest = ldexp(input, exp);
73 using R = std::remove_const_t<decltype(totest)>;
74 auto&& expected = [&](const auto& v) -> const R {
75 R tmp = {};
76 using std::ldexp;
77 for (std::size_t i = 0; i < R::size(); ++i)
78 {
79 tmp[i] = ldexp(v[i], exp);
80 }
81 return tmp;
82 };
83 const R expect1 = expected(input);
84 COMPARE(isnan(totest), isnan(expect1))
85 << "ldexp(" << input << ", " << exp << ") = " << totest
86 << " != " << expect1;
87 FUZZY_COMPARE(ldexp(iif(isnan(expect1), 0, input), exp),
88 expected(iif(isnan(expect1), 0, input)))
89 << "\nclean = " << iif(isnan(expect1), 0, input);
90 }
91 },
92 [](const V input) {
93 for (int exp : {-10000, -100, -10, -1, 0, 1, 10, 100, 10000})
94 {
95 const auto totest = scalbn(input, exp);
96 using R = std::remove_const_t<decltype(totest)>;
97 auto&& expected = [&](const auto& v) -> const R {
98 R tmp = {};
99 using std::scalbn;
100 for (std::size_t i = 0; i < R::size(); ++i)
101 {
102 tmp[i] = scalbn(v[i], exp);
103 }
104 return tmp;
105 };
106 const R expect1 = expected(input);
107 COMPARE(isnan(totest), isnan(expect1))
108 << "scalbn(" << input << ", " << exp << ") = " << totest
109 << " != " << expect1;
110 FUZZY_COMPARE(scalbn(iif(isnan(expect1), 0, input), exp),
111 expected(iif(isnan(expect1), 0, input)))
112 << "\nclean = " << iif(isnan(expect1), 0, input);
113 }
114 },
115 [](const V input) {
116 for (long exp : {-10000, -100, -10, -1, 0, 1, 10, 100, 10000})
117 {
118 const auto totest = scalbln(input, exp);
119 using R = std::remove_const_t<decltype(totest)>;
120 auto&& expected = [&](const auto& v) -> const R {
121 R tmp = {};
122 using std::scalbln;
123 for (std::size_t i = 0; i < R::size(); ++i)
124 {
125 tmp[i] = scalbln(v[i], exp);
126 }
127 return tmp;
128 };
129 const R expect1 = expected(input);
130 COMPARE(isnan(totest), isnan(expect1))
131 << "scalbln(" << input << ", " << exp << ") = " << totest
132 << " != " << expect1;
133 FUZZY_COMPARE(scalbln(iif(isnan(expect1), 0, input), exp),
134 expected(iif(isnan(expect1), 0, input)))
135 << "\nclean = " << iif(isnan(expect1), 0, input);
136 }
137 },
138 [modf_is_broken](const V input) {
139 if (modf_is_broken)
140 return;
141 V integral = {};
142 const V totest = modf(input, &integral);
143 auto&& expected = [&](const auto& v) -> std::pair<const V, const V> {
144 std::pair<V, V> tmp = {};
145 using std::modf;
146 for (std::size_t i = 0; i < V::size(); ++i)
147 {
148 typename V::value_type tmp2;
149 tmp.first[i] = modf(v[i], &tmp2);
150 tmp.second[i] = tmp2;
151 }
152 return tmp;
153 };
154 const auto expect1 = expected(input);
155 #ifdef __STDC_IEC_559__
156 COMPARE(isnan(totest), isnan(expect1.first))
157 << "modf(" << input << ", iptr) = " << totest << " != " << expect1;
158 COMPARE(isnan(integral), isnan(expect1.second))
159 << "modf(" << input << ", iptr) = " << totest << " != " << expect1;
160 COMPARE(isnan(totest), isnan(integral))
161 << "modf(" << input << ", iptr) = " << totest << " != " << expect1;
162 const V clean = iif(isnan(totest), V(), input);
163 #else
164 const V clean = iif(isnormal(input), input, V());
165 #endif
166 const auto expect2 = expected(clean);
167 COMPARE(modf(clean, &integral), expect2.first) << "\nclean = " << clean;
168 COMPARE(integral, expect2.second);
169 });
170 }