This source file includes following definitions.
- floorf_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 "isnanf-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 float
44 #define MANT_DIG FLT_MANT_DIG
45 #define L_(literal) literal##f
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 floorf_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 > -FLT_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 (isnanf (x) ? isnanf (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 (float x)
127 {
128
129 float reference = floorf_reference (x);
130 ASSERT (correct_result_p (x, reference));
131
132 {
133 float result = floorf (x);
134 if (correct_result_p (x, result))
135 return 0;
136 else
137 {
138 #if GNULIB_TEST_FPRINTF_POSIX
139 fprintf (stderr, "floorf %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 12
148 #define NUM_LOWBITS 4
149
150 int
151 main ()
152 {
153 unsigned int highbits;
154 unsigned int lowbits;
155 int error = 0;
156 for (highbits = 0; highbits < (1 << NUM_HIGHBITS); highbits++)
157 for (lowbits = 0; lowbits < (1 << NUM_LOWBITS); lowbits++)
158 {
159
160
161 union { float f; uint32_t i; } janus;
162 janus.i = ((uint32_t) highbits << (32 - NUM_HIGHBITS))
163 | ((uint32_t) ((int32_t) ((uint32_t) lowbits << (32 - NUM_LOWBITS))
164 >> (32 - NUM_LOWBITS - NUM_HIGHBITS))
165 >> NUM_HIGHBITS);
166 error |= check (janus.f);
167 }
168 return (error ? 1 : 0);
169 }