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