// Copyright (C) 2020-2024 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . // only: float|double|ldouble * * * // expensive: * [1-9] * * #include "bits/main.h" template void test() { vir::test::setFuzzyness(0); vir::test::setFuzzyness(0); using T = typename V::value_type; constexpr T inf = std::__infinity_v; constexpr T nan = std::__quiet_NaN_v; constexpr T denorm_min = std::__denorm_min_v; constexpr T norm_min = std::__norm_min_v; constexpr T max = std::__finite_max_v; #if defined __LONG_DOUBLE_IBM128__ // On POWER with IBM128 long double, 1+eps and 2-eps is not a constant // expression. Until this is fixed, just use const instead of constexpr. // (error: '(1.0e+0l + 4.94065645841246544176568792868221e-324l)' is not a // constant expression) const T after_one = 1 + std::__epsilon_v; const T before_one = (2 - std::__epsilon_v) / 2; #else constexpr T after_one = 1 + std::__epsilon_v; constexpr T before_one = (2 - std::__epsilon_v) / 2; #endif const std::initializer_list input_values = {+0., 0.5, -0.5, before_one, -before_one, after_one, -after_one, 1.5, -1.5, 2 * before_one, -2 * before_one, 2 * after_one, -2 * after_one, 2.5, -2.5, 0x1.fffffffffffffp52, -0x1.fffffffffffffp52, 0x1.ffffffffffffep52, -0x1.ffffffffffffep52, 0x1.ffffffffffffdp52, -0x1.ffffffffffffdp52, 0x1.fffffep21, -0x1.fffffep21, 0x1.fffffcp21, -0x1.fffffcp21, 0x1.fffffep22, -0x1.fffffep22, 0x1.fffffcp22, -0x1.fffffcp22, 0x1.fffffep23, -0x1.fffffep23, 0x1.fffffcp23, -0x1.fffffcp23, 0x1.8p23, -0x1.8p23, inf, -inf, -0., nan, denorm_min, norm_min / 3, norm_min, max}; test_values(input_values, {10000}, MAKE_TESTER(erf), MAKE_TESTER(erfc), MAKE_TESTER(tgamma), MAKE_TESTER(lgamma), MAKE_TESTER(ceil), MAKE_TESTER(floor), MAKE_TESTER(trunc), MAKE_TESTER(round), MAKE_TESTER(lround), MAKE_TESTER(llround), MAKE_TESTER(nearbyint), MAKE_TESTER(rint), MAKE_TESTER(lrint), MAKE_TESTER(llrint), MAKE_TESTER(ilogb)); // sqrt(x) on x87 is precise in 80 bits, but the subsequent rounding can be // wrong (up to 1 ULP) #if __FLT_EVAL_METHOD__ == 1 vir::test::setFuzzyness(1); vir::test::setFuzzyness(0); #elif __FLT_EVAL_METHOD__ == 2 vir::test::setFuzzyness(1); vir::test::setFuzzyness(1); #endif test_values(input_values, {10000}, MAKE_TESTER(sqrt)); }