1 //===-- Unittests for frexpf ----------------------------------------------===//
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/math/frexpf.h"
10 #include "utils/FPUtil/BasicOperations.h"
11 #include "utils/FPUtil/BitPatterns.h"
12 #include "utils/FPUtil/ClassificationFunctions.h"
13 #include "utils/FPUtil/FPBits.h"
14 #include "utils/FPUtil/FloatOperations.h"
15 #include "utils/FPUtil/FloatProperties.h"
16 #include "utils/MPFRWrapper/MPFRUtils.h"
17 #include "utils/UnitTest/Test.h"
18 #include <math.h>
19 
20 using FPBits = __llvm_libc::fputil::FPBits<float>;
21 using __llvm_libc::fputil::valueAsBits;
22 using __llvm_libc::fputil::valueFromBits;
23 
24 namespace mpfr = __llvm_libc::testing::mpfr;
25 
26 using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
27 using Properties = __llvm_libc::fputil::FloatProperties<float>;
28 
TEST(FrexpfTest,SpecialNumbers)29 TEST(FrexpfTest, SpecialNumbers) {
30   int exponent;
31 
32   EXPECT_EQ(BitPatterns::aQuietNaN,
33             valueAsBits(__llvm_libc::frexpf(
34                 valueFromBits(BitPatterns::aQuietNaN), &exponent)));
35   EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
36             valueAsBits(__llvm_libc::frexpf(
37                 valueFromBits(BitPatterns::aNegativeQuietNaN), &exponent)));
38 
39   EXPECT_EQ(BitPatterns::aSignallingNaN,
40             valueAsBits(__llvm_libc::frexpf(
41                 valueFromBits(BitPatterns::aSignallingNaN), &exponent)));
42   EXPECT_EQ(
43       BitPatterns::aNegativeSignallingNaN,
44       valueAsBits(__llvm_libc::frexpf(
45           valueFromBits(BitPatterns::aNegativeSignallingNaN), &exponent)));
46 
47   EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::frexpf(
48                                   valueFromBits(BitPatterns::inf), &exponent)));
49   EXPECT_EQ(BitPatterns::negInf,
50             valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::negInf),
51                                             &exponent)));
52 
53   EXPECT_EQ(BitPatterns::zero,
54             valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::zero),
55                                             &exponent)));
56   EXPECT_EQ(exponent, 0);
57   EXPECT_EQ(BitPatterns::negZero,
58             valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::negZero),
59                                             &exponent)));
60   EXPECT_EQ(exponent, 0);
61 }
62 
TEST(FrexpfTest,PowersOfTwo)63 TEST(FrexpfTest, PowersOfTwo) {
64   int exponent;
65 
66   EXPECT_EQ(valueAsBits(0.5f),
67             valueAsBits(__llvm_libc::frexpf(1.0f, &exponent)));
68   EXPECT_EQ(exponent, 1);
69   EXPECT_EQ(valueAsBits(-0.5f),
70             valueAsBits(__llvm_libc::frexpf(-1.0f, &exponent)));
71   EXPECT_EQ(exponent, 1);
72 
73   EXPECT_EQ(valueAsBits(0.5f),
74             valueAsBits(__llvm_libc::frexpf(2.0f, &exponent)));
75   EXPECT_EQ(exponent, 2);
76   EXPECT_EQ(valueAsBits(-0.5f),
77             valueAsBits(__llvm_libc::frexpf(-2.0f, &exponent)));
78   EXPECT_EQ(exponent, 2);
79 
80   EXPECT_EQ(valueAsBits(0.5f),
81             valueAsBits(__llvm_libc::frexpf(4.0f, &exponent)));
82   EXPECT_EQ(exponent, 3);
83   EXPECT_EQ(valueAsBits(-0.5f),
84             valueAsBits(__llvm_libc::frexpf(-4.0f, &exponent)));
85   EXPECT_EQ(exponent, 3);
86 
87   EXPECT_EQ(valueAsBits(0.5f),
88             valueAsBits(__llvm_libc::frexpf(8.0f, &exponent)));
89   EXPECT_EQ(exponent, 4);
90   EXPECT_EQ(valueAsBits(-0.5f),
91             valueAsBits(__llvm_libc::frexpf(-8.0f, &exponent)));
92   EXPECT_EQ(exponent, 4);
93 
94   EXPECT_EQ(valueAsBits(0.5f),
95             valueAsBits(__llvm_libc::frexpf(16.0f, &exponent)));
96   EXPECT_EQ(exponent, 5);
97   EXPECT_EQ(valueAsBits(-0.5f),
98             valueAsBits(__llvm_libc::frexpf(-16.0f, &exponent)));
99   EXPECT_EQ(exponent, 5);
100 
101   EXPECT_EQ(valueAsBits(0.5f),
102             valueAsBits(__llvm_libc::frexpf(32.0f, &exponent)));
103   EXPECT_EQ(exponent, 6);
104   EXPECT_EQ(valueAsBits(-0.5f),
105             valueAsBits(__llvm_libc::frexpf(-32.0f, &exponent)));
106   EXPECT_EQ(exponent, 6);
107 
108   EXPECT_EQ(valueAsBits(0.5f),
109             valueAsBits(__llvm_libc::frexpf(64.0f, &exponent)));
110   EXPECT_EQ(exponent, 7);
111   EXPECT_EQ(valueAsBits(-0.5f),
112             valueAsBits(__llvm_libc::frexpf(-64.0f, &exponent)));
113   EXPECT_EQ(exponent, 7);
114 }
115 
TEST(FrexpfTest,SomeIntegers)116 TEST(FrexpfTest, SomeIntegers) {
117   int exponent;
118 
119   EXPECT_EQ(valueAsBits(0.75f),
120             valueAsBits(__llvm_libc::frexpf(24.0f, &exponent)));
121   EXPECT_EQ(exponent, 5);
122   EXPECT_EQ(valueAsBits(-0.75f),
123             valueAsBits(__llvm_libc::frexpf(-24.0f, &exponent)));
124   EXPECT_EQ(exponent, 5);
125 
126   EXPECT_EQ(valueAsBits(0.625f),
127             valueAsBits(__llvm_libc::frexpf(40.0f, &exponent)));
128   EXPECT_EQ(exponent, 6);
129   EXPECT_EQ(valueAsBits(-0.625f),
130             valueAsBits(__llvm_libc::frexpf(-40.0f, &exponent)));
131   EXPECT_EQ(exponent, 6);
132 
133   EXPECT_EQ(valueAsBits(0.78125f),
134             valueAsBits(__llvm_libc::frexpf(800.0f, &exponent)));
135   EXPECT_EQ(exponent, 10);
136   EXPECT_EQ(valueAsBits(-0.78125f),
137             valueAsBits(__llvm_libc::frexpf(-800.0f, &exponent)));
138   EXPECT_EQ(exponent, 10);
139 }
140 
TEST(FrexpfTest,InFloatRange)141 TEST(FrexpfTest, InFloatRange) {
142   using UIntType = FPBits::UIntType;
143   constexpr UIntType count = 1000001;
144   constexpr UIntType step = UIntType(-1) / count;
145   for (UIntType i = 0, v = 0; i <= count; ++i, v += step) {
146     float x = FPBits(v);
147     if (isnan(x) || isinf(x) || x == 0.0)
148       continue;
149 
150     mpfr::BinaryOutput<float> result;
151     result.f = __llvm_libc::frexpf(x, &result.i);
152 
153     ASSERT_TRUE(__llvm_libc::fputil::abs(result.f) < 1.0);
154     ASSERT_TRUE(__llvm_libc::fputil::abs(result.f) >= 0.5);
155     ASSERT_MPFR_MATCH(mpfr::Operation::Frexp, x, result, 0.0);
156   }
157 }
158