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