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