1*7f8c6829SSascha Wildner /*-
2*7f8c6829SSascha Wildner * Copyright (c) 2008 David Schultz <das@FreeBSD.org>
3*7f8c6829SSascha Wildner * All rights reserved.
4*7f8c6829SSascha Wildner *
5*7f8c6829SSascha Wildner * Redistribution and use in source and binary forms, with or without
6*7f8c6829SSascha Wildner * modification, are permitted provided that the following conditions
7*7f8c6829SSascha Wildner * are met:
8*7f8c6829SSascha Wildner * 1. Redistributions of source code must retain the above copyright
9*7f8c6829SSascha Wildner * notice, this list of conditions and the following disclaimer.
10*7f8c6829SSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright
11*7f8c6829SSascha Wildner * notice, this list of conditions and the following disclaimer in the
12*7f8c6829SSascha Wildner * documentation and/or other materials provided with the distribution.
13*7f8c6829SSascha Wildner *
14*7f8c6829SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*7f8c6829SSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*7f8c6829SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*7f8c6829SSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*7f8c6829SSascha Wildner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*7f8c6829SSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*7f8c6829SSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*7f8c6829SSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*7f8c6829SSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*7f8c6829SSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*7f8c6829SSascha Wildner * SUCH DAMAGE.
25*7f8c6829SSascha Wildner *
26*7f8c6829SSascha Wildner * $FreeBSD: src/tools/regression/lib/msun/test-fma.c,v 1.6 2013/05/28 00:27:56 svnexp Exp $
27*7f8c6829SSascha Wildner */
28*7f8c6829SSascha Wildner
29*7f8c6829SSascha Wildner /*
30*7f8c6829SSascha Wildner * Tests for fma{,f,l}().
31*7f8c6829SSascha Wildner */
32*7f8c6829SSascha Wildner
33*7f8c6829SSascha Wildner #include <assert.h>
34*7f8c6829SSascha Wildner #include <fenv.h>
35*7f8c6829SSascha Wildner #include <float.h>
36*7f8c6829SSascha Wildner #include <math.h>
37*7f8c6829SSascha Wildner #include <stdio.h>
38*7f8c6829SSascha Wildner
39*7f8c6829SSascha Wildner #define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
40*7f8c6829SSascha Wildner FE_OVERFLOW | FE_UNDERFLOW)
41*7f8c6829SSascha Wildner
42*7f8c6829SSascha Wildner #pragma STDC FENV_ACCESS ON
43*7f8c6829SSascha Wildner
44*7f8c6829SSascha Wildner /*
45*7f8c6829SSascha Wildner * Test that a function returns the correct value and sets the
46*7f8c6829SSascha Wildner * exception flags correctly. The exceptmask specifies which
47*7f8c6829SSascha Wildner * exceptions we should check. We need to be lenient for several
48*7f8c6829SSascha Wildner * reasons, but mainly because on some architectures it's impossible
49*7f8c6829SSascha Wildner * to raise FE_OVERFLOW without raising FE_INEXACT.
50*7f8c6829SSascha Wildner *
51*7f8c6829SSascha Wildner * These are macros instead of functions so that assert provides more
52*7f8c6829SSascha Wildner * meaningful error messages.
53*7f8c6829SSascha Wildner */
54*7f8c6829SSascha Wildner #define test(func, x, y, z, result, exceptmask, excepts) do { \
55*7f8c6829SSascha Wildner assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
56*7f8c6829SSascha Wildner assert(fpequal((func)((x), (y), (z)), (result))); \
57*7f8c6829SSascha Wildner assert(((func), fetestexcept(exceptmask) == (excepts))); \
58*7f8c6829SSascha Wildner } while (0)
59*7f8c6829SSascha Wildner
60*7f8c6829SSascha Wildner #define testall(x, y, z, result, exceptmask, excepts) do { \
61*7f8c6829SSascha Wildner test(fma, (x), (y), (z), (double)(result), (exceptmask), (excepts)); \
62*7f8c6829SSascha Wildner test(fmaf, (x), (y), (z), (float)(result), (exceptmask), (excepts)); \
63*7f8c6829SSascha Wildner test(fmal, (x), (y), (z), (result), (exceptmask), (excepts)); \
64*7f8c6829SSascha Wildner } while (0)
65*7f8c6829SSascha Wildner
66*7f8c6829SSascha Wildner /* Test in all rounding modes. */
67*7f8c6829SSascha Wildner #define testrnd(func, x, y, z, rn, ru, rd, rz, exceptmask, excepts) do { \
68*7f8c6829SSascha Wildner fesetround(FE_TONEAREST); \
69*7f8c6829SSascha Wildner test((func), (x), (y), (z), (rn), (exceptmask), (excepts)); \
70*7f8c6829SSascha Wildner fesetround(FE_UPWARD); \
71*7f8c6829SSascha Wildner test((func), (x), (y), (z), (ru), (exceptmask), (excepts)); \
72*7f8c6829SSascha Wildner fesetround(FE_DOWNWARD); \
73*7f8c6829SSascha Wildner test((func), (x), (y), (z), (rd), (exceptmask), (excepts)); \
74*7f8c6829SSascha Wildner fesetround(FE_TOWARDZERO); \
75*7f8c6829SSascha Wildner test((func), (x), (y), (z), (rz), (exceptmask), (excepts)); \
76*7f8c6829SSascha Wildner } while (0)
77*7f8c6829SSascha Wildner
78*7f8c6829SSascha Wildner /*
79*7f8c6829SSascha Wildner * This is needed because clang constant-folds fma in ways that are incorrect
80*7f8c6829SSascha Wildner * in rounding modes other than FE_TONEAREST.
81*7f8c6829SSascha Wildner */
82*7f8c6829SSascha Wildner volatile double one = 1.0;
83*7f8c6829SSascha Wildner
84*7f8c6829SSascha Wildner /*
85*7f8c6829SSascha Wildner * Determine whether x and y are equal, with two special rules:
86*7f8c6829SSascha Wildner * +0.0 != -0.0
87*7f8c6829SSascha Wildner * NaN == NaN
88*7f8c6829SSascha Wildner */
89*7f8c6829SSascha Wildner int
fpequal(long double x,long double y)90*7f8c6829SSascha Wildner fpequal(long double x, long double y)
91*7f8c6829SSascha Wildner {
92*7f8c6829SSascha Wildner
93*7f8c6829SSascha Wildner return ((x == y && !signbit(x) == !signbit(y))
94*7f8c6829SSascha Wildner || (isnan(x) && isnan(y)));
95*7f8c6829SSascha Wildner }
96*7f8c6829SSascha Wildner
97*7f8c6829SSascha Wildner static void
test_zeroes(void)98*7f8c6829SSascha Wildner test_zeroes(void)
99*7f8c6829SSascha Wildner {
100*7f8c6829SSascha Wildner const int rd = (fegetround() == FE_DOWNWARD);
101*7f8c6829SSascha Wildner
102*7f8c6829SSascha Wildner testall(0.0, 0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0);
103*7f8c6829SSascha Wildner testall(1.0, 0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0);
104*7f8c6829SSascha Wildner testall(0.0, 1.0, 0.0, 0.0, ALL_STD_EXCEPT, 0);
105*7f8c6829SSascha Wildner testall(0.0, 0.0, 1.0, 1.0, ALL_STD_EXCEPT, 0);
106*7f8c6829SSascha Wildner
107*7f8c6829SSascha Wildner testall(-0.0, 0.0, 0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
108*7f8c6829SSascha Wildner testall(0.0, -0.0, 0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
109*7f8c6829SSascha Wildner testall(-0.0, -0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0);
110*7f8c6829SSascha Wildner testall(0.0, 0.0, -0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
111*7f8c6829SSascha Wildner testall(-0.0, -0.0, -0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
112*7f8c6829SSascha Wildner
113*7f8c6829SSascha Wildner testall(-0.0, 0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0);
114*7f8c6829SSascha Wildner testall(0.0, -0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0);
115*7f8c6829SSascha Wildner
116*7f8c6829SSascha Wildner testall(-one, one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
117*7f8c6829SSascha Wildner testall(one, -one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
118*7f8c6829SSascha Wildner testall(-one, -one, -one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
119*7f8c6829SSascha Wildner
120*7f8c6829SSascha Wildner switch (fegetround()) {
121*7f8c6829SSascha Wildner case FE_TONEAREST:
122*7f8c6829SSascha Wildner case FE_TOWARDZERO:
123*7f8c6829SSascha Wildner test(fmaf, -FLT_MIN, FLT_MIN, 0.0, -0.0,
124*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW);
125*7f8c6829SSascha Wildner test(fma, -DBL_MIN, DBL_MIN, 0.0, -0.0,
126*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW);
127*7f8c6829SSascha Wildner test(fmal, -LDBL_MIN, LDBL_MIN, 0.0, -0.0,
128*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW);
129*7f8c6829SSascha Wildner }
130*7f8c6829SSascha Wildner }
131*7f8c6829SSascha Wildner
132*7f8c6829SSascha Wildner static void
test_infinities(void)133*7f8c6829SSascha Wildner test_infinities(void)
134*7f8c6829SSascha Wildner {
135*7f8c6829SSascha Wildner
136*7f8c6829SSascha Wildner testall(INFINITY, 1.0, -1.0, INFINITY, ALL_STD_EXCEPT, 0);
137*7f8c6829SSascha Wildner testall(-1.0, INFINITY, 0.0, -INFINITY, ALL_STD_EXCEPT, 0);
138*7f8c6829SSascha Wildner testall(0.0, 0.0, INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
139*7f8c6829SSascha Wildner testall(1.0, 1.0, INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
140*7f8c6829SSascha Wildner testall(1.0, 1.0, -INFINITY, -INFINITY, ALL_STD_EXCEPT, 0);
141*7f8c6829SSascha Wildner
142*7f8c6829SSascha Wildner testall(INFINITY, -INFINITY, 1.0, -INFINITY, ALL_STD_EXCEPT, 0);
143*7f8c6829SSascha Wildner testall(INFINITY, INFINITY, 1.0, INFINITY, ALL_STD_EXCEPT, 0);
144*7f8c6829SSascha Wildner testall(-INFINITY, -INFINITY, INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
145*7f8c6829SSascha Wildner
146*7f8c6829SSascha Wildner testall(0.0, INFINITY, 1.0, NAN, ALL_STD_EXCEPT, FE_INVALID);
147*7f8c6829SSascha Wildner testall(INFINITY, 0.0, -0.0, NAN, ALL_STD_EXCEPT, FE_INVALID);
148*7f8c6829SSascha Wildner
149*7f8c6829SSascha Wildner /* The invalid exception is optional in this case. */
150*7f8c6829SSascha Wildner testall(INFINITY, 0.0, NAN, NAN, ALL_STD_EXCEPT & ~FE_INVALID, 0);
151*7f8c6829SSascha Wildner
152*7f8c6829SSascha Wildner testall(INFINITY, INFINITY, -INFINITY, NAN,
153*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INVALID);
154*7f8c6829SSascha Wildner testall(-INFINITY, INFINITY, INFINITY, NAN,
155*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INVALID);
156*7f8c6829SSascha Wildner testall(INFINITY, -1.0, INFINITY, NAN,
157*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INVALID);
158*7f8c6829SSascha Wildner
159*7f8c6829SSascha Wildner test(fmaf, FLT_MAX, FLT_MAX, -INFINITY, -INFINITY, ALL_STD_EXCEPT, 0);
160*7f8c6829SSascha Wildner test(fma, DBL_MAX, DBL_MAX, -INFINITY, -INFINITY, ALL_STD_EXCEPT, 0);
161*7f8c6829SSascha Wildner test(fmal, LDBL_MAX, LDBL_MAX, -INFINITY, -INFINITY,
162*7f8c6829SSascha Wildner ALL_STD_EXCEPT, 0);
163*7f8c6829SSascha Wildner test(fmaf, FLT_MAX, -FLT_MAX, INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
164*7f8c6829SSascha Wildner test(fma, DBL_MAX, -DBL_MAX, INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
165*7f8c6829SSascha Wildner test(fmal, LDBL_MAX, -LDBL_MAX, INFINITY, INFINITY,
166*7f8c6829SSascha Wildner ALL_STD_EXCEPT, 0);
167*7f8c6829SSascha Wildner }
168*7f8c6829SSascha Wildner
169*7f8c6829SSascha Wildner static void
test_nans(void)170*7f8c6829SSascha Wildner test_nans(void)
171*7f8c6829SSascha Wildner {
172*7f8c6829SSascha Wildner
173*7f8c6829SSascha Wildner testall(NAN, 0.0, 0.0, NAN, ALL_STD_EXCEPT, 0);
174*7f8c6829SSascha Wildner testall(1.0, NAN, 1.0, NAN, ALL_STD_EXCEPT, 0);
175*7f8c6829SSascha Wildner testall(1.0, -1.0, NAN, NAN, ALL_STD_EXCEPT, 0);
176*7f8c6829SSascha Wildner testall(0.0, 0.0, NAN, NAN, ALL_STD_EXCEPT, 0);
177*7f8c6829SSascha Wildner testall(NAN, NAN, NAN, NAN, ALL_STD_EXCEPT, 0);
178*7f8c6829SSascha Wildner
179*7f8c6829SSascha Wildner /* x*y should not raise an inexact/overflow/underflow if z is NaN. */
180*7f8c6829SSascha Wildner testall(M_PI, M_PI, NAN, NAN, ALL_STD_EXCEPT, 0);
181*7f8c6829SSascha Wildner test(fmaf, FLT_MIN, FLT_MIN, NAN, NAN, ALL_STD_EXCEPT, 0);
182*7f8c6829SSascha Wildner test(fma, DBL_MIN, DBL_MIN, NAN, NAN, ALL_STD_EXCEPT, 0);
183*7f8c6829SSascha Wildner test(fmal, LDBL_MIN, LDBL_MIN, NAN, NAN, ALL_STD_EXCEPT, 0);
184*7f8c6829SSascha Wildner test(fmaf, FLT_MAX, FLT_MAX, NAN, NAN, ALL_STD_EXCEPT, 0);
185*7f8c6829SSascha Wildner test(fma, DBL_MAX, DBL_MAX, NAN, NAN, ALL_STD_EXCEPT, 0);
186*7f8c6829SSascha Wildner test(fmal, LDBL_MAX, LDBL_MAX, NAN, NAN, ALL_STD_EXCEPT, 0);
187*7f8c6829SSascha Wildner }
188*7f8c6829SSascha Wildner
189*7f8c6829SSascha Wildner /*
190*7f8c6829SSascha Wildner * Tests for cases where z is very small compared to x*y.
191*7f8c6829SSascha Wildner */
192*7f8c6829SSascha Wildner static void
test_small_z(void)193*7f8c6829SSascha Wildner test_small_z(void)
194*7f8c6829SSascha Wildner {
195*7f8c6829SSascha Wildner
196*7f8c6829SSascha Wildner /* x*y positive, z positive */
197*7f8c6829SSascha Wildner if (fegetround() == FE_UPWARD) {
198*7f8c6829SSascha Wildner test(fmaf, one, one, 0x1.0p-100, 1.0 + FLT_EPSILON,
199*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
200*7f8c6829SSascha Wildner test(fma, one, one, 0x1.0p-200, 1.0 + DBL_EPSILON,
201*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
202*7f8c6829SSascha Wildner test(fmal, one, one, 0x1.0p-200, 1.0 + LDBL_EPSILON,
203*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
204*7f8c6829SSascha Wildner } else {
205*7f8c6829SSascha Wildner testall(0x1.0p100, one, 0x1.0p-100, 0x1.0p100,
206*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
207*7f8c6829SSascha Wildner }
208*7f8c6829SSascha Wildner
209*7f8c6829SSascha Wildner /* x*y negative, z negative */
210*7f8c6829SSascha Wildner if (fegetround() == FE_DOWNWARD) {
211*7f8c6829SSascha Wildner test(fmaf, -one, one, -0x1.0p-100, -(1.0 + FLT_EPSILON),
212*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
213*7f8c6829SSascha Wildner test(fma, -one, one, -0x1.0p-200, -(1.0 + DBL_EPSILON),
214*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
215*7f8c6829SSascha Wildner test(fmal, -one, one, -0x1.0p-200, -(1.0 + LDBL_EPSILON),
216*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
217*7f8c6829SSascha Wildner } else {
218*7f8c6829SSascha Wildner testall(0x1.0p100, -one, -0x1.0p-100, -0x1.0p100,
219*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
220*7f8c6829SSascha Wildner }
221*7f8c6829SSascha Wildner
222*7f8c6829SSascha Wildner /* x*y positive, z negative */
223*7f8c6829SSascha Wildner if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) {
224*7f8c6829SSascha Wildner test(fmaf, one, one, -0x1.0p-100, 1.0 - FLT_EPSILON / 2,
225*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
226*7f8c6829SSascha Wildner test(fma, one, one, -0x1.0p-200, 1.0 - DBL_EPSILON / 2,
227*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
228*7f8c6829SSascha Wildner test(fmal, one, one, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2,
229*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
230*7f8c6829SSascha Wildner } else {
231*7f8c6829SSascha Wildner testall(0x1.0p100, one, -0x1.0p-100, 0x1.0p100,
232*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
233*7f8c6829SSascha Wildner }
234*7f8c6829SSascha Wildner
235*7f8c6829SSascha Wildner /* x*y negative, z positive */
236*7f8c6829SSascha Wildner if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) {
237*7f8c6829SSascha Wildner test(fmaf, -one, one, 0x1.0p-100, -1.0 + FLT_EPSILON / 2,
238*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
239*7f8c6829SSascha Wildner test(fma, -one, one, 0x1.0p-200, -1.0 + DBL_EPSILON / 2,
240*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
241*7f8c6829SSascha Wildner test(fmal, -one, one, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2,
242*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
243*7f8c6829SSascha Wildner } else {
244*7f8c6829SSascha Wildner testall(-0x1.0p100, one, 0x1.0p-100, -0x1.0p100,
245*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
246*7f8c6829SSascha Wildner }
247*7f8c6829SSascha Wildner }
248*7f8c6829SSascha Wildner
249*7f8c6829SSascha Wildner /*
250*7f8c6829SSascha Wildner * Tests for cases where z is very large compared to x*y.
251*7f8c6829SSascha Wildner */
252*7f8c6829SSascha Wildner static void
test_big_z(void)253*7f8c6829SSascha Wildner test_big_z(void)
254*7f8c6829SSascha Wildner {
255*7f8c6829SSascha Wildner
256*7f8c6829SSascha Wildner /* z positive, x*y positive */
257*7f8c6829SSascha Wildner if (fegetround() == FE_UPWARD) {
258*7f8c6829SSascha Wildner test(fmaf, 0x1.0p-50, 0x1.0p-50, 1.0, 1.0 + FLT_EPSILON,
259*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
260*7f8c6829SSascha Wildner test(fma, 0x1.0p-100, 0x1.0p-100, 1.0, 1.0 + DBL_EPSILON,
261*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
262*7f8c6829SSascha Wildner test(fmal, 0x1.0p-100, 0x1.0p-100, 1.0, 1.0 + LDBL_EPSILON,
263*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
264*7f8c6829SSascha Wildner } else {
265*7f8c6829SSascha Wildner testall(-0x1.0p-50, -0x1.0p-50, 0x1.0p100, 0x1.0p100,
266*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
267*7f8c6829SSascha Wildner }
268*7f8c6829SSascha Wildner
269*7f8c6829SSascha Wildner /* z negative, x*y negative */
270*7f8c6829SSascha Wildner if (fegetround() == FE_DOWNWARD) {
271*7f8c6829SSascha Wildner test(fmaf, -0x1.0p-50, 0x1.0p-50, -1.0, -(1.0 + FLT_EPSILON),
272*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
273*7f8c6829SSascha Wildner test(fma, -0x1.0p-100, 0x1.0p-100, -1.0, -(1.0 + DBL_EPSILON),
274*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
275*7f8c6829SSascha Wildner test(fmal, -0x1.0p-100, 0x1.0p-100, -1.0, -(1.0 + LDBL_EPSILON),
276*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
277*7f8c6829SSascha Wildner } else {
278*7f8c6829SSascha Wildner testall(0x1.0p-50, -0x1.0p-50, -0x1.0p100, -0x1.0p100,
279*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
280*7f8c6829SSascha Wildner }
281*7f8c6829SSascha Wildner
282*7f8c6829SSascha Wildner /* z negative, x*y positive */
283*7f8c6829SSascha Wildner if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) {
284*7f8c6829SSascha Wildner test(fmaf, -0x1.0p-50, -0x1.0p-50, -1.0,
285*7f8c6829SSascha Wildner -1.0 + FLT_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT);
286*7f8c6829SSascha Wildner test(fma, -0x1.0p-100, -0x1.0p-100, -1.0,
287*7f8c6829SSascha Wildner -1.0 + DBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT);
288*7f8c6829SSascha Wildner test(fmal, -0x1.0p-100, -0x1.0p-100, -1.0,
289*7f8c6829SSascha Wildner -1.0 + LDBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT);
290*7f8c6829SSascha Wildner } else {
291*7f8c6829SSascha Wildner testall(0x1.0p-50, 0x1.0p-50, -0x1.0p100, -0x1.0p100,
292*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
293*7f8c6829SSascha Wildner }
294*7f8c6829SSascha Wildner
295*7f8c6829SSascha Wildner /* z positive, x*y negative */
296*7f8c6829SSascha Wildner if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) {
297*7f8c6829SSascha Wildner test(fmaf, 0x1.0p-50, -0x1.0p-50, 1.0, 1.0 - FLT_EPSILON / 2,
298*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
299*7f8c6829SSascha Wildner test(fma, 0x1.0p-100, -0x1.0p-100, 1.0, 1.0 - DBL_EPSILON / 2,
300*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
301*7f8c6829SSascha Wildner test(fmal, 0x1.0p-100, -0x1.0p-100, 1.0, 1.0 - LDBL_EPSILON / 2,
302*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
303*7f8c6829SSascha Wildner } else {
304*7f8c6829SSascha Wildner testall(-0x1.0p-50, 0x1.0p-50, 0x1.0p100, 0x1.0p100,
305*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
306*7f8c6829SSascha Wildner }
307*7f8c6829SSascha Wildner }
308*7f8c6829SSascha Wildner
309*7f8c6829SSascha Wildner static void
test_accuracy(void)310*7f8c6829SSascha Wildner test_accuracy(void)
311*7f8c6829SSascha Wildner {
312*7f8c6829SSascha Wildner
313*7f8c6829SSascha Wildner /* ilogb(x*y) - ilogb(z) = 20 */
314*7f8c6829SSascha Wildner testrnd(fmaf, -0x1.c139d8p-51, -0x1.600e7ap32, 0x1.26558cp-38,
315*7f8c6829SSascha Wildner 0x1.34e48ap-18, 0x1.34e48cp-18, 0x1.34e48ap-18, 0x1.34e48ap-18,
316*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
317*7f8c6829SSascha Wildner testrnd(fma, -0x1.c139d7b84f1a3p-51, -0x1.600e7a2a16484p32,
318*7f8c6829SSascha Wildner 0x1.26558cac31580p-38, 0x1.34e48a78aae97p-18,
319*7f8c6829SSascha Wildner 0x1.34e48a78aae97p-18, 0x1.34e48a78aae96p-18,
320*7f8c6829SSascha Wildner 0x1.34e48a78aae96p-18, ALL_STD_EXCEPT, FE_INEXACT);
321*7f8c6829SSascha Wildner #if LDBL_MANT_DIG == 113
322*7f8c6829SSascha Wildner testrnd(fmal, -0x1.c139d7b84f1a3079263afcc5bae3p-51L,
323*7f8c6829SSascha Wildner -0x1.600e7a2a164840edbe2e7d301a72p32L,
324*7f8c6829SSascha Wildner 0x1.26558cac315807eb07e448042101p-38L,
325*7f8c6829SSascha Wildner 0x1.34e48a78aae96c76ed36077dd387p-18L,
326*7f8c6829SSascha Wildner 0x1.34e48a78aae96c76ed36077dd388p-18L,
327*7f8c6829SSascha Wildner 0x1.34e48a78aae96c76ed36077dd387p-18L,
328*7f8c6829SSascha Wildner 0x1.34e48a78aae96c76ed36077dd387p-18L,
329*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
330*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 64
331*7f8c6829SSascha Wildner testrnd(fmal, -0x1.c139d7b84f1a307ap-51L, -0x1.600e7a2a164840eep32L,
332*7f8c6829SSascha Wildner 0x1.26558cac315807ecp-38L, 0x1.34e48a78aae96c78p-18L,
333*7f8c6829SSascha Wildner 0x1.34e48a78aae96c78p-18L, 0x1.34e48a78aae96c76p-18L,
334*7f8c6829SSascha Wildner 0x1.34e48a78aae96c76p-18L, ALL_STD_EXCEPT, FE_INEXACT);
335*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 53
336*7f8c6829SSascha Wildner testrnd(fmal, -0x1.c139d7b84f1a3p-51L, -0x1.600e7a2a16484p32L,
337*7f8c6829SSascha Wildner 0x1.26558cac31580p-38L, 0x1.34e48a78aae97p-18L,
338*7f8c6829SSascha Wildner 0x1.34e48a78aae97p-18L, 0x1.34e48a78aae96p-18L,
339*7f8c6829SSascha Wildner 0x1.34e48a78aae96p-18L, ALL_STD_EXCEPT, FE_INEXACT);
340*7f8c6829SSascha Wildner #endif
341*7f8c6829SSascha Wildner
342*7f8c6829SSascha Wildner /* ilogb(x*y) - ilogb(z) = -40 */
343*7f8c6829SSascha Wildner testrnd(fmaf, 0x1.98210ap53, 0x1.9556acp-24, 0x1.d87da4p70,
344*7f8c6829SSascha Wildner 0x1.d87da4p70, 0x1.d87da6p70, 0x1.d87da4p70, 0x1.d87da4p70,
345*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
346*7f8c6829SSascha Wildner testrnd(fma, 0x1.98210ac83fe2bp53, 0x1.9556ac1475f0fp-24,
347*7f8c6829SSascha Wildner 0x1.d87da3aafc60ep70, 0x1.d87da3aafda40p70,
348*7f8c6829SSascha Wildner 0x1.d87da3aafda40p70, 0x1.d87da3aafda3fp70,
349*7f8c6829SSascha Wildner 0x1.d87da3aafda3fp70, ALL_STD_EXCEPT, FE_INEXACT);
350*7f8c6829SSascha Wildner #if LDBL_MANT_DIG == 113
351*7f8c6829SSascha Wildner testrnd(fmal, 0x1.98210ac83fe2a8f65b6278b74cebp53L,
352*7f8c6829SSascha Wildner 0x1.9556ac1475f0f28968b61d0de65ap-24L,
353*7f8c6829SSascha Wildner 0x1.d87da3aafc60d830aa4c6d73b749p70L,
354*7f8c6829SSascha Wildner 0x1.d87da3aafda3f36a69eb86488224p70L,
355*7f8c6829SSascha Wildner 0x1.d87da3aafda3f36a69eb86488225p70L,
356*7f8c6829SSascha Wildner 0x1.d87da3aafda3f36a69eb86488224p70L,
357*7f8c6829SSascha Wildner 0x1.d87da3aafda3f36a69eb86488224p70L,
358*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
359*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 64
360*7f8c6829SSascha Wildner testrnd(fmal, 0x1.98210ac83fe2a8f6p53L, 0x1.9556ac1475f0f28ap-24L,
361*7f8c6829SSascha Wildner 0x1.d87da3aafc60d83p70L, 0x1.d87da3aafda3f36ap70L,
362*7f8c6829SSascha Wildner 0x1.d87da3aafda3f36ap70L, 0x1.d87da3aafda3f368p70L,
363*7f8c6829SSascha Wildner 0x1.d87da3aafda3f368p70L, ALL_STD_EXCEPT, FE_INEXACT);
364*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 53
365*7f8c6829SSascha Wildner testrnd(fmal, 0x1.98210ac83fe2bp53L, 0x1.9556ac1475f0fp-24L,
366*7f8c6829SSascha Wildner 0x1.d87da3aafc60ep70L, 0x1.d87da3aafda40p70L,
367*7f8c6829SSascha Wildner 0x1.d87da3aafda40p70L, 0x1.d87da3aafda3fp70L,
368*7f8c6829SSascha Wildner 0x1.d87da3aafda3fp70L, ALL_STD_EXCEPT, FE_INEXACT);
369*7f8c6829SSascha Wildner #endif
370*7f8c6829SSascha Wildner
371*7f8c6829SSascha Wildner /* ilogb(x*y) - ilogb(z) = 0 */
372*7f8c6829SSascha Wildner testrnd(fmaf, 0x1.31ad02p+100, 0x1.2fbf7ap-42, -0x1.c3e106p+58,
373*7f8c6829SSascha Wildner -0x1.64c27cp+56, -0x1.64c27ap+56, -0x1.64c27cp+56,
374*7f8c6829SSascha Wildner -0x1.64c27ap+56, ALL_STD_EXCEPT, FE_INEXACT);
375*7f8c6829SSascha Wildner testrnd(fma, 0x1.31ad012ede8aap+100, 0x1.2fbf79c839067p-42,
376*7f8c6829SSascha Wildner -0x1.c3e106929056ep+58, -0x1.64c282b970a5fp+56,
377*7f8c6829SSascha Wildner -0x1.64c282b970a5ep+56, -0x1.64c282b970a5fp+56,
378*7f8c6829SSascha Wildner -0x1.64c282b970a5ep+56, ALL_STD_EXCEPT, FE_INEXACT);
379*7f8c6829SSascha Wildner #if LDBL_MANT_DIG == 113
380*7f8c6829SSascha Wildner testrnd(fmal, 0x1.31ad012ede8aa282fa1c19376d16p+100L,
381*7f8c6829SSascha Wildner 0x1.2fbf79c839066f0f5c68f6d2e814p-42L,
382*7f8c6829SSascha Wildner -0x1.c3e106929056ec19de72bfe64215p+58L,
383*7f8c6829SSascha Wildner -0x1.64c282b970a612598fc025ca8cddp+56L,
384*7f8c6829SSascha Wildner -0x1.64c282b970a612598fc025ca8cddp+56L,
385*7f8c6829SSascha Wildner -0x1.64c282b970a612598fc025ca8cdep+56L,
386*7f8c6829SSascha Wildner -0x1.64c282b970a612598fc025ca8cddp+56L,
387*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
388*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 64
389*7f8c6829SSascha Wildner testrnd(fmal, 0x1.31ad012ede8aa4eap+100L, 0x1.2fbf79c839066aeap-42L,
390*7f8c6829SSascha Wildner -0x1.c3e106929056e61p+58L, -0x1.64c282b970a60298p+56L,
391*7f8c6829SSascha Wildner -0x1.64c282b970a60298p+56L, -0x1.64c282b970a6029ap+56L,
392*7f8c6829SSascha Wildner -0x1.64c282b970a60298p+56L, ALL_STD_EXCEPT, FE_INEXACT);
393*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 53
394*7f8c6829SSascha Wildner testrnd(fmal, 0x1.31ad012ede8aap+100L, 0x1.2fbf79c839067p-42L,
395*7f8c6829SSascha Wildner -0x1.c3e106929056ep+58L, -0x1.64c282b970a5fp+56L,
396*7f8c6829SSascha Wildner -0x1.64c282b970a5ep+56L, -0x1.64c282b970a5fp+56L,
397*7f8c6829SSascha Wildner -0x1.64c282b970a5ep+56L, ALL_STD_EXCEPT, FE_INEXACT);
398*7f8c6829SSascha Wildner #endif
399*7f8c6829SSascha Wildner
400*7f8c6829SSascha Wildner /* x*y (rounded) ~= -z */
401*7f8c6829SSascha Wildner /* XXX spurious inexact exceptions */
402*7f8c6829SSascha Wildner testrnd(fmaf, 0x1.bbffeep-30, -0x1.1d164cp-74, 0x1.ee7296p-104,
403*7f8c6829SSascha Wildner -0x1.c46ea8p-128, -0x1.c46ea8p-128, -0x1.c46ea8p-128,
404*7f8c6829SSascha Wildner -0x1.c46ea8p-128, ALL_STD_EXCEPT & ~FE_INEXACT, 0);
405*7f8c6829SSascha Wildner testrnd(fma, 0x1.bbffeea6fc7d6p-30, 0x1.1d164c6cbf078p-74,
406*7f8c6829SSascha Wildner -0x1.ee72993aff948p-104, -0x1.71f72ac7d9d8p-159,
407*7f8c6829SSascha Wildner -0x1.71f72ac7d9d8p-159, -0x1.71f72ac7d9d8p-159,
408*7f8c6829SSascha Wildner -0x1.71f72ac7d9d8p-159, ALL_STD_EXCEPT & ~FE_INEXACT, 0);
409*7f8c6829SSascha Wildner #if LDBL_MANT_DIG == 113
410*7f8c6829SSascha Wildner testrnd(fmal, 0x1.bbffeea6fc7d65927d147f437675p-30L,
411*7f8c6829SSascha Wildner 0x1.1d164c6cbf078b7a22607d1cd6a2p-74L,
412*7f8c6829SSascha Wildner -0x1.ee72993aff94973876031bec0944p-104L,
413*7f8c6829SSascha Wildner 0x1.64e086175b3a2adc36e607058814p-217L,
414*7f8c6829SSascha Wildner 0x1.64e086175b3a2adc36e607058814p-217L,
415*7f8c6829SSascha Wildner 0x1.64e086175b3a2adc36e607058814p-217L,
416*7f8c6829SSascha Wildner 0x1.64e086175b3a2adc36e607058814p-217L,
417*7f8c6829SSascha Wildner ALL_STD_EXCEPT & ~FE_INEXACT, 0);
418*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 64
419*7f8c6829SSascha Wildner testrnd(fmal, 0x1.bbffeea6fc7d6592p-30L, 0x1.1d164c6cbf078b7ap-74L,
420*7f8c6829SSascha Wildner -0x1.ee72993aff949736p-104L, 0x1.af190e7a1ee6ad94p-168L,
421*7f8c6829SSascha Wildner 0x1.af190e7a1ee6ad94p-168L, 0x1.af190e7a1ee6ad94p-168L,
422*7f8c6829SSascha Wildner 0x1.af190e7a1ee6ad94p-168L, ALL_STD_EXCEPT & ~FE_INEXACT, 0);
423*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 53
424*7f8c6829SSascha Wildner testrnd(fmal, 0x1.bbffeea6fc7d6p-30L, 0x1.1d164c6cbf078p-74L,
425*7f8c6829SSascha Wildner -0x1.ee72993aff948p-104L, -0x1.71f72ac7d9d8p-159L,
426*7f8c6829SSascha Wildner -0x1.71f72ac7d9d8p-159L, -0x1.71f72ac7d9d8p-159L,
427*7f8c6829SSascha Wildner -0x1.71f72ac7d9d8p-159L, ALL_STD_EXCEPT & ~FE_INEXACT, 0);
428*7f8c6829SSascha Wildner #endif
429*7f8c6829SSascha Wildner }
430*7f8c6829SSascha Wildner
431*7f8c6829SSascha Wildner static void
test_double_rounding(void)432*7f8c6829SSascha Wildner test_double_rounding(void)
433*7f8c6829SSascha Wildner {
434*7f8c6829SSascha Wildner
435*7f8c6829SSascha Wildner /*
436*7f8c6829SSascha Wildner * a = 0x1.8000000000001p0
437*7f8c6829SSascha Wildner * b = 0x1.8000000000001p0
438*7f8c6829SSascha Wildner * c = -0x0.0000000000000000000000000080...1p+1
439*7f8c6829SSascha Wildner * a * b = 0x1.2000000000001800000000000080p+1
440*7f8c6829SSascha Wildner *
441*7f8c6829SSascha Wildner * The correct behavior is to round DOWN to 0x1.2000000000001p+1 in
442*7f8c6829SSascha Wildner * round-to-nearest mode. An implementation that computes a*b+c in
443*7f8c6829SSascha Wildner * double+double precision, however, will get 0x1.20000000000018p+1,
444*7f8c6829SSascha Wildner * and then round UP.
445*7f8c6829SSascha Wildner */
446*7f8c6829SSascha Wildner fesetround(FE_TONEAREST);
447*7f8c6829SSascha Wildner test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0,
448*7f8c6829SSascha Wildner -0x1.0000000000001p-104, 0x1.2000000000001p+1,
449*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
450*7f8c6829SSascha Wildner fesetround(FE_DOWNWARD);
451*7f8c6829SSascha Wildner test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0,
452*7f8c6829SSascha Wildner -0x1.0000000000001p-104, 0x1.2000000000001p+1,
453*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
454*7f8c6829SSascha Wildner fesetround(FE_UPWARD);
455*7f8c6829SSascha Wildner test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0,
456*7f8c6829SSascha Wildner -0x1.0000000000001p-104, 0x1.2000000000002p+1,
457*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
458*7f8c6829SSascha Wildner
459*7f8c6829SSascha Wildner fesetround(FE_TONEAREST);
460*7f8c6829SSascha Wildner test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200002p+1,
461*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
462*7f8c6829SSascha Wildner fesetround(FE_DOWNWARD);
463*7f8c6829SSascha Wildner test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200002p+1,
464*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
465*7f8c6829SSascha Wildner fesetround(FE_UPWARD);
466*7f8c6829SSascha Wildner test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200004p+1,
467*7f8c6829SSascha Wildner ALL_STD_EXCEPT, FE_INEXACT);
468*7f8c6829SSascha Wildner
469*7f8c6829SSascha Wildner fesetround(FE_TONEAREST);
470*7f8c6829SSascha Wildner #if LDBL_MANT_DIG == 64
471*7f8c6829SSascha Wildner test(fmal, 0x1.4p+0L, 0x1.0000000000000004p+0L, 0x1p-128L,
472*7f8c6829SSascha Wildner 0x1.4000000000000006p+0L, ALL_STD_EXCEPT, FE_INEXACT);
473*7f8c6829SSascha Wildner #elif LDBL_MANT_DIG == 113
474*7f8c6829SSascha Wildner test(fmal, 0x1.8000000000000000000000000001p+0L,
475*7f8c6829SSascha Wildner 0x1.8000000000000000000000000001p+0L,
476*7f8c6829SSascha Wildner -0x1.0000000000000000000000000001p-224L,
477*7f8c6829SSascha Wildner 0x1.2000000000000000000000000001p+1L, ALL_STD_EXCEPT, FE_INEXACT);
478*7f8c6829SSascha Wildner #endif
479*7f8c6829SSascha Wildner
480*7f8c6829SSascha Wildner }
481*7f8c6829SSascha Wildner
482*7f8c6829SSascha Wildner int
main(int argc,char * argv[])483*7f8c6829SSascha Wildner main(int argc, char *argv[])
484*7f8c6829SSascha Wildner {
485*7f8c6829SSascha Wildner int rmodes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
486*7f8c6829SSascha Wildner int i;
487*7f8c6829SSascha Wildner
488*7f8c6829SSascha Wildner printf("1..19\n");
489*7f8c6829SSascha Wildner
490*7f8c6829SSascha Wildner for (i = 0; i < 4; i++) {
491*7f8c6829SSascha Wildner fesetround(rmodes[i]);
492*7f8c6829SSascha Wildner test_zeroes();
493*7f8c6829SSascha Wildner printf("ok %d - fma zeroes\n", i + 1);
494*7f8c6829SSascha Wildner }
495*7f8c6829SSascha Wildner
496*7f8c6829SSascha Wildner for (i = 0; i < 4; i++) {
497*7f8c6829SSascha Wildner fesetround(rmodes[i]);
498*7f8c6829SSascha Wildner test_infinities();
499*7f8c6829SSascha Wildner printf("ok %d - fma infinities\n", i + 5);
500*7f8c6829SSascha Wildner }
501*7f8c6829SSascha Wildner
502*7f8c6829SSascha Wildner fesetround(FE_TONEAREST);
503*7f8c6829SSascha Wildner test_nans();
504*7f8c6829SSascha Wildner printf("ok 9 - fma NaNs\n");
505*7f8c6829SSascha Wildner
506*7f8c6829SSascha Wildner for (i = 0; i < 4; i++) {
507*7f8c6829SSascha Wildner fesetround(rmodes[i]);
508*7f8c6829SSascha Wildner test_small_z();
509*7f8c6829SSascha Wildner printf("ok %d - fma small z\n", i + 10);
510*7f8c6829SSascha Wildner }
511*7f8c6829SSascha Wildner
512*7f8c6829SSascha Wildner for (i = 0; i < 4; i++) {
513*7f8c6829SSascha Wildner fesetround(rmodes[i]);
514*7f8c6829SSascha Wildner test_big_z();
515*7f8c6829SSascha Wildner printf("ok %d - fma big z\n", i + 14);
516*7f8c6829SSascha Wildner }
517*7f8c6829SSascha Wildner
518*7f8c6829SSascha Wildner fesetround(FE_TONEAREST);
519*7f8c6829SSascha Wildner test_accuracy();
520*7f8c6829SSascha Wildner printf("ok 18 - fma accuracy\n");
521*7f8c6829SSascha Wildner
522*7f8c6829SSascha Wildner test_double_rounding();
523*7f8c6829SSascha Wildner printf("ok 19 - fma double rounding\n");
524*7f8c6829SSascha Wildner
525*7f8c6829SSascha Wildner /*
526*7f8c6829SSascha Wildner * TODO:
527*7f8c6829SSascha Wildner * - Tests for subnormals
528*7f8c6829SSascha Wildner * - Cancellation tests (e.g., z = (double)x*y, but x*y is inexact)
529*7f8c6829SSascha Wildner */
530*7f8c6829SSascha Wildner
531*7f8c6829SSascha Wildner return (0);
532*7f8c6829SSascha Wildner }
533