1 //===-- Unittests for cosf ------------------------------------------------===// 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 "include/math.h" 10 #include "src/errno/llvmlibc_errno.h" 11 #include "src/math/cosf.h" 12 #include "src/math/math_utils.h" 13 #include "test/src/math/float.h" 14 #include "test/src/math/sdcomp26094.h" 15 #include "utils/CPP/Array.h" 16 #include "utils/MPFRWrapper/MPFRUtils.h" 17 #include "utils/UnitTest/Test.h" 18 19 #include <stdint.h> 20 21 using __llvm_libc::as_float; 22 using __llvm_libc::as_uint32_bits; 23 24 using __llvm_libc::testing::FloatBits; 25 using __llvm_libc::testing::sdcomp26094Values; 26 27 namespace mpfr = __llvm_libc::testing::mpfr; 28 29 // 12 additional bits of precision over the base precision of a |float| 30 // value. 31 static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 12, 32 3 * 0x1000 / 4}; 33 34 TEST(CosfTest, SpecialNumbers) { 35 llvmlibc_errno = 0; 36 37 EXPECT_TRUE(FloatBits::isQNan( 38 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::QNan))))); 39 EXPECT_EQ(llvmlibc_errno, 0); 40 41 EXPECT_TRUE(FloatBits::isNegQNan( 42 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::NegQNan))))); 43 EXPECT_EQ(llvmlibc_errno, 0); 44 45 EXPECT_TRUE(FloatBits::isQNan( 46 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::SNan))))); 47 EXPECT_EQ(llvmlibc_errno, 0); 48 49 EXPECT_TRUE(FloatBits::isNegQNan( 50 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::NegSNan))))); 51 EXPECT_EQ(llvmlibc_errno, 0); 52 53 EXPECT_EQ(FloatBits::One, 54 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::Zero)))); 55 EXPECT_EQ(llvmlibc_errno, 0); 56 57 EXPECT_EQ(FloatBits::One, 58 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::NegZero)))); 59 EXPECT_EQ(llvmlibc_errno, 0); 60 61 llvmlibc_errno = 0; 62 EXPECT_TRUE(FloatBits::isQNan( 63 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::Inf))))); 64 EXPECT_EQ(llvmlibc_errno, EDOM); 65 66 llvmlibc_errno = 0; 67 EXPECT_TRUE(FloatBits::isNegQNan( 68 as_uint32_bits(__llvm_libc::cosf(as_float(FloatBits::NegInf))))); 69 EXPECT_EQ(llvmlibc_errno, EDOM); 70 } 71 72 TEST(CosfTest, InFloatRange) { 73 constexpr uint32_t count = 1000000; 74 constexpr uint32_t step = UINT32_MAX / count; 75 for (uint32_t i = 0, v = 0; i <= count; ++i, v += step) { 76 float x = as_float(v); 77 if (isnan(x) || isinf(x)) 78 continue; 79 ASSERT_MPFR_MATCH(mpfr::OP_Cos, x, __llvm_libc::cosf(x), tolerance); 80 } 81 } 82 83 // For small values, cos(x) is 1. 84 TEST(CosfTest, SmallValues) { 85 float x = as_float(0x17800000); 86 float result = __llvm_libc::cosf(x); 87 EXPECT_MPFR_MATCH(mpfr::OP_Cos, x, result, tolerance); 88 EXPECT_EQ(FloatBits::One, as_uint32_bits(result)); 89 90 x = as_float(0x0040000); 91 result = __llvm_libc::cosf(x); 92 EXPECT_MPFR_MATCH(mpfr::OP_Cos, x, result, tolerance); 93 EXPECT_EQ(FloatBits::One, as_uint32_bits(result)); 94 } 95 96 // SDCOMP-26094: check cosf in the cases for which the range reducer 97 // returns values furthest beyond its nominal upper bound of pi/4. 98 TEST(CosfTest, SDCOMP_26094) { 99 for (uint32_t v : sdcomp26094Values) { 100 float x = as_float(v); 101 ASSERT_MPFR_MATCH(mpfr::OP_Cos, x, __llvm_libc::cosf(x), tolerance); 102 } 103 } 104