1 /* Test floating-point arithmetic operations.
2 Copyright (C) 1997-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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 <https://www.gnu.org/licenses/>. */
29 typedef double tocheck_t
;
39 #define R_ALL (R_NEAREST|R_ZERO|R_UP|R_DOWN)
40 static fenv_t rmodes
[4];
41 static const char * const rmnames
[4] =
42 { "nearest","zero","+Inf","-Inf" };
46 unsigned char c
[sizeof (tocheck_t
)];
49 /* Don't try reading these in a font that doesn't distinguish
52 P_Z
= 0x0, /* 00000...0 */
53 P_000O
= 0x1, /* 00011...1 */
54 P_001Z
= 0x2, /* 00100...0 */
55 P_00O
= 0x3, /* 00111...1 */
56 P_01Z
= 0x4, /* 01000...0 */
57 P_010O
= 0x5, /* 01011...1 */
58 P_011Z
= 0x6, /* 01100...0 */
59 P_0O
= 0x7, /* 01111...1 */
60 P_1Z
= 0x8, /* 10000...0 */
61 P_100O
= 0x9, /* 10011...1 */
62 P_101Z
= 0xa, /* 10100...0 */
63 P_10O
= 0xb, /* 10111...1 */
64 P_11Z
= 0xc, /* 11000...0 */
65 P_110O
= 0xd, /* 11011...1 */
66 P_111Z
= 0xe, /* 11100...0 */
67 P_O
= 0xf, /* 11111...1 */
68 P_Z1
= 0x11, /* 000...001 */
69 P_Z10
= 0x12, /* 000...010 */
70 P_Z11
= 0x13, /* 000...011 */
71 P_0O00
= 0x14, /* 011...100 */
72 P_0O01
= 0x15, /* 011...101 */
73 P_0O0
= 0x16, /* 011...110 */
74 P_1Z1
= 0x19, /* 100...001 */
75 P_1Z10
= 0x1a, /* 100...010 */
76 P_1Z11
= 0x1b, /* 100...011 */
77 P_O00
= 0x1c, /* 111...100 */
78 P_O01
= 0x1d, /* 111...101 */
79 P_O0
= 0x1e, /* 111...110 */
80 P_R
= 0x20, /* rrr...rrr */ /* ('r' means random. ) */
81 P_Ro
= 0x21, /* rrr...rrr, with odd parity. */
82 P_0R
= 0x22, /* 0rr...rrr */
83 P_1R
= 0x23, /* 1rr...rrr */
84 P_Rno
= 0x24, /* rrr...rrr, but not all ones. */
88 pattern_fill(pattern_t ptn
, unsigned char *start
, int bitoffset
, int count
)
90 #define bitset(count, value) \
91 start[(count)/8] = (start[(count)/8] & ~(1 << 7-(count)%8) \
92 | (value) << 7-(count)%8)
95 if (ptn
>= 0 && ptn
<= 0xf)
97 /* Patterns between 0 and 0xF have the following format:
98 The LSBit is used to fill the last n-3 bits of the pattern;
99 The next 3 bits are the first 3 bits of the pattern. */
100 for (i
= 0; i
< count
; i
++)
102 bitset((bitoffset
+i
), ptn
>> (3-i
) & 1);
104 bitset((bitoffset
+i
), ptn
>> 0 & 1);
106 else if (ptn
<= 0x1f)
108 /* Patterns between 0x10 and 0x1F have the following format:
109 The two LSBits are the last two bits of the pattern;
110 The 0x8 bit is the first bit of the pattern;
111 The 0x4 bit is used to fill the remainder. */
112 for (i
= 0; i
< count
; i
++)
114 bitset((bitoffset
+i
), ptn
>> 3 & 1);
115 else if (i
>= count
-2)
116 bitset((bitoffset
+i
), ptn
>> (count
-1-i
) & 1);
118 bitset((bitoffset
+i
), ptn
>> 2 & 1);
122 case P_0R
: case P_1R
:
124 bitset(bitoffset
, ptn
& 1);
128 for (; count
> 0; count
--, bitoffset
++)
129 bitset(bitoffset
, rand() & 1);
135 for (; count
> 1; count
--, bitoffset
++)
136 bitset(bitoffset
, op
^= (rand() & 1));
137 bitset(bitoffset
, op
);
144 for (; count
> 1; count
--, bitoffset
++)
148 bitset(bitoffset
, r
);
150 bitset(bitoffset
, rand() & (op
^ 1));
161 pattern(int negative
, pattern_t exp
, pattern_t mant
)
168 pattern_fill(negative
? P_O
: P_Z
, result
.c
, 0, 1);
169 pattern_fill(exp
, result
.c
, 1, ESIZE
);
170 pattern_fill(mant
, result
.c
, ESIZE
+1, MSIZE
);
172 printf("neg=%d exp=%02x mant=%02x: ", negative
, exp
, mant
);
173 for (i
= 0; i
< sizeof (tocheck_t
); i
++)
174 printf("%02x", result
.c
[i
]);
180 /* Return the closest different tocheck_t to 'x' in the direction of
181 'direction', or 'x' if there is no such value. Assumes 'x' is not
184 delta(tocheck_t x
, int direction
)
191 direction
= -direction
;
195 tx
.tc
= pattern(xx
.c
[0] >> 7, P_O
, P_Z
);
196 if (memcmp (tx
.c
, xx
.c
, sizeof (tocheck_t
)) == 0)
199 for (i
= sizeof (tocheck_t
)-1; i
> 0; i
--)
201 xx
.c
[i
] += direction
;
202 if (xx
.c
[i
] != (direction
> 0 ? 0 : 0xff))
205 if (direction
< 0 && (xx
.c
[0] & 0x7f) == 0)
206 return pattern(~(xx
.c
[0] >> 7) & 1, P_Z
, P_Z1
);
209 xx
.c
[0] += direction
;
214 static int nerrors
= 0;
216 #ifdef FE_ALL_INVALID
217 static const int all_exceptions
= FE_ALL_INVALID
| FE_ALL_EXCEPT
;
219 static const int all_exceptions
= FE_ALL_EXCEPT
;
223 check_result(int line
, const char *rm
, tocheck_t expected
, tocheck_t actual
)
225 if (memcmp (&expected
, &actual
, sizeof (tocheck_t
)) != 0)
227 unsigned char *ex
, *ac
;
230 printf("%s:%d:round %s:result failed\n"
231 " expected result 0x", __FILE__
, line
, rm
);
232 ex
= (unsigned char *)&expected
;
233 ac
= (unsigned char *)&actual
;
234 for (i
= 0; i
< sizeof (tocheck_t
); i
++)
235 printf("%02x", ex
[i
]);
237 for (i
= 0; i
< sizeof (tocheck_t
); i
++)
238 printf("%02x", ac
[i
]);
244 static const struct {
248 #define except_entry(ex) { ex, #ex } ,
250 except_entry(FE_INEXACT
)
252 # define FE_INEXACT 0
255 except_entry(FE_DIVBYZERO
)
257 # define FE_DIVBYZERO 0
260 except_entry(FE_UNDERFLOW
)
262 # define FE_UNDERFLOW 0
265 except_entry(FE_OVERFLOW
)
267 # define FE_OVERFLOW 0
270 except_entry(FE_INVALID
)
272 # define FE_INVALID 0
274 #ifdef FE_INVALID_SNAN
275 except_entry(FE_INVALID_SNAN
)
277 # define FE_INVALID_SNAN FE_INVALID
279 #ifdef FE_INVALID_ISI
280 except_entry(FE_INVALID_ISI
)
282 # define FE_INVALID_ISI FE_INVALID
284 #ifdef FE_INVALID_IDI
285 except_entry(FE_INVALID_IDI
)
287 # define FE_INVALID_IDI FE_INVALID
289 #ifdef FE_INVALID_ZDZ
290 except_entry(FE_INVALID_ZDZ
)
292 # define FE_INVALID_ZDZ FE_INVALID
294 #ifdef FE_INVALID_COMPARE
295 except_entry(FE_INVALID_COMPARE
)
297 # define FE_INVALID_COMPARE FE_INVALID
299 #ifdef FE_INVALID_SOFTWARE
300 except_entry(FE_INVALID_SOFTWARE
)
302 # define FE_INVALID_SOFTWARE FE_INVALID
304 #ifdef FE_INVALID_SQRT
305 except_entry(FE_INVALID_SQRT
)
307 # define FE_INVALID_SQRT FE_INVALID
309 #ifdef FE_INVALID_INTEGER_CONVERSION
310 except_entry(FE_INVALID_INTEGER_CONVERSION
)
312 # define FE_INVALID_INTEGER_CONVERSION FE_INVALID
316 static int excepts_missing
= 0;
319 check_excepts(int line
, const char *rm
, int expected
, int actual
)
321 if (expected
& excepts_missing
)
322 expected
= expected
& ~excepts_missing
| FE_INVALID_SNAN
;
323 if ((expected
& all_exceptions
) != actual
)
326 printf("%s:%d:round %s:exceptions failed\n"
327 " expected exceptions ", __FILE__
, line
,rm
);
328 for (i
= 0; i
< sizeof (excepts
) / sizeof (excepts
[0]); i
++)
329 if (expected
& excepts
[i
].except
)
330 printf("%s ",excepts
[i
].name
);
331 if ((expected
& all_exceptions
) == 0)
334 for (i
= 0; i
< sizeof (excepts
) / sizeof (excepts
[0]); i
++)
335 if (actual
& excepts
[i
].except
)
336 printf(" %s",excepts
[i
].name
);
337 if ((actual
& all_exceptions
) == 0)
345 B_ADD
, B_SUB
, B_MUL
, B_DIV
, B_NEG
, B_ABS
, B_SQRT
351 pattern_t a_exp
, a_mant
;
353 pattern_t b_exp
, b_mant
;
357 pattern_t x_exp
, x_mant
;
359 static const optest_t optests
[] = {
360 /* Additions of zero. */
361 {__LINE__
,B_ADD
, 0,P_Z
,P_Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_Z
,P_Z
},
362 {__LINE__
,B_ADD
, 1,P_Z
,P_Z
, 0,P_Z
,P_Z
, R_ALL
& ~R_DOWN
,0, 0,P_Z
,P_Z
},
363 {__LINE__
,B_ADD
, 1,P_Z
,P_Z
, 0,P_Z
,P_Z
, R_DOWN
,0, 1,P_Z
,P_Z
},
364 {__LINE__
,B_ADD
, 1,P_Z
,P_Z
, 1,P_Z
,P_Z
, R_ALL
,0, 1,P_Z
,P_Z
},
366 /* Additions with NaN. */
367 {__LINE__
,B_ADD
, 0,P_O
,P_101Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_101Z
},
368 {__LINE__
,B_ADD
, 0,P_O
,P_01Z
, 0,P_Z
,P_Z
, R_ALL
,
369 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_11Z
},
370 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_O
,P_0O
, R_ALL
,
371 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_O
},
372 {__LINE__
,B_ADD
, 0,P_Z
,P_Z
, 0,P_O
,P_11Z
, R_ALL
,0, 0,P_O
,P_11Z
},
373 {__LINE__
,B_ADD
, 0,P_O
,P_001Z
, 0,P_O
,P_001Z
, R_ALL
,
374 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_101Z
},
375 {__LINE__
,B_ADD
, 0,P_O
,P_1Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_1Z
},
376 {__LINE__
,B_ADD
, 0,P_0O
,P_Z
, 0,P_O
,P_10O
, R_ALL
,0, 0,P_O
,P_10O
},
378 /* Additions with infinity. */
379 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
380 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 1,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
381 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 0,P_Z
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
382 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 1,P_Z
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
383 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_O
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
384 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 1,P_O
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
385 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 1,P_O
,P_Z
, R_ALL
,
386 FE_INVALID
| FE_INVALID_ISI
, 0,P_O
,P_1Z
},
387 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 0,P_O
,P_Z
, R_ALL
,
388 FE_INVALID
| FE_INVALID_ISI
, 0,P_O
,P_1Z
},
389 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_0O
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
390 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 0,P_0O
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
391 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 1,P_0O
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
392 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 1,P_0O
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
394 /* Overflow (and zero). */
395 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 0,P_O0
,P_Z
, R_NEAREST
| R_UP
,
396 FE_INEXACT
| FE_OVERFLOW
, 0,P_O
,P_Z
},
397 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 0,P_O0
,P_Z
, R_ZERO
| R_DOWN
,
398 FE_INEXACT
| FE_OVERFLOW
, 0,P_O0
,P_O
},
399 {__LINE__
,B_ADD
, 1,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_NEAREST
| R_DOWN
,
400 FE_INEXACT
| FE_OVERFLOW
, 1,P_O
,P_Z
},
401 {__LINE__
,B_ADD
, 1,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_ZERO
| R_UP
,
402 FE_INEXACT
| FE_OVERFLOW
, 1,P_O0
,P_O
},
403 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_ALL
& ~R_DOWN
,
405 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_DOWN
,
409 {__LINE__
,B_NEG
, 0,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 1,P_Z
,P_Z
},
410 {__LINE__
,B_NEG
, 1,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
411 {__LINE__
,B_NEG
, 0,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_Z
},
412 {__LINE__
,B_NEG
, 1,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
413 {__LINE__
,B_NEG
, 0,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_1Z
},
414 {__LINE__
,B_NEG
, 1,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
415 {__LINE__
,B_NEG
, 0,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_01Z
},
416 {__LINE__
,B_NEG
, 1,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_01Z
},
417 {__LINE__
,B_NEG
, 0,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 1,P_1Z
,P_1Z1
},
418 {__LINE__
,B_NEG
, 1,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 0,P_1Z
,P_1Z1
},
419 {__LINE__
,B_NEG
, 0,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 1,P_Z
,P_Z1
},
420 {__LINE__
,B_NEG
, 1,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z1
},
422 /* Absolute value. */
423 {__LINE__
,B_ABS
, 0,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
424 {__LINE__
,B_ABS
, 1,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
425 {__LINE__
,B_ABS
, 0,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
426 {__LINE__
,B_ABS
, 1,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
427 {__LINE__
,B_ABS
, 0,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
428 {__LINE__
,B_ABS
, 1,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
429 {__LINE__
,B_ABS
, 0,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_01Z
},
430 {__LINE__
,B_ABS
, 1,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_01Z
},
431 {__LINE__
,B_ABS
, 0,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 0,P_1Z
,P_1Z1
},
432 {__LINE__
,B_ABS
, 1,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 0,P_1Z
,P_1Z1
},
433 {__LINE__
,B_ABS
, 0,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z1
},
434 {__LINE__
,B_ABS
, 1,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z1
},
437 {__LINE__
,B_SQRT
, 0,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
438 {__LINE__
,B_SQRT
, 1,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 1,P_Z
,P_Z
},
439 {__LINE__
,B_SQRT
, 0,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
440 {__LINE__
,B_SQRT
, 1,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_1Z
},
441 {__LINE__
,B_SQRT
, 0,P_O
,P_01Z
, 0,0,0, R_ALL
,
442 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_11Z
},
443 {__LINE__
,B_SQRT
, 1,P_O
,P_01Z
, 0,0,0, R_ALL
,
444 FE_INVALID
| FE_INVALID_SNAN
, 1,P_O
,P_11Z
},
446 {__LINE__
,B_SQRT
, 0,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
447 {__LINE__
,B_SQRT
, 0,P_0O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_0O
,P_Z
},
449 {__LINE__
,B_SQRT
, 1,P_O
,P_Z
, 0,0,0, R_ALL
,
450 FE_INVALID
| FE_INVALID_SQRT
, 0,P_O
,P_1Z
},
451 {__LINE__
,B_SQRT
, 1,P_1Z
,P_1Z1
, 0,0,0, R_ALL
,
452 FE_INVALID
| FE_INVALID_SQRT
, 0,P_O
,P_1Z
},
453 {__LINE__
,B_SQRT
, 1,P_Z
,P_Z1
, 0,0,0, R_ALL
,
454 FE_INVALID
| FE_INVALID_SQRT
, 0,P_O
,P_1Z
},
463 tocheck_t r
, a
, b
, x
;
466 for (i
= 0; i
< sizeof (optests
) / sizeof (optests
[0]); i
++)
468 a
= pattern(optests
[i
].a_sgn
, optests
[i
].a_exp
,
470 b
= pattern(optests
[i
].b_sgn
, optests
[i
].b_exp
,
472 x
= pattern(optests
[i
].x_sgn
, optests
[i
].x_exp
,
474 for (j
= 0; j
< 4; j
++)
475 if (optests
[i
].rmode
& 1<<j
)
478 switch (optests
[i
].op
)
480 case B_ADD
: r
= a
+ b
; break;
481 case B_SUB
: r
= a
- b
; break;
482 case B_MUL
: r
= a
* b
; break;
483 case B_DIV
: r
= a
/ b
; break;
484 case B_NEG
: r
= -a
; break;
485 case B_ABS
: r
= FUNC(fabs
)(a
); break;
486 case B_SQRT
: r
= FUNC(sqrt
)(a
); break;
488 raised
= fetestexcept(all_exceptions
);
489 check_result(optests
[i
].line
,rmnames
[j
],x
,r
);
490 check_excepts(optests
[i
].line
,rmnames
[j
],
491 optests
[i
].excepts
,raised
);
497 fail_xr(int line
, const char *rm
, tocheck_t x
, tocheck_t r
, tocheck_t xx
,
501 unsigned char *cx
, *cr
, *cxx
;
503 printf("%s:%d:round %s:fail\n with x=0x", __FILE__
, line
,rm
);
504 cx
= (unsigned char *)&x
;
505 cr
= (unsigned char *)&r
;
506 cxx
= (unsigned char *)&xx
;
507 for (i
= 0; i
< sizeof (tocheck_t
); i
++)
508 printf("%02x", cx
[i
]);
510 for (i
= 0; i
< sizeof (tocheck_t
); i
++)
511 printf("%02x", cr
[i
]);
513 for (i
= 0; i
< sizeof (tocheck_t
); i
++)
514 printf("%02x", cxx
[i
]);
515 printf(" inexact=%d\n", xflag
!= 0);
520 check_sqrt(tocheck_t a
)
523 tocheck_t r0
, r1
, r2
, x0
, x1
, x2
;
527 for (j
= 0; j
< 4; j
++)
533 excepts
= fetestexcept(all_exceptions
);
534 fesetenv(FE_DFL_ENV
);
535 raised
|= excepts
& ~FE_INEXACT
;
537 if (excepts
& FE_INEXACT
)
539 r0
= delta(r1
,-1); r2
= delta(r1
,1);
543 x0
= r0
* r0
- a
; x2
= r2
* r2
- a
;
544 ok
= fabs(x0
) >= fabs(x1
) && fabs(x1
) <= fabs(x2
);
546 case R_ZERO
: case R_DOWN
:
548 ok
= x1
<= 0 && x2
>= 0;
552 ok
= x1
>= 0 && x0
<= 0;
561 fail_xr(__LINE__
,rmnames
[j
],a
,r1
,x1
,excepts
&FE_INEXACT
);
563 check_excepts(__LINE__
,"all",0,raised
);
566 int main(int argc
, char **argv
)
570 _LIB_VERSION
= _IEEE_
;
572 /* Set up environments for rounding modes. */
573 fesetenv(FE_DFL_ENV
);
574 fesetround(FE_TONEAREST
);
576 fesetround(FE_TOWARDZERO
);
578 fesetround(FE_UPWARD
);
580 fesetround(FE_DOWNWARD
);
583 #if defined(FE_INVALID_SOFTWARE) || defined(FE_INVALID_SQRT)
584 /* There's this really stupid feature of the 601... */
585 fesetenv(FE_DFL_ENV
);
586 feraiseexcept(FE_INVALID_SOFTWARE
);
587 if (!fetestexcept(FE_INVALID_SOFTWARE
))
588 excepts_missing
|= FE_INVALID_SOFTWARE
;
589 fesetenv(FE_DFL_ENV
);
590 feraiseexcept(FE_INVALID_SQRT
);
591 if (!fetestexcept(FE_INVALID_SQRT
))
592 excepts_missing
|= FE_INVALID_SQRT
;
596 for (i
= 0; i
< 100000; i
++)
597 check_sqrt(pattern(0, P_Rno
, P_R
));
598 for (i
= 0; i
< 100; i
++)
599 check_sqrt(pattern(0, P_Z
, P_R
));
600 check_sqrt(pattern(0,P_Z
,P_Z1
));
602 printf("%d errors.\n", nerrors
);
603 return nerrors
== 0 ? 0 : 1;