258 lines · cpp
1//===-- Unittests for pow -------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "hdr/fenv_macros.h"10#include "src/math/pow.h"11#include "test/UnitTest/FPMatcher.h"12#include "test/UnitTest/Test.h"13 14using LlvmLibcPowTest = LIBC_NAMESPACE::testing::FPTest<double>;15using LIBC_NAMESPACE::fputil::testing::ForceRoundingMode;16using LIBC_NAMESPACE::fputil::testing::RoundingMode;17 18TEST_F(LlvmLibcPowTest, SpecialNumbers) {19 constexpr double NEG_ODD_INTEGER = -3.0;20 constexpr double NEG_EVEN_INTEGER = -6.0;21 constexpr double NEG_NON_INTEGER = -1.1;22 constexpr double POS_ODD_INTEGER = 5.0;23 constexpr double POS_EVEN_INTEGER = 8.0;24 constexpr double POS_NON_INTEGER = 1.1;25 constexpr double ONE_HALF = 0.5;26 27 for (int i = 0; i < N_ROUNDING_MODES; ++i) {28 ForceRoundingMode __r(ROUNDING_MODES[i]);29 if (!__r.success)30 continue;31 32 // pow( sNaN, exponent )33 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, sNaN),34 FE_INVALID);35 EXPECT_FP_EQ_WITH_EXCEPTION(36 aNaN, LIBC_NAMESPACE::pow(sNaN, NEG_ODD_INTEGER), FE_INVALID);37 EXPECT_FP_EQ_WITH_EXCEPTION(38 aNaN, LIBC_NAMESPACE::pow(sNaN, NEG_EVEN_INTEGER), FE_INVALID);39 EXPECT_FP_EQ_WITH_EXCEPTION(40 aNaN, LIBC_NAMESPACE::pow(sNaN, POS_ODD_INTEGER), FE_INVALID);41 EXPECT_FP_EQ_WITH_EXCEPTION(42 aNaN, LIBC_NAMESPACE::pow(sNaN, POS_EVEN_INTEGER), FE_INVALID);43 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, ONE_HALF),44 FE_INVALID);45 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, zero),46 FE_INVALID);47 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, neg_zero),48 FE_INVALID);49 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, inf),50 FE_INVALID);51 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, neg_inf),52 FE_INVALID);53 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, aNaN),54 FE_INVALID);55 56 // pow( 0.0, exponent )57 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(zero, sNaN),58 FE_INVALID);59 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_ODD_INTEGER),60 FE_DIVBYZERO);61 EXPECT_FP_EQ_WITH_EXCEPTION(62 inf, LIBC_NAMESPACE::pow(zero, NEG_EVEN_INTEGER), FE_DIVBYZERO);63 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_NON_INTEGER),64 FE_DIVBYZERO);65 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_ODD_INTEGER));66 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_EVEN_INTEGER));67 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_NON_INTEGER));68 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, ONE_HALF));69 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, zero));70 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, neg_zero));71 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(zero, inf));72 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, neg_inf),73 FE_DIVBYZERO);74 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(zero, aNaN));75 76 // pow( -0.0, exponent )77 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(neg_zero, sNaN),78 FE_INVALID);79 EXPECT_FP_EQ_WITH_EXCEPTION(80 neg_inf, LIBC_NAMESPACE::pow(neg_zero, NEG_ODD_INTEGER), FE_DIVBYZERO);81 EXPECT_FP_EQ_WITH_EXCEPTION(82 inf, LIBC_NAMESPACE::pow(neg_zero, NEG_EVEN_INTEGER), FE_DIVBYZERO);83 EXPECT_FP_EQ_WITH_EXCEPTION(84 inf, LIBC_NAMESPACE::pow(neg_zero, NEG_NON_INTEGER), FE_DIVBYZERO);85 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_zero, POS_ODD_INTEGER));86 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_EVEN_INTEGER));87 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_NON_INTEGER));88 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, ONE_HALF));89 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, zero));90 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, neg_zero));91 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(neg_zero, inf));92 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(neg_zero, neg_inf),93 FE_DIVBYZERO);94 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_zero, aNaN));95 96 // pow( 1.0, exponent )97 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(1.0, sNaN),98 FE_INVALID);99 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, zero));100 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_zero));101 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, 1.0));102 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, -1.0));103 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_ODD_INTEGER));104 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_EVEN_INTEGER));105 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_NON_INTEGER));106 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_ODD_INTEGER));107 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_EVEN_INTEGER));108 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_NON_INTEGER));109 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, inf));110 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_inf));111 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, aNaN));112 113 // pow( -1.0, exponent )114 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(-1.0, sNaN),115 FE_INVALID);116 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, zero));117 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_zero));118 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, 1.0));119 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, -1.0));120 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, NEG_ODD_INTEGER));121 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, NEG_EVEN_INTEGER));122 EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, NEG_NON_INTEGER),123 FE_INVALID);124 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, POS_ODD_INTEGER));125 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, POS_EVEN_INTEGER));126 EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, POS_NON_INTEGER),127 FE_INVALID);128 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, inf));129 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_inf));130 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-1.0, aNaN));131 132 // pow( inf, exponent )133 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(inf, sNaN),134 FE_INVALID);135 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, zero));136 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, neg_zero));137 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, 1.0));138 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, -1.0));139 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_ODD_INTEGER));140 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_EVEN_INTEGER));141 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_NON_INTEGER));142 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_ODD_INTEGER));143 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_EVEN_INTEGER));144 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_NON_INTEGER));145 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, ONE_HALF));146 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, inf));147 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, neg_inf));148 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(inf, aNaN));149 150 // pow( -inf, exponent )151 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(neg_inf, sNaN),152 FE_INVALID);153 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, zero));154 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, neg_zero));155 EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, 1.0));156 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, -1.0));157 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, NEG_ODD_INTEGER));158 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_EVEN_INTEGER));159 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_NON_INTEGER));160 EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, POS_ODD_INTEGER));161 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_EVEN_INTEGER));162 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_NON_INTEGER));163 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, ONE_HALF));164 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, inf));165 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, neg_inf));166 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_inf, aNaN));167 168 // pow ( aNaN, exponent )169 EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(aNaN, sNaN),170 FE_INVALID);171 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, zero));172 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, neg_zero));173 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, 1.0));174 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, -1.0));175 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_ODD_INTEGER));176 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_EVEN_INTEGER));177 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_NON_INTEGER));178 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_ODD_INTEGER));179 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_EVEN_INTEGER));180 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_NON_INTEGER));181 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, inf));182 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, neg_inf));183 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, aNaN));184 185 // pow ( base, inf )186 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(0.1, inf));187 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-0.1, inf));188 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(1.1, inf));189 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-1.1, inf));190 191 // pow ( base, -inf )192 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(0.1, neg_inf));193 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-0.1, neg_inf));194 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(1.1, neg_inf));195 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-1.1, neg_inf));196 197 // Exact powers of 2:198 // TODO: Enable these tests when we use exp2.199 // EXPECT_FP_EQ(0x1.0p15, LIBC_NAMESPACE::pow(2.0, 15.0));200 // EXPECT_FP_EQ(0x1.0p126, LIBC_NAMESPACE::pow(2.0, 126.0));201 // EXPECT_FP_EQ(0x1.0p-45, LIBC_NAMESPACE::pow(2.0, -45.0));202 // EXPECT_FP_EQ(0x1.0p-126, LIBC_NAMESPACE::pow(2.0, -126.0));203 // EXPECT_FP_EQ(0x1.0p-149, LIBC_NAMESPACE::pow(2.0, -149.0));204 205 // Exact powers of 10:206 // TODO: Enable these tests when we use exp10207 // EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(10.0, 0.0));208 // EXPECT_FP_EQ(10.0, LIBC_NAMESPACE::pow(10.0, 1.0));209 // EXPECT_FP_EQ(100.0, LIBC_NAMESPACE::pow(10.0, 2.0));210 // EXPECT_FP_EQ(1000.0, LIBC_NAMESPACE::pow(10.0, 3.0));211 // EXPECT_FP_EQ(10000.0, LIBC_NAMESPACE::pow(10.0, 4.0));212 // EXPECT_FP_EQ(100000.0, LIBC_NAMESPACE::pow(10.0, 5.0));213 // EXPECT_FP_EQ(1000000.0, LIBC_NAMESPACE::pow(10.0, 6.0));214 // EXPECT_FP_EQ(10000000.0, LIBC_NAMESPACE::pow(10.0, 7.0));215 // EXPECT_FP_EQ(100000000.0, LIBC_NAMESPACE::pow(10.0, 8.0));216 // EXPECT_FP_EQ(1000000000.0, LIBC_NAMESPACE::pow(10.0, 9.0));217 // EXPECT_FP_EQ(10000000000.0, LIBC_NAMESPACE::pow(10.0, 10.0));218 219 // Overflow / Underflow:220 if (ROUNDING_MODES[i] != RoundingMode::Downward &&221 ROUNDING_MODES[i] != RoundingMode::TowardZero) {222 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(3.1, 2001.0),223 FE_OVERFLOW);224 }225 if (ROUNDING_MODES[i] != RoundingMode::Upward) {226 EXPECT_FP_EQ_WITH_EXCEPTION(0.0, LIBC_NAMESPACE::pow(3.1, -2001.0),227 FE_UNDERFLOW);228 }229 }230}231 232#ifdef LIBC_TEST_FTZ_DAZ233 234using namespace LIBC_NAMESPACE::testing;235 236TEST_F(LlvmLibcPowTest, FTZMode) {237 ModifyMXCSR mxcsr(FTZ);238 239 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-min_denormal, 0.5));240 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));241}242 243TEST_F(LlvmLibcPowTest, DAZMode) {244 ModifyMXCSR mxcsr(DAZ);245 246 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5));247 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));248}249 250TEST_F(LlvmLibcPowTest, FTZDAZMode) {251 ModifyMXCSR mxcsr(FTZ | DAZ);252 253 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5));254 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));255}256 257#endif258