Add another fma test.
[platform/upstream/glibc.git] / math / basic-test.c
1 /* Copyright (C) 1999-2013 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Andreas Jaeger <aj@suse.de>, 1999.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <math.h>
20 #include <float.h>
21 #include <stdio.h>
22
23 #include <math-tests.h>
24
25
26 static int errors = 0;
27
28
29 static void
30 check (const char *testname, int result)
31 {
32   if (!result) {
33     printf ("Failure: %s\n", testname);
34     errors++;
35   }
36 }
37
38 #define TEST_FUNC(NAME, FLOAT, SUFFIX, EPSILON, HUGEVAL)                      \
39 static void                                                                   \
40 NAME (void)                                                                   \
41 {                                                                             \
42   /* Variables are declared volatile to forbid some compiler                  \
43      optimizations.  */                                                       \
44   volatile FLOAT Inf_var, qNaN_var, zero_var, one_var;                        \
45   /* A sNaN is only guaranteed to be representable in variables with */       \
46   /* static (or thread-local) storage duration.  */                           \
47   static volatile FLOAT sNaN_var = __builtin_nans ## SUFFIX ("");             \
48   static volatile FLOAT minus_sNaN_var = -__builtin_nans ## SUFFIX ("");      \
49   FLOAT x1, x2;                                                               \
50                                                                               \
51   zero_var = 0.0;                                                             \
52   one_var = 1.0;                                                              \
53   qNaN_var = __builtin_nan ## SUFFIX ("");                                    \
54   Inf_var = one_var / zero_var;                                               \
55                                                                               \
56   (void) &zero_var;                                                           \
57   (void) &one_var;                                                            \
58   (void) &qNaN_var;                                                           \
59   (void) &sNaN_var;                                                           \
60   (void) &minus_sNaN_var;                                                     \
61   (void) &Inf_var;                                                            \
62                                                                               \
63                                                                               \
64   check (#FLOAT " isinf (inf) == 1", isinf (Inf_var) == 1);                   \
65   check (#FLOAT " isinf (-inf) == -1", isinf (-Inf_var) == -1);               \
66   check (#FLOAT " !isinf (1)", !(isinf (one_var)));                           \
67   check (#FLOAT " !isinf (qNaN)", !(isinf (qNaN_var)));                       \
68   if (SNAN_TESTS (FLOAT))                                                     \
69     check (#FLOAT " !isinf (sNaN)", !(isinf (sNaN_var)));                     \
70                                                                               \
71   check (#FLOAT " isnan (qNaN)", isnan (qNaN_var));                           \
72   if (SNAN_TESTS (FLOAT))                                                     \
73     check (#FLOAT " isnan (sNaN)", isnan (sNaN_var));                         \
74   check (#FLOAT " isnan (-qNaN)", isnan (-qNaN_var));                         \
75   if (SNAN_TESTS (FLOAT))                                                     \
76     check (#FLOAT " isnan (-sNaN)", isnan (minus_sNaN_var));                  \
77   check (#FLOAT " !isnan (1)", !(isnan (one_var)));                           \
78   check (#FLOAT " !isnan (inf)", !(isnan (Inf_var)));                         \
79                                                                               \
80   check (#FLOAT " !issignaling (qNaN)", !(issignaling (qNaN_var)));           \
81   if (SNAN_TESTS (FLOAT))                                                     \
82     check (#FLOAT " issignaling (sNaN)", issignaling (sNaN_var));             \
83   check (#FLOAT " !issignaling (-qNaN)", !(issignaling (-qNaN_var)));         \
84   if (SNAN_TESTS (FLOAT))                                                     \
85     check (#FLOAT " issignaling (-sNaN)", issignaling (minus_sNaN_var));      \
86   check (#FLOAT " !issignaling (1)", !(issignaling (one_var)));               \
87   check (#FLOAT " !issignaling (inf)", !(issignaling (Inf_var)));             \
88                                                                               \
89   check (#FLOAT " inf == inf", Inf_var == Inf_var);                           \
90   check (#FLOAT " -inf == -inf", -Inf_var == -Inf_var);                       \
91   check (#FLOAT " inf != -inf", Inf_var != -Inf_var);                         \
92   check (#FLOAT " qNaN != qNaN", qNaN_var != qNaN_var);                       \
93   if (SNAN_TESTS (FLOAT))                                                     \
94     check (#FLOAT " sNaN != sNaN", sNaN_var != sNaN_var);                     \
95   if (SNAN_TESTS (FLOAT))                                                     \
96     check (#FLOAT " qNaN != sNaN", qNaN_var != sNaN_var);                     \
97   if (SNAN_TESTS (FLOAT))                                                     \
98     check (#FLOAT " -sNaN != -sNaN", minus_sNaN_var != minus_sNaN_var);       \
99   if (SNAN_TESTS (FLOAT))                                                     \
100     check (#FLOAT " sNaN != -sNaN", sNaN_var != minus_sNaN_var);              \
101   if (SNAN_TESTS (FLOAT))                                                     \
102     check (#FLOAT " qNaN != -sNaN", qNaN_var != minus_sNaN_var);              \
103                                                                               \
104   /*                                                                          \
105      the same tests but this time with NAN from <bits/nan.h>                  \
106      NAN is a double const                                                    \
107    */                                                                         \
108   check (#FLOAT " isnan (NAN)", isnan (NAN));                                 \
109   check (#FLOAT " isnan (-NAN)", isnan (-NAN));                               \
110   check (#FLOAT " !isinf (NAN)", !(isinf (NAN)));                             \
111   check (#FLOAT " !isinf (-NAN)", !(isinf (-NAN)));                           \
112   check (#FLOAT " NAN != NAN", NAN != NAN);                                   \
113   check (#FLOAT " NAN != qNaN", NAN != qNaN_var);                             \
114   if (SNAN_TESTS (FLOAT))                                                     \
115     check (#FLOAT " NAN != sNaN", NAN != sNaN_var);                           \
116   if (SNAN_TESTS (FLOAT))                                                     \
117     check (#FLOAT " NAN != -sNaN", NAN != minus_sNaN_var);                    \
118                                                                               \
119   /*                                                                          \
120      And again with the value returned by the `nan' function.                 \
121    */                                                                         \
122   check (#FLOAT " isnan (nan (\"\"))", isnan (nan ## SUFFIX ("")));           \
123   check (#FLOAT " isnan (-nan (\"\"))", isnan (-nan ## SUFFIX ("")));         \
124   check (#FLOAT " !isinf (nan (\"\"))", !(isinf (nan ## SUFFIX (""))));       \
125   check (#FLOAT " !isinf (-nan (\"\"))", !(isinf (-nan ## SUFFIX (""))));     \
126   check (#FLOAT " nan (\"\") != nan (\"\")",                                  \
127          nan ## SUFFIX ("") != nan ## SUFFIX (""));                           \
128   check (#FLOAT " nan (\"\") != qNaN", nan ## SUFFIX ("") != qNaN_var);       \
129   if (SNAN_TESTS (FLOAT))                                                     \
130     check (#FLOAT " nan (\"\") != sNaN", nan ## SUFFIX ("") != sNaN_var);     \
131   if (SNAN_TESTS (FLOAT))                                                     \
132     check (#FLOAT " nan (\"\") != -sNaN",                                     \
133            nan ## SUFFIX ("") != minus_sNaN_var);                             \
134                                                                               \
135   /* test if EPSILON is ok */                                                 \
136   x1 = 1.0;                                                                   \
137   x2 = x1 + EPSILON;                                                          \
138   check (#FLOAT " 1 != 1+EPSILON", x1 != x2);                                 \
139                                                                               \
140   x1 = 1.0;                                                                   \
141   x2 = x1 - EPSILON;                                                          \
142   check (#FLOAT " 1 != 1-EPSILON", x1 != x2);                                 \
143                                                                               \
144   /* test if HUGE_VALx is ok */                                               \
145   x1 = HUGEVAL;                                                               \
146   check (#FLOAT " isinf (HUGE_VALx) == +1", isinf (x1) == +1);                \
147   x1 = - HUGEVAL;                                                             \
148   check (#FLOAT " isinf (-HUGE_VALx) == -1", isinf (x1) == -1);               \
149 }
150
151 #define TEST_TRUNC(NAME, FLOAT, DOUBLE, SUFFIX)                               \
152 void                                                                          \
153 NAME (void)                                                                   \
154 {                                                                             \
155   volatile DOUBLE Inf_var, qNaN_var, zero_var, one_var;                       \
156   /* A sNaN is only guaranteed to be representable in variables with */       \
157   /* static (or thread-local) storage duration.  */                           \
158   static volatile DOUBLE sNaN_var = __builtin_nans ## SUFFIX ("");            \
159   FLOAT x1, x2;                                                               \
160                                                                               \
161   zero_var = 0.0;                                                             \
162   one_var = 1.0;                                                              \
163   qNaN_var = __builtin_nan ## SUFFIX ("");                                    \
164   Inf_var = one_var / zero_var;                                               \
165                                                                               \
166   (void) &qNaN_var;                                                           \
167   (void) &sNaN_var;                                                           \
168   (void) &Inf_var;                                                            \
169                                                                               \
170   x1 = (FLOAT) qNaN_var;                                                      \
171   check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") qNaN, isnan", isnan (x1));     \
172   check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") qNaN, !issignaling",           \
173          !issignaling (x1));                                                  \
174   if (SNAN_TESTS (FLOAT))                                                     \
175     {                                                                         \
176       x1 = (FLOAT) sNaN_var;                                                  \
177       check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") sNaN, isnan", isnan (x1)); \
178       if (SNAN_TESTS_TYPE_CAST)                                               \
179         {                                                                     \
180           /* Upon type conversion, a sNaN is converted into a qNaN plus an */ \
181           /* INVALID exception (not checked here).  */                        \
182           check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") sNaN, !issignaling",   \
183                  !issignaling (x1));                                          \
184         }                                                                     \
185       }                                                                       \
186   x2 = (FLOAT) Inf_var;                                                       \
187   check (" "#FLOAT" x = ("#FLOAT") ("#DOUBLE") Inf", isinf (x2) != 0);        \
188 }
189
190 TEST_FUNC (float_test, float, f, FLT_EPSILON, HUGE_VALF)
191 TEST_FUNC (double_test, double, , DBL_EPSILON, HUGE_VAL)
192 TEST_TRUNC (truncdfsf_test, float, double, )
193 #ifndef NO_LONG_DOUBLE
194 TEST_FUNC (ldouble_test, long double, l, LDBL_EPSILON, HUGE_VALL)
195 TEST_TRUNC (trunctfsf_test, float, long double, l)
196 TEST_TRUNC (trunctfdf_test, double, long double, l)
197 #endif
198
199 int
200 do_test (void)
201 {
202   float_test ();
203   double_test ();
204   truncdfsf_test();
205
206 #ifndef NO_LONG_DOUBLE
207   ldouble_test ();
208   trunctfsf_test();
209   trunctfdf_test();
210 #endif
211
212   return errors != 0;
213 }
214
215 #define TEST_FUNCTION do_test ()
216 #include "../test-skeleton.c"