1 //===-- flang/unittests/Runtime/Numeric.cpp ---------------------*- C++ -*-===// 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 9 #include "flang/Runtime/numeric.h" 10 #include "gtest/gtest.h" 11 #include "flang/Common/float128.h" 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 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); 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); 32 } 33 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); 37 #if HAS_FLOAT80 38 EXPECT_NEAR(RTNAME(ErfcScaled10)(Real<10>{20.0}), 0.02817434874, 1.0e-8); 39 #endif 40 } 41 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 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 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); 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); 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); 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); 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), 143 Real<8>{1.0} - 0.5 * std::ldexp(Real<8>{1.0}, -52)); 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); 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); 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); 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 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 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 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()))); 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()); 267 } 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 298 #if HAS_FLOAT80 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 313 #if HAS_LDBL128 || HAS_FLOAT128 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 } 347