1 //===-- Unittests for modfff
2 //-----------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "include/math.h"
11 #include "src/math/modff.h"
12 #include "utils/FPUtil/BasicOperations.h"
13 #include "utils/FPUtil/BitPatterns.h"
14 #include "utils/FPUtil/FloatOperations.h"
15 #include "utils/FPUtil/FloatProperties.h"
16 #include "utils/FPUtil/NearestIntegerOperations.h"
17 #include "utils/UnitTest/Test.h"
18 
19 using __llvm_libc::fputil::valueAsBits;
20 using __llvm_libc::fputil::valueFromBits;
21 
22 using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
23 using Properties = __llvm_libc::fputil::FloatProperties<float>;
24 
25 TEST(ModffTest, SpecialNumbers) {
26   float integral;
27 
28   EXPECT_EQ(BitPatterns::aQuietNaN,
29             valueAsBits(__llvm_libc::modff(
30                 valueFromBits(BitPatterns::aQuietNaN), &integral)));
31   EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
32             valueAsBits(__llvm_libc::modff(
33                 valueFromBits(BitPatterns::aNegativeQuietNaN), &integral)));
34 
35   EXPECT_EQ(BitPatterns::aSignallingNaN,
36             valueAsBits(__llvm_libc::modff(
37                 valueFromBits(BitPatterns::aSignallingNaN), &integral)));
38   EXPECT_EQ(
39       BitPatterns::aNegativeSignallingNaN,
40       valueAsBits(__llvm_libc::modff(
41           valueFromBits(BitPatterns::aNegativeSignallingNaN), &integral)));
42 
43   EXPECT_EQ(BitPatterns::zero,
44             valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::inf),
45                                            &integral)));
46   EXPECT_EQ(valueAsBits(integral), BitPatterns::inf);
47 
48   EXPECT_EQ(BitPatterns::negZero,
49             valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::negInf),
50                                            &integral)));
51   EXPECT_EQ(valueAsBits(integral), BitPatterns::negInf);
52 
53   EXPECT_EQ(BitPatterns::zero,
54             valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::zero),
55                                            &integral)));
56   EXPECT_EQ(valueAsBits(integral), BitPatterns::zero);
57 
58   EXPECT_EQ(BitPatterns::negZero,
59             valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::negZero),
60                                            &integral)));
61   EXPECT_EQ(valueAsBits(integral), BitPatterns::negZero);
62 }
63 
64 TEST(ModffTest, Integers) {
65   float integral;
66 
67   EXPECT_EQ(BitPatterns::zero,
68             valueAsBits(__llvm_libc::modff(1.0f, &integral)));
69   EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0f));
70 
71   EXPECT_EQ(BitPatterns::negZero,
72             valueAsBits(__llvm_libc::modff(-1.0f, &integral)));
73   EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0f));
74 
75   EXPECT_EQ(BitPatterns::zero,
76             valueAsBits(__llvm_libc::modff(10.0f, &integral)));
77   EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0f));
78 
79   EXPECT_EQ(BitPatterns::negZero,
80             valueAsBits(__llvm_libc::modff(-10.0f, &integral)));
81   EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0f));
82 
83   EXPECT_EQ(BitPatterns::zero,
84             valueAsBits(__llvm_libc::modff(12345.0f, &integral)));
85   EXPECT_EQ(valueAsBits(integral), valueAsBits(12345.0f));
86 
87   EXPECT_EQ(BitPatterns::negZero,
88             valueAsBits(__llvm_libc::modff(-12345.0f, &integral)));
89   EXPECT_EQ(valueAsBits(integral), valueAsBits(-12345.0f));
90 }
91 
92 TEST(ModfTest, Fractions) {
93   float integral;
94 
95   EXPECT_EQ(valueAsBits(0.5f),
96             valueAsBits(__llvm_libc::modff(1.5f, &integral)));
97   EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0f));
98 
99   EXPECT_EQ(valueAsBits(-0.5f),
100             valueAsBits(__llvm_libc::modff(-1.5f, &integral)));
101   EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0f));
102 
103   EXPECT_EQ(valueAsBits(0.75f),
104             valueAsBits(__llvm_libc::modff(10.75f, &integral)));
105   EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0f));
106 
107   EXPECT_EQ(valueAsBits(-0.75f),
108             valueAsBits(__llvm_libc::modff(-10.75f, &integral)));
109   EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0f));
110 
111   EXPECT_EQ(valueAsBits(0.125f),
112             valueAsBits(__llvm_libc::modff(100.125f, &integral)));
113   EXPECT_EQ(valueAsBits(integral), valueAsBits(100.0f));
114 
115   EXPECT_EQ(valueAsBits(-0.125f),
116             valueAsBits(__llvm_libc::modff(-100.125f, &integral)));
117   EXPECT_EQ(valueAsBits(integral), valueAsBits(-100.0f));
118 }
119 
120 TEST(ModffTest, InDoubleRange) {
121   using BitsType = Properties::BitsType;
122   constexpr BitsType count = 10000000;
123   constexpr BitsType step = UINT32_MAX / count;
124   for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
125     float x = valueFromBits(v);
126     if (isnan(x) || isinf(x) || x == 0.0f) {
127       // These conditions have been tested in other tests.
128       continue;
129     }
130 
131     float integral;
132     float frac = __llvm_libc::modff(x, &integral);
133     ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0f);
134     ASSERT_TRUE(__llvm_libc::fputil::trunc(x) == integral);
135     ASSERT_TRUE(integral + frac == x);
136   }
137 }
138