Michael Kruse | 54f3713 | 2025-02-16 13:25:31 +0100 | [diff] [blame] | 1 | //===-- unittests/Runtime/Numeric.cpp ---------------------------*- C++ -*-===// |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 2 | // |
| 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 | //===----------------------------------------------------------------------===// |
| 8 | |
Peter Klausler | 830c0b9 | 2021-09-01 16:00:53 -0700 | [diff] [blame] | 9 | #include "flang/Runtime/numeric.h" |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 10 | #include "gtest/gtest.h" |
Peter Steinfeld | 478e0b5 | 2023-07-17 12:21:01 -0700 | [diff] [blame] | 11 | #include "flang/Common/float128.h" |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 12 | #include <cmath> |
| 13 | #include <limits> |
| 14 | |
| 15 | using namespace Fortran::runtime; |
| 16 | using Fortran::common::TypeCategory; |
| 17 | template <int KIND> using Int = CppTypeFor<TypeCategory::Integer, KIND>; |
| 18 | template <int KIND> using Real = CppTypeFor<TypeCategory::Real, KIND>; |
| 19 | |
| 20 | // Simple tests of numeric intrinsic functions using examples from Fortran 2018 |
| 21 | |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 22 | TEST(Numeric, Ceiling) { |
| 23 | EXPECT_EQ(RTNAME(Ceiling4_4)(Real<4>{3.7}), 4); |
| 24 | EXPECT_EQ(RTNAME(Ceiling8_8)(Real<8>{-3.7}), -3); |
| 25 | EXPECT_EQ(RTNAME(Ceiling4_1)(Real<4>{0}), 0); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 26 | } |
| 27 | |
| 28 | TEST(Numeric, Floor) { |
| 29 | EXPECT_EQ(RTNAME(Floor4_4)(Real<4>{3.7}), 3); |
| 30 | EXPECT_EQ(RTNAME(Floor8_8)(Real<8>{-3.7}), -4); |
| 31 | EXPECT_EQ(RTNAME(Floor4_1)(Real<4>{0}), 0); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 32 | } |
| 33 | |
David Parks | a03e93e | 2024-06-11 10:40:00 -0600 | [diff] [blame] | 34 | TEST(Numeric, Erfc_scaled) { |
| 35 | EXPECT_NEAR(RTNAME(ErfcScaled4)(Real<4>{20.0}), 0.02817434874, 1.0e-8); |
| 36 | EXPECT_NEAR(RTNAME(ErfcScaled8)(Real<8>{20.0}), 0.02817434874, 1.0e-11); |
Slava Zakharin | 104f3c1 | 2024-09-18 17:41:33 -0700 | [diff] [blame] | 37 | #if HAS_FLOAT80 |
David Parks | a03e93e | 2024-06-11 10:40:00 -0600 | [diff] [blame] | 38 | EXPECT_NEAR(RTNAME(ErfcScaled10)(Real<10>{20.0}), 0.02817434874, 1.0e-8); |
| 39 | #endif |
| 40 | } |
| 41 | |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 42 | TEST(Numeric, Exponent) { |
| 43 | EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0); |
| 44 | EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1); |
| 45 | EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3); |
| 46 | EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()), |
| 47 | std::numeric_limits<Int<8>>::max()); |
| 48 | EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()), |
| 49 | std::numeric_limits<Int<8>>::max()); |
| 50 | } |
| 51 | |
| 52 | TEST(Numeric, Fraction) { |
| 53 | EXPECT_EQ(RTNAME(Fraction4)(Real<4>{0}), 0); |
| 54 | EXPECT_EQ(RTNAME(Fraction8)(Real<8>{3.0}), 0.75); |
| 55 | EXPECT_TRUE( |
| 56 | std::isnan(RTNAME(Fraction4)(std::numeric_limits<Real<4>>::infinity()))); |
| 57 | EXPECT_TRUE( |
| 58 | std::isnan(RTNAME(Fraction8)(std::numeric_limits<Real<8>>::quiet_NaN()))); |
| 59 | } |
| 60 | |
peter klausler | 71d868c | 2021-04-15 14:11:47 -0700 | [diff] [blame] | 61 | TEST(Numeric, IsNaN) { |
| 62 | EXPECT_FALSE(RTNAME(IsNaN4)(Real<4>{0})); |
| 63 | EXPECT_FALSE(RTNAME(IsNaN8)(std::numeric_limits<Real<8>>::infinity())); |
| 64 | EXPECT_TRUE(RTNAME(IsNaN8)(std::numeric_limits<Real<8>>::quiet_NaN())); |
| 65 | } |
| 66 | |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 67 | TEST(Numeric, Mod) { |
| 68 | EXPECT_EQ(RTNAME(ModInteger1)(Int<1>{8}, Int<1>(5)), 3); |
| 69 | EXPECT_EQ(RTNAME(ModInteger4)(Int<4>{-8}, Int<4>(5)), -3); |
| 70 | EXPECT_EQ(RTNAME(ModInteger2)(Int<2>{8}, Int<2>(-5)), 3); |
| 71 | EXPECT_EQ(RTNAME(ModInteger8)(Int<8>{-8}, Int<8>(-5)), -3); |
| 72 | EXPECT_EQ(RTNAME(ModReal4)(Real<4>{8.0}, Real<4>(5.0)), 3.0); |
| 73 | EXPECT_EQ(RTNAME(ModReal4)(Real<4>{-8.0}, Real<4>(5.0)), -3.0); |
| 74 | EXPECT_EQ(RTNAME(ModReal8)(Real<8>{8.0}, Real<8>(-5.0)), 3.0); |
| 75 | EXPECT_EQ(RTNAME(ModReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0); |
Slava Zakharin | 315c88c5 | 2024-04-03 10:19:06 -0700 | [diff] [blame] | 76 | EXPECT_EQ( |
| 77 | RTNAME(ModReal4)(Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity()), |
| 78 | 0.5); |
| 79 | EXPECT_EQ( |
| 80 | RTNAME(ModReal4)(Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity()), |
| 81 | -0.5); |
| 82 | EXPECT_EQ( |
| 83 | RTNAME(ModReal4)(Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity()), |
| 84 | 0.5); |
| 85 | EXPECT_EQ(RTNAME(ModReal4)( |
| 86 | Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity()), |
| 87 | -0.5); |
| 88 | EXPECT_EQ( |
| 89 | RTNAME(ModReal8)(Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity()), |
| 90 | 0.5); |
| 91 | EXPECT_EQ( |
| 92 | RTNAME(ModReal8)(Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity()), |
| 93 | -0.5); |
| 94 | EXPECT_EQ( |
| 95 | RTNAME(ModReal8)(Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity()), |
| 96 | 0.5); |
| 97 | EXPECT_EQ(RTNAME(ModReal8)( |
| 98 | Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity()), |
| 99 | -0.5); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | TEST(Numeric, Modulo) { |
| 103 | EXPECT_EQ(RTNAME(ModuloInteger1)(Int<1>{8}, Int<1>(5)), 3); |
| 104 | EXPECT_EQ(RTNAME(ModuloInteger4)(Int<4>{-8}, Int<4>(5)), 2); |
| 105 | EXPECT_EQ(RTNAME(ModuloInteger2)(Int<2>{8}, Int<2>(-5)), -2); |
| 106 | EXPECT_EQ(RTNAME(ModuloInteger8)(Int<8>{-8}, Int<8>(-5)), -3); |
| 107 | EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{8.0}, Real<4>(5.0)), 3.0); |
| 108 | EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-8.0}, Real<4>(5.0)), 2.0); |
| 109 | EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{8.0}, Real<8>(-5.0)), -2.0); |
| 110 | EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0); |
Slava Zakharin | 315c88c5 | 2024-04-03 10:19:06 -0700 | [diff] [blame] | 111 | // MODULO(x, INF) == NaN |
| 112 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)( |
| 113 | Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity()))); |
| 114 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)( |
| 115 | Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity()))); |
| 116 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)( |
| 117 | Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity()))); |
| 118 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)( |
| 119 | Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity()))); |
| 120 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)( |
| 121 | Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity()))); |
| 122 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)( |
| 123 | Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity()))); |
| 124 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)( |
| 125 | Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity()))); |
| 126 | EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)( |
| 127 | Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity()))); |
| 128 | // MODULO(x, y) for integer values of x and y with 0 remainder. |
| 129 | EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(1.0)), 0.0); |
| 130 | EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(-1.0)), -0.0); |
| 131 | EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-5.0}, Real<4>(1.0)), 0.0); |
| 132 | EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-5.0}, Real<4>(-1.0)), -0.0); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | TEST(Numeric, Nearest) { |
| 136 | EXPECT_EQ(RTNAME(Nearest4)(Real<4>{0}, true), |
| 137 | std::numeric_limits<Real<4>>::denorm_min()); |
| 138 | EXPECT_EQ(RTNAME(Nearest4)(Real<4>{3.0}, true), |
| 139 | Real<4>{3.0} + std::ldexp(Real<4>{1.0}, -22)); |
| 140 | EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, true), |
| 141 | Real<8>{1.0} + std::ldexp(Real<8>{1.0}, -52)); |
| 142 | EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, false), |
Peter Klausler | 39c2f59 | 2023-12-26 15:28:36 -0800 | [diff] [blame] | 143 | Real<8>{1.0} - 0.5 * std::ldexp(Real<8>{1.0}, -52)); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 144 | } |
| 145 | |
| 146 | TEST(Numeric, Nint) { |
| 147 | EXPECT_EQ(RTNAME(Nint4_4)(Real<4>{2.783}), 3); |
| 148 | EXPECT_EQ(RTNAME(Nint8_4)(Real<8>{-2.783}), -3); |
| 149 | EXPECT_EQ(RTNAME(Nint4_4)(Real<4>{2.5}), 3); |
| 150 | EXPECT_EQ(RTNAME(Nint8_4)(Real<8>{-2.5}), -3); |
| 151 | EXPECT_EQ(RTNAME(Nint8_8)(Real<8>{0}), 0); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 152 | } |
| 153 | |
| 154 | TEST(Numeric, RRSpacing) { |
| 155 | EXPECT_EQ(RTNAME(RRSpacing8)(Real<8>{0}), 0); |
| 156 | EXPECT_EQ(RTNAME(RRSpacing4)(Real<4>{-3.0}), 0.75 * (1 << 24)); |
| 157 | EXPECT_EQ(RTNAME(RRSpacing8)(Real<8>{-3.0}), 0.75 * (std::int64_t{1} << 53)); |
| 158 | EXPECT_TRUE( |
| 159 | std::isnan(RTNAME(RRSpacing4)(std::numeric_limits<Real<4>>::infinity()))); |
| 160 | EXPECT_TRUE(std::isnan( |
| 161 | RTNAME(RRSpacing8)(std::numeric_limits<Real<8>>::quiet_NaN()))); |
| 162 | } |
| 163 | |
| 164 | TEST(Numeric, Scale) { |
| 165 | EXPECT_EQ(RTNAME(Scale4)(Real<4>{0}, 0), 0); |
| 166 | EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, 0), 1.0); |
| 167 | EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, 1), 2.0); |
| 168 | EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, -1), 0.5); |
| 169 | EXPECT_TRUE( |
| 170 | std::isinf(RTNAME(Scale4)(std::numeric_limits<Real<4>>::infinity(), 1))); |
| 171 | EXPECT_TRUE( |
| 172 | std::isnan(RTNAME(Scale8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1))); |
| 173 | } |
| 174 | |
| 175 | TEST(Numeric, SetExponent) { |
| 176 | EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{0}, 0), 0); |
| 177 | EXPECT_EQ(RTNAME(SetExponent8)(Real<8>{0}, 666), 0); |
peter klausler | a05bae6 | 2021-08-12 11:10:53 -0700 | [diff] [blame] | 178 | EXPECT_EQ(RTNAME(SetExponent8)(Real<8>{3.0}, 0), 0.75); |
| 179 | EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 0), 0.5); |
| 180 | EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 1), 1.0); |
| 181 | EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, -1), 0.25); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 182 | EXPECT_TRUE(std::isnan( |
| 183 | RTNAME(SetExponent4)(std::numeric_limits<Real<4>>::infinity(), 1))); |
| 184 | EXPECT_TRUE(std::isnan( |
| 185 | RTNAME(SetExponent8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1))); |
| 186 | } |
| 187 | |
Peixin Qiao | f532c07 | 2022-07-26 00:33:27 +0800 | [diff] [blame] | 188 | TEST(Numeric, SelectedIntKind) { |
| 189 | std::int8_t r0 = 1; |
| 190 | std::int16_t r1 = 3; |
| 191 | std::int32_t r2 = 8; |
| 192 | std::int64_t r3 = 10; |
| 193 | std::int32_t r4 = -10; |
| 194 | std::int32_t r5 = 100; |
| 195 | EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r0, 1), 1); |
| 196 | EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r1, 2), 2); |
| 197 | EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r2, 4), 4); |
| 198 | EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r3, 8), 8); |
| 199 | EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r4, 4), 1); |
| 200 | EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r5, 4), -1); |
| 201 | } |
| 202 | |
Peixin Qiao | 57e3fa3 | 2022-07-25 19:36:14 +0800 | [diff] [blame] | 203 | TEST(Numeric, SelectedRealKind) { |
| 204 | std::int8_t p_s = 1; |
| 205 | std::int16_t p[11] = {-10, 1, 1, 4, 50, 1, 1, 4, 1, 1, 50}; |
| 206 | std::int32_t r[11] = {-1, 1, 1, 1, 2, 1, 20, 20, 100, 5000, 5000}; |
| 207 | std::int64_t d[11] = {2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2}; |
| 208 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 209 | __FILE__, __LINE__, &p[0], 2, &r[0], 4, &d[0], 8), |
| 210 | 2); |
| 211 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 212 | __FILE__, __LINE__, &p[1], 2, &r[1], 4, &d[1], 8), |
| 213 | -5); |
| 214 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 215 | __FILE__, __LINE__, &p[2], 2, &r[2], 4, &d[2], 8), |
| 216 | 2); |
| 217 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 218 | __FILE__, __LINE__, &p[3], 2, &r[3], 4, &d[3], 8), |
| 219 | 4); |
| 220 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 221 | __FILE__, __LINE__, &p[4], 2, &r[4], 4, &d[4], 8), |
| 222 | -1); |
| 223 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 224 | __FILE__, __LINE__, &p[5], 2, &r[5], 4, &d[5], 8), |
| 225 | 2); |
| 226 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 227 | __FILE__, __LINE__, &p[6], 2, &r[6], 4, &d[6], 8), |
| 228 | 3); |
| 229 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 230 | __FILE__, __LINE__, &p[7], 2, &r[7], 4, &d[7], 8), |
| 231 | 4); |
| 232 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 233 | __FILE__, __LINE__, &p[8], 2, &r[8], 4, &d[8], 8), |
| 234 | 8); |
| 235 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 236 | __FILE__, __LINE__, &p[9], 2, &r[9], 4, &d[9], 8), |
| 237 | -2); |
| 238 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 239 | __FILE__, __LINE__, &p[10], 2, &r[10], 4, &d[10], 8), |
| 240 | -3); |
| 241 | EXPECT_EQ( |
| 242 | RTNAME(SelectedRealKind)(__FILE__, __LINE__, &p_s, 1, &r[0], 4, &d[0], 8), |
| 243 | 2); |
| 244 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 245 | __FILE__, __LINE__, nullptr, 0, &r[0], 4, &d[0], 8), |
| 246 | 2); |
| 247 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 248 | __FILE__, __LINE__, &p[0], 2, nullptr, 0, &d[0], 8), |
| 249 | 2); |
| 250 | EXPECT_EQ(RTNAME(SelectedRealKind)( |
| 251 | __FILE__, __LINE__, &p[0], 2, &r[0], 4, nullptr, 0), |
| 252 | 2); |
| 253 | } |
| 254 | |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 255 | TEST(Numeric, Spacing) { |
| 256 | EXPECT_EQ(RTNAME(Spacing8)(Real<8>{0}), std::numeric_limits<Real<8>>::min()); |
| 257 | EXPECT_EQ(RTNAME(Spacing4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -22)); |
| 258 | EXPECT_TRUE( |
| 259 | std::isnan(RTNAME(Spacing4)(std::numeric_limits<Real<4>>::infinity()))); |
| 260 | EXPECT_TRUE( |
| 261 | std::isnan(RTNAME(Spacing8)(std::numeric_limits<Real<8>>::quiet_NaN()))); |
Peter Klausler | 500f6cc | 2024-09-04 10:53:22 -0700 | [diff] [blame] | 262 | EXPECT_EQ(RTNAME(Spacing2By4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -9)); |
| 263 | EXPECT_EQ(RTNAME(Spacing2By4)(Real<4>{0.0}), Real<4>{0.00006103515625E-04}); |
| 264 | EXPECT_EQ(RTNAME(Spacing3By4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -6)); |
| 265 | EXPECT_EQ( |
| 266 | RTNAME(Spacing3By4)(Real<4>{0.0}), std::numeric_limits<Real<4>>::min()); |
peter klausler | 5f6c5c6 | 2021-04-01 12:59:59 -0700 | [diff] [blame] | 267 | } |
Slava Zakharin | 9e8f677 | 2022-12-14 10:22:00 -0800 | [diff] [blame] | 268 | |
| 269 | TEST(Numeric, FPowI) { |
| 270 | EXPECT_EQ(RTNAME(FPow4i)(Real<4>{0}, Int<4>{0}), Real<4>{1}); |
| 271 | EXPECT_EQ(RTNAME(FPow4i)(Real<4>{0.3}, Int<4>{0}), Real<4>{1}); |
| 272 | EXPECT_EQ(RTNAME(FPow4i)(Real<4>{2}, Int<4>{-1}), Real<4>{0.5}); |
| 273 | EXPECT_EQ(RTNAME(FPow4i)(Real<4>{0.5}, Int<4>{-1}), Real<4>{2}); |
| 274 | EXPECT_EQ(RTNAME(FPow4i)(Real<4>{-3}, Int<4>{3}), Real<4>{-27}); |
| 275 | EXPECT_EQ(RTNAME(FPow4i)(Real<4>{-2}, Int<4>{-3}), Real<4>{-0.125}); |
| 276 | |
| 277 | EXPECT_EQ(RTNAME(FPow4k)(Real<4>{0}, Int<8>{0}), Real<4>{1}); |
| 278 | EXPECT_EQ(RTNAME(FPow4k)(Real<4>{0.3}, Int<8>{0}), Real<4>{1}); |
| 279 | EXPECT_EQ(RTNAME(FPow4k)(Real<4>{2}, Int<8>{-1}), Real<4>{0.5}); |
| 280 | EXPECT_EQ(RTNAME(FPow4k)(Real<4>{0.5}, Int<8>{-1}), Real<4>{2}); |
| 281 | EXPECT_EQ(RTNAME(FPow4k)(Real<4>{-3}, Int<8>{3}), Real<4>{-27}); |
| 282 | EXPECT_EQ(RTNAME(FPow4k)(Real<4>{-2}, Int<8>{-3}), Real<4>{-0.125}); |
| 283 | |
| 284 | EXPECT_EQ(RTNAME(FPow8i)(Real<8>{0}, Int<4>{0}), Real<8>{1}); |
| 285 | EXPECT_EQ(RTNAME(FPow8i)(Real<8>{0.3}, Int<4>{0}), Real<8>{1}); |
| 286 | EXPECT_EQ(RTNAME(FPow8i)(Real<8>{2}, Int<4>{-1}), Real<8>{0.5}); |
| 287 | EXPECT_EQ(RTNAME(FPow8i)(Real<8>{0.5}, Int<4>{-1}), Real<8>{2}); |
| 288 | EXPECT_EQ(RTNAME(FPow8i)(Real<8>{-3}, Int<4>{3}), Real<8>{-27}); |
| 289 | EXPECT_EQ(RTNAME(FPow8i)(Real<8>{-2}, Int<4>{-3}), Real<8>{-0.125}); |
| 290 | |
| 291 | EXPECT_EQ(RTNAME(FPow8k)(Real<8>{0}, Int<8>{0}), Real<8>{1}); |
| 292 | EXPECT_EQ(RTNAME(FPow8k)(Real<8>{0.3}, Int<8>{0}), Real<8>{1}); |
| 293 | EXPECT_EQ(RTNAME(FPow8k)(Real<8>{2}, Int<8>{-1}), Real<8>{0.5}); |
| 294 | EXPECT_EQ(RTNAME(FPow8k)(Real<8>{0.5}, Int<8>{-1}), Real<8>{2}); |
| 295 | EXPECT_EQ(RTNAME(FPow8k)(Real<8>{-3}, Int<8>{3}), Real<8>{-27}); |
| 296 | EXPECT_EQ(RTNAME(FPow8k)(Real<8>{-2}, Int<8>{-3}), Real<8>{-0.125}); |
| 297 | |
Slava Zakharin | 104f3c1 | 2024-09-18 17:41:33 -0700 | [diff] [blame] | 298 | #if HAS_FLOAT80 |
Slava Zakharin | 9e8f677 | 2022-12-14 10:22:00 -0800 | [diff] [blame] | 299 | EXPECT_EQ(RTNAME(FPow10i)(Real<10>{0}, Int<4>{0}), Real<10>{1}); |
| 300 | EXPECT_EQ(RTNAME(FPow10i)(Real<10>{0.3}, Int<4>{0}), Real<10>{1}); |
| 301 | EXPECT_EQ(RTNAME(FPow10i)(Real<10>{2}, Int<4>{-1}), Real<10>{0.5}); |
| 302 | EXPECT_EQ(RTNAME(FPow10i)(Real<10>{0.5}, Int<4>{-1}), Real<10>{2}); |
| 303 | EXPECT_EQ(RTNAME(FPow10i)(Real<10>{-3}, Int<4>{3}), Real<10>{-27}); |
| 304 | EXPECT_EQ(RTNAME(FPow10i)(Real<10>{-2}, Int<4>{-3}), Real<10>{-0.125}); |
| 305 | |
| 306 | EXPECT_EQ(RTNAME(FPow10k)(Real<10>{0}, Int<8>{0}), Real<10>{1}); |
| 307 | EXPECT_EQ(RTNAME(FPow10k)(Real<10>{0.3}, Int<8>{0}), Real<10>{1}); |
| 308 | EXPECT_EQ(RTNAME(FPow10k)(Real<10>{2}, Int<8>{-1}), Real<10>{0.5}); |
| 309 | EXPECT_EQ(RTNAME(FPow10k)(Real<10>{0.5}, Int<8>{-1}), Real<10>{2}); |
| 310 | EXPECT_EQ(RTNAME(FPow10k)(Real<10>{-3}, Int<8>{3}), Real<10>{-27}); |
| 311 | EXPECT_EQ(RTNAME(FPow10k)(Real<10>{-2}, Int<8>{-3}), Real<10>{-0.125}); |
| 312 | #endif |
Slava Zakharin | fc51c7f | 2024-09-19 15:45:45 -0700 | [diff] [blame] | 313 | #if HAS_LDBL128 || HAS_FLOAT128 |
Slava Zakharin | 9e8f677 | 2022-12-14 10:22:00 -0800 | [diff] [blame] | 314 | EXPECT_EQ(RTNAME(FPow16i)(Real<16>{0}, Int<4>{0}), Real<16>{1}); |
| 315 | EXPECT_EQ(RTNAME(FPow16i)(Real<16>{0.3}, Int<4>{0}), Real<16>{1}); |
| 316 | EXPECT_EQ(RTNAME(FPow16i)(Real<16>{2}, Int<4>{-1}), Real<16>{0.5}); |
| 317 | EXPECT_EQ(RTNAME(FPow16i)(Real<16>{0.5}, Int<4>{-1}), Real<16>{2}); |
| 318 | EXPECT_EQ(RTNAME(FPow16i)(Real<16>{-3}, Int<4>{3}), Real<16>{-27}); |
| 319 | EXPECT_EQ(RTNAME(FPow16i)(Real<16>{-2}, Int<4>{-3}), Real<16>{-0.125}); |
| 320 | |
| 321 | EXPECT_EQ(RTNAME(FPow16k)(Real<16>{0}, Int<8>{0}), Real<16>{1}); |
| 322 | EXPECT_EQ(RTNAME(FPow16k)(Real<16>{0.3}, Int<8>{0}), Real<16>{1}); |
| 323 | EXPECT_EQ(RTNAME(FPow16k)(Real<16>{2}, Int<8>{-1}), Real<16>{0.5}); |
| 324 | EXPECT_EQ(RTNAME(FPow16k)(Real<16>{0.5}, Int<8>{-1}), Real<16>{2}); |
| 325 | EXPECT_EQ(RTNAME(FPow16k)(Real<16>{-3}, Int<8>{3}), Real<16>{-27}); |
| 326 | EXPECT_EQ(RTNAME(FPow16k)(Real<16>{-2}, Int<8>{-3}), Real<16>{-0.125}); |
| 327 | #endif |
| 328 | |
| 329 | // Test some extreme values. |
| 330 | if (sizeof(double) == sizeof(std::uint64_t)) { |
| 331 | // (0x3FF0000000000001 ** -2147483648) ~ 0x3FEFFFFF00000401 |
| 332 | double base; |
| 333 | *reinterpret_cast<std::uint64_t *>(&base) = 4607182418800017409ULL; |
| 334 | double result; |
| 335 | *reinterpret_cast<std::uint64_t *>(&result) = 4607182414505051137ULL; |
| 336 | EXPECT_TRUE(std::abs(RTNAME(FPow8i)(Real<8>{base}, |
| 337 | Int<4>{std::numeric_limits<Int<4>>::min()}) - |
| 338 | Real<8>{result}) < 0.00000000001); |
| 339 | |
| 340 | // (0x3FF0000000000001 ** 4294967296ULL) ~ 0x3FF00001000007FF |
| 341 | *reinterpret_cast<std::uint64_t *>(&base) = 4607182418800017409ULL; |
| 342 | *reinterpret_cast<std::uint64_t *>(&result) = 4607182423094986751ULL; |
| 343 | EXPECT_TRUE(std::abs(RTNAME(FPow8k)(Real<8>{base}, Int<8>{4294967296ULL}) - |
| 344 | Real<8>{result}) < 0.00000000001); |
| 345 | } |
| 346 | } |