This source file includes following definitions.
- floor_reference
- equal
- correct_result_p
- check
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #include <math.h>
25
26 #include <float.h>
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <stdio.h>
30
31 #include "isnand-nolibm.h"
32 #include "macros.h"
33
34
35
36 #if defined _MSC_VER && !defined __clang__
37 # pragma fenv_access (off)
38 #endif
39
40
41
42
43 #define DOUBLE double
44 #define MANT_DIG DBL_MANT_DIG
45 #define L_(literal) literal
46
47
48 static const DOUBLE TWO_MANT_DIG =
49
50
51
52 (DOUBLE) (1U << ((MANT_DIG - 1) / 5))
53 * (DOUBLE) (1U << ((MANT_DIG - 1 + 1) / 5))
54 * (DOUBLE) (1U << ((MANT_DIG - 1 + 2) / 5))
55 * (DOUBLE) (1U << ((MANT_DIG - 1 + 3) / 5))
56 * (DOUBLE) (1U << ((MANT_DIG - 1 + 4) / 5));
57
58 DOUBLE
59 floor_reference (DOUBLE x)
60 {
61
62
63
64
65
66
67 volatile DOUBLE y = x;
68 volatile DOUBLE z = y;
69
70 if (z > L_(0.0))
71 {
72
73
74 if (z < L_(1.0))
75 z = L_(0.0);
76
77 else if (z < TWO_MANT_DIG)
78 {
79
80 z += TWO_MANT_DIG;
81 z -= TWO_MANT_DIG;
82
83 if (z > y)
84 z -= L_(1.0);
85 }
86 }
87 else if (z < L_(0.0))
88 {
89
90 if (z > -DBL_MIN)
91 return L_(-1.0);
92
93 if (z > - TWO_MANT_DIG)
94 {
95
96 z -= TWO_MANT_DIG;
97 z += TWO_MANT_DIG;
98
99 if (z > y)
100 z -= L_(1.0);
101 }
102 }
103 return z;
104 }
105
106
107
108 static int
109 equal (DOUBLE x, DOUBLE y)
110 {
111 return (isnand (x) ? isnand (y) : x == y);
112 }
113
114
115 static bool
116 correct_result_p (DOUBLE x, DOUBLE result)
117 {
118 return
119 (x < 0 && x >= -1 ? result == - L_(1.0) :
120 x - 1 < x ? result <= x && result >= x - 1 && x - result < 1 :
121 equal (result, x));
122 }
123
124
125 static int
126 check (double x)
127 {
128
129 double reference = floor_reference (x);
130 ASSERT (correct_result_p (x, reference));
131
132 {
133 double result = floor (x);
134 if (correct_result_p (x, result))
135 return 0;
136 else
137 {
138 #if GNULIB_TEST_FPRINTF_POSIX
139 fprintf (stderr, "floor %g(%a) = %g(%a) or %g(%a)?\n",
140 x, x, reference, reference, result, result);
141 #endif
142 return 1;
143 }
144 }
145 }
146
147 #define NUM_HIGHBITS 15
148 #define NUM_LOWBITS 4
149
150 int
151 main ()
152 {
153 #ifdef UINT64_MAX
154 unsigned int highbits;
155 unsigned int lowbits;
156 int error = 0;
157 for (highbits = 0; highbits < (1 << NUM_HIGHBITS); highbits++)
158 for (lowbits = 0; lowbits < (1 << NUM_LOWBITS); lowbits++)
159 {
160
161
162 union { double f; uint64_t i; } janus;
163 janus.i = ((uint64_t) highbits << (64 - NUM_HIGHBITS))
164 | ((uint64_t) ((int64_t) ((uint64_t) lowbits << (64 - NUM_LOWBITS))
165 >> (64 - NUM_LOWBITS - NUM_HIGHBITS))
166 >> NUM_HIGHBITS);
167 error |= check (janus.f);
168 }
169 return (error ? 1 : 0);
170 #else
171 fprintf (stderr, "Skipping test: no 64-bit integer type available\n");
172 return 77;
173 #endif
174 }