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