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