1 //===-- Utility class to test frexp[f|l] ------------------------*- 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 "src/__support/FPUtil/BasicOperations.h" 10 #include "test/UnitTest/FEnvSafeTest.h" 11 #include "test/UnitTest/FPMatcher.h" 12 #include "test/UnitTest/Test.h" 13 14 template <typename T> 15 class FrexpTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { 16 17 DECLARE_SPECIAL_CONSTANTS(T) 18 19 public: 20 typedef T (*FrexpFunc)(T, int *); 21 testSpecialNumbers(FrexpFunc func)22 void testSpecialNumbers(FrexpFunc func) { 23 int exponent; 24 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, &exponent)); 25 EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, &exponent)); 26 EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, &exponent)); 27 28 EXPECT_FP_EQ_ALL_ROUNDING(0.0, func(0.0, &exponent)); 29 EXPECT_EQ(exponent, 0); 30 31 EXPECT_FP_EQ_ALL_ROUNDING(-0.0, func(-0.0, &exponent)); 32 EXPECT_EQ(exponent, 0); 33 } 34 testPowersOfTwo(FrexpFunc func)35 void testPowersOfTwo(FrexpFunc func) { 36 int exponent; 37 38 EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(1.0), &exponent)); 39 EXPECT_EQ(exponent, 1); 40 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-1.0), &exponent)); 41 EXPECT_EQ(exponent, 1); 42 43 EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(2.0), &exponent)); 44 EXPECT_EQ(exponent, 2); 45 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-2.0), &exponent)); 46 EXPECT_EQ(exponent, 2); 47 48 EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(4.0), &exponent)); 49 EXPECT_EQ(exponent, 3); 50 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-4.0), &exponent)); 51 EXPECT_EQ(exponent, 3); 52 53 EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(8.0), &exponent)); 54 EXPECT_EQ(exponent, 4); 55 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-8.0), &exponent)); 56 EXPECT_EQ(exponent, 4); 57 58 EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(16.0), &exponent)); 59 EXPECT_EQ(exponent, 5); 60 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-16.0), &exponent)); 61 EXPECT_EQ(exponent, 5); 62 63 EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(32.0), &exponent)); 64 EXPECT_EQ(exponent, 6); 65 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-32.0), &exponent)); 66 EXPECT_EQ(exponent, 6); 67 } 68 testSomeIntegers(FrexpFunc func)69 void testSomeIntegers(FrexpFunc func) { 70 int exponent; 71 72 EXPECT_FP_EQ_ALL_ROUNDING(T(0.75), func(T(24.0), &exponent)); 73 EXPECT_EQ(exponent, 5); 74 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.75), func(T(-24.0), &exponent)); 75 EXPECT_EQ(exponent, 5); 76 77 EXPECT_FP_EQ_ALL_ROUNDING(T(0.625), func(T(40.0), &exponent)); 78 EXPECT_EQ(exponent, 6); 79 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.625), func(T(-40.0), &exponent)); 80 EXPECT_EQ(exponent, 6); 81 82 EXPECT_FP_EQ_ALL_ROUNDING(T(0.78125), func(T(800.0), &exponent)); 83 EXPECT_EQ(exponent, 10); 84 EXPECT_FP_EQ_ALL_ROUNDING(T(-0.78125), func(T(-800.0), &exponent)); 85 EXPECT_EQ(exponent, 10); 86 } 87 }; 88 89 #define LIST_FREXP_TESTS(T, func) \ 90 using LlvmLibcFrexpTest = FrexpTest<T>; \ 91 TEST_F(LlvmLibcFrexpTest, SpecialNumbers) { testSpecialNumbers(&func); } \ 92 TEST_F(LlvmLibcFrexpTest, PowersOfTwo) { testPowersOfTwo(&func); } \ 93 TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); } \ 94 static_assert(true, "Require semicolon.") 95