1 /* Test floating-point arithmetic operations.
2 Copyright (C) 1997, 1998 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 typedef double tocheck_t
;
40 #define R_ALL (R_NEAREST|R_ZERO|R_UP|R_DOWN)
41 static fenv_t rmodes
[4];
42 static const char * const rmnames
[4] =
43 { "nearest","zero","+Inf","-Inf" };
47 unsigned char c
[sizeof(tocheck_t
)];
50 /* Don't try reading these in a font that doesn't distinguish
53 P_Z
= 0x0, /* 00000...0 */
54 P_000O
= 0x1, /* 00011...1 */
55 P_001Z
= 0x2, /* 00100...0 */
56 P_00O
= 0x3, /* 00111...1 */
57 P_01Z
= 0x4, /* 01000...0 */
58 P_010O
= 0x5, /* 01011...1 */
59 P_011Z
= 0x6, /* 01100...0 */
60 P_0O
= 0x7, /* 01111...1 */
61 P_1Z
= 0x8, /* 10000...0 */
62 P_100O
= 0x9, /* 10011...1 */
63 P_101Z
= 0xa, /* 10100...0 */
64 P_10O
= 0xb, /* 10111...1 */
65 P_11Z
= 0xc, /* 11000...0 */
66 P_110O
= 0xd, /* 11011...1 */
67 P_111Z
= 0xe, /* 11100...0 */
68 P_O
= 0xf, /* 11111...1 */
69 P_Z1
= 0x11, /* 000...001 */
70 P_Z10
= 0x12, /* 000...010 */
71 P_Z11
= 0x13, /* 000...011 */
72 P_0O00
= 0x14, /* 011...100 */
73 P_0O01
= 0x15, /* 011...101 */
74 P_0O0
= 0x16, /* 011...110 */
75 P_1Z1
= 0x19, /* 100...001 */
76 P_1Z10
= 0x1a, /* 100...010 */
77 P_1Z11
= 0x1b, /* 100...011 */
78 P_O00
= 0x1c, /* 111...100 */
79 P_O01
= 0x1d, /* 111...101 */
80 P_O0
= 0x1e, /* 111...110 */
81 P_R
= 0x20, /* rrr...rrr */ /* ('r' means random. ) */
82 P_Ro
= 0x21, /* rrr...rrr, with odd parity. */
83 P_0R
= 0x22, /* 0rr...rrr */
84 P_1R
= 0x23, /* 1rr...rrr */
85 P_Rno
= 0x24, /* rrr...rrr, but not all ones. */
89 pattern_fill(pattern_t ptn
, unsigned char *start
, int bitoffset
, int count
)
91 #define bitset(count, value) \
92 start[(count)/8] = (start[(count)/8] & ~(1 << 7-(count)%8) \
93 | (value) << 7-(count)%8)
96 if (ptn
>= 0 && ptn
<= 0xf)
98 /* Patterns between 0 and 0xF have the following format:
99 The LSBit is used to fill the last n-3 bits of the pattern;
100 The next 3 bits are the first 3 bits of the pattern. */
101 for (i
= 0; i
< count
; i
++)
103 bitset((bitoffset
+i
), ptn
>> (3-i
) & 1);
105 bitset((bitoffset
+i
), ptn
>> 0 & 1);
107 else if (ptn
<= 0x1f)
109 /* Patterns between 0x10 and 0x1F have the following format:
110 The two LSBits are the last two bits of the pattern;
111 The 0x8 bit is the first bit of the pattern;
112 The 0x4 bit is used to fill the remainder. */
113 for (i
= 0; i
< count
; i
++)
115 bitset((bitoffset
+i
), ptn
>> 3 & 1);
116 else if (i
>= count
-2)
117 bitset((bitoffset
+i
), ptn
>> (count
-1-i
) & 1);
119 bitset((bitoffset
+i
), ptn
>> 2 & 1);
123 case P_0R
: case P_1R
:
125 bitset(bitoffset
, ptn
& 1);
129 for (; count
> 0; count
--, bitoffset
++)
130 bitset(bitoffset
, rand() & 1);
136 for (; count
> 1; count
--, bitoffset
++)
137 bitset(bitoffset
, op
^= (rand() & 1));
138 bitset(bitoffset
, op
);
145 for (; count
> 1; count
--, bitoffset
++)
149 bitset(bitoffset
, r
);
151 bitset(bitoffset
, rand() & (op
^ 1));
162 pattern(int negative
, pattern_t exp
, pattern_t mant
)
169 pattern_fill(negative
? P_O
: P_Z
, result
.c
, 0, 1);
170 pattern_fill(exp
, result
.c
, 1, ESIZE
);
171 pattern_fill(mant
, result
.c
, ESIZE
+1, MSIZE
);
173 printf("neg=%d exp=%02x mant=%02x: ", negative
, exp
, mant
);
174 for (i
= 0; i
< sizeof(tocheck_t
); i
++)
175 printf("%02x", result
.c
[i
]);
181 /* Return the closest different tocheck_t to 'x' in the direction of
182 'direction', or 'x' if there is no such value. Assumes 'x' is not
185 delta(tocheck_t x
, int direction
)
192 direction
= -direction
;
196 tx
.tc
= pattern(xx
.c
[0] >> 7, P_O
, P_Z
);
197 if (memcmp(tx
.c
, xx
.c
, sizeof(tocheck_t
)) == 0)
200 for (i
= sizeof(tocheck_t
)-1; i
> 0; i
--)
202 xx
.c
[i
] += direction
;
203 if (xx
.c
[i
] != (direction
> 0 ? 0 : 0xff))
206 if (direction
< 0 && (xx
.c
[0] & 0x7f) == 0)
207 return pattern(~(xx
.c
[0] >> 7) & 1, P_Z
, P_Z1
);
210 xx
.c
[0] += direction
;
215 static int nerrors
= 0;
217 #ifdef FE_ALL_INVALID
218 static const int all_exceptions
= FE_ALL_INVALID
| FE_ALL_EXCEPT
;
220 static const int all_exceptions
= FE_ALL_EXCEPT
;
224 check_result(int line
, const char *rm
, tocheck_t expected
, tocheck_t actual
)
226 if (memcmp(&expected
, &actual
, sizeof(tocheck_t
)) != 0)
228 unsigned char *ex
, *ac
;
231 printf("%s:%d:round %s:result failed\n"
232 " expected result 0x", __FILE__
, line
, rm
);
233 ex
= (unsigned char *)&expected
;
234 ac
= (unsigned char *)&actual
;
235 for (i
= 0; i
< sizeof(tocheck_t
); i
++)
236 printf("%02x", ex
[i
]);
238 for (i
= 0; i
< sizeof(tocheck_t
); i
++)
239 printf("%02x", ac
[i
]);
245 static const struct {
249 #define except_entry(ex) { ex, #ex } ,
251 except_entry(FE_INEXACT
)
253 # define FE_INEXACT 0
256 except_entry(FE_DIVBYZERO
)
258 # define FE_DIVBYZERO 0
261 except_entry(FE_UNDERFLOW
)
263 # define FE_UNDERFLOW 0
266 except_entry(FE_OVERFLOW
)
268 # define FE_OVERFLOW 0
271 except_entry(FE_INVALID
)
273 # define FE_INVALID 0
275 #ifdef FE_INVALID_SNAN
276 except_entry(FE_INVALID_SNAN
)
278 # define FE_INVALID_SNAN FE_INVALID
280 #ifdef FE_INVALID_ISI
281 except_entry(FE_INVALID_ISI
)
283 # define FE_INVALID_ISI FE_INVALID
285 #ifdef FE_INVALID_IDI
286 except_entry(FE_INVALID_IDI
)
288 # define FE_INVALID_IDI FE_INVALID
290 #ifdef FE_INVALID_ZDZ
291 except_entry(FE_INVALID_ZDZ
)
293 # define FE_INVALID_ZDZ FE_INVALID
295 #ifdef FE_INVALID_COMPARE
296 except_entry(FE_INVALID_COMPARE
)
298 # define FE_INVALID_COMPARE FE_INVALID
300 #ifdef FE_INVALID_SOFTWARE
301 except_entry(FE_INVALID_SOFTWARE
)
303 # define FE_INVALID_SOFTWARE FE_INVALID
305 #ifdef FE_INVALID_SQRT
306 except_entry(FE_INVALID_SQRT
)
308 # define FE_INVALID_SQRT FE_INVALID
310 #ifdef FE_INVALID_INTEGER_CONVERSION
311 except_entry(FE_INVALID_INTEGER_CONVERSION
)
313 # define FE_INVALID_INTEGER_CONVERSION FE_INVALID
317 static int excepts_missing
= 0;
320 check_excepts(int line
, const char *rm
, int expected
, int actual
)
322 if (expected
& excepts_missing
)
323 expected
= expected
& ~excepts_missing
| FE_INVALID_SNAN
;
324 if ((expected
& all_exceptions
) != actual
)
327 printf("%s:%d:round %s:exceptions failed\n"
328 " expected exceptions ", __FILE__
, line
,rm
);
329 for (i
= 0; i
< sizeof(excepts
)/sizeof(excepts
[0]); i
++)
330 if (expected
& excepts
[i
].except
)
331 printf("%s ",excepts
[i
].name
);
332 if ((expected
& all_exceptions
) == 0)
335 for (i
= 0; i
< sizeof(excepts
)/sizeof(excepts
[0]); i
++)
336 if (actual
& excepts
[i
].except
)
337 printf(" %s",excepts
[i
].name
);
338 if ((actual
& all_exceptions
) == 0)
346 B_ADD
, B_SUB
, B_MUL
, B_DIV
, B_NEG
, B_ABS
, B_SQRT
352 pattern_t a_exp
, a_mant
;
354 pattern_t b_exp
, b_mant
;
358 pattern_t x_exp
, x_mant
;
360 static const optest_t optests
[] = {
361 /* Additions of zero. */
362 {__LINE__
,B_ADD
, 0,P_Z
,P_Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_Z
,P_Z
},
363 {__LINE__
,B_ADD
, 1,P_Z
,P_Z
, 0,P_Z
,P_Z
, R_ALL
& ~R_DOWN
,0, 0,P_Z
,P_Z
},
364 {__LINE__
,B_ADD
, 1,P_Z
,P_Z
, 0,P_Z
,P_Z
, R_DOWN
,0, 1,P_Z
,P_Z
},
365 {__LINE__
,B_ADD
, 1,P_Z
,P_Z
, 1,P_Z
,P_Z
, R_ALL
,0, 1,P_Z
,P_Z
},
367 /* Additions with NaN. */
368 {__LINE__
,B_ADD
, 0,P_O
,P_101Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_101Z
},
369 {__LINE__
,B_ADD
, 0,P_O
,P_01Z
, 0,P_Z
,P_Z
, R_ALL
,
370 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_11Z
},
371 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_O
,P_0O
, R_ALL
,
372 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_O
},
373 {__LINE__
,B_ADD
, 0,P_Z
,P_Z
, 0,P_O
,P_11Z
, R_ALL
,0, 0,P_O
,P_11Z
},
374 {__LINE__
,B_ADD
, 0,P_O
,P_001Z
, 0,P_O
,P_001Z
, R_ALL
,
375 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_101Z
},
376 {__LINE__
,B_ADD
, 0,P_O
,P_1Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_1Z
},
377 {__LINE__
,B_ADD
, 0,P_0O
,P_Z
, 0,P_O
,P_10O
, R_ALL
,0, 0,P_O
,P_10O
},
379 /* Additions with infinity. */
380 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
381 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 1,P_Z
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
382 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 0,P_Z
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
383 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 1,P_Z
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
384 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_O
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
385 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 1,P_O
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
386 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 1,P_O
,P_Z
, R_ALL
,
387 FE_INVALID
| FE_INVALID_ISI
, 0,P_O
,P_1Z
},
388 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 0,P_O
,P_Z
, R_ALL
,
389 FE_INVALID
| FE_INVALID_ISI
, 0,P_O
,P_1Z
},
390 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 0,P_0O
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
391 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 0,P_0O
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
392 {__LINE__
,B_ADD
, 0,P_O
,P_Z
, 1,P_0O
,P_Z
, R_ALL
,0, 0,P_O
,P_Z
},
393 {__LINE__
,B_ADD
, 1,P_O
,P_Z
, 1,P_0O
,P_Z
, R_ALL
,0, 1,P_O
,P_Z
},
395 /* Overflow (and zero). */
396 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 0,P_O0
,P_Z
, R_NEAREST
| R_UP
,
397 FE_INEXACT
| FE_OVERFLOW
, 0,P_O
,P_Z
},
398 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 0,P_O0
,P_Z
, R_ZERO
| R_DOWN
,
399 FE_INEXACT
| FE_OVERFLOW
, 0,P_O0
,P_O
},
400 {__LINE__
,B_ADD
, 1,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_NEAREST
| R_DOWN
,
401 FE_INEXACT
| FE_OVERFLOW
, 1,P_O
,P_Z
},
402 {__LINE__
,B_ADD
, 1,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_ZERO
| R_UP
,
403 FE_INEXACT
| FE_OVERFLOW
, 1,P_O0
,P_O
},
404 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_ALL
& ~R_DOWN
,
406 {__LINE__
,B_ADD
, 0,P_O0
,P_Z
, 1,P_O0
,P_Z
, R_DOWN
,
410 {__LINE__
,B_NEG
, 0,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 1,P_Z
,P_Z
},
411 {__LINE__
,B_NEG
, 1,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
412 {__LINE__
,B_NEG
, 0,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_Z
},
413 {__LINE__
,B_NEG
, 1,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
414 {__LINE__
,B_NEG
, 0,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_1Z
},
415 {__LINE__
,B_NEG
, 1,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
416 {__LINE__
,B_NEG
, 0,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_01Z
},
417 {__LINE__
,B_NEG
, 1,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_01Z
},
418 {__LINE__
,B_NEG
, 0,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 1,P_1Z
,P_1Z1
},
419 {__LINE__
,B_NEG
, 1,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 0,P_1Z
,P_1Z1
},
420 {__LINE__
,B_NEG
, 0,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 1,P_Z
,P_Z1
},
421 {__LINE__
,B_NEG
, 1,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z1
},
423 /* Absolute value. */
424 {__LINE__
,B_ABS
, 0,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
425 {__LINE__
,B_ABS
, 1,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
426 {__LINE__
,B_ABS
, 0,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
427 {__LINE__
,B_ABS
, 1,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
428 {__LINE__
,B_ABS
, 0,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
429 {__LINE__
,B_ABS
, 1,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
430 {__LINE__
,B_ABS
, 0,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_01Z
},
431 {__LINE__
,B_ABS
, 1,P_O
,P_01Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_01Z
},
432 {__LINE__
,B_ABS
, 0,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 0,P_1Z
,P_1Z1
},
433 {__LINE__
,B_ABS
, 1,P_1Z
,P_1Z1
, 0,0,0, R_ALL
, 0, 0,P_1Z
,P_1Z1
},
434 {__LINE__
,B_ABS
, 0,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z1
},
435 {__LINE__
,B_ABS
, 1,P_Z
,P_Z1
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z1
},
438 {__LINE__
,B_SQRT
, 0,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_Z
,P_Z
},
439 {__LINE__
,B_SQRT
, 1,P_Z
,P_Z
, 0,0,0, R_ALL
, 0, 1,P_Z
,P_Z
},
440 {__LINE__
,B_SQRT
, 0,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_1Z
},
441 {__LINE__
,B_SQRT
, 1,P_O
,P_1Z
, 0,0,0, R_ALL
, 0, 1,P_O
,P_1Z
},
442 {__LINE__
,B_SQRT
, 0,P_O
,P_01Z
, 0,0,0, R_ALL
,
443 FE_INVALID
| FE_INVALID_SNAN
, 0,P_O
,P_11Z
},
444 {__LINE__
,B_SQRT
, 1,P_O
,P_01Z
, 0,0,0, R_ALL
,
445 FE_INVALID
| FE_INVALID_SNAN
, 1,P_O
,P_11Z
},
447 {__LINE__
,B_SQRT
, 0,P_O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_O
,P_Z
},
448 {__LINE__
,B_SQRT
, 0,P_0O
,P_Z
, 0,0,0, R_ALL
, 0, 0,P_0O
,P_Z
},
450 {__LINE__
,B_SQRT
, 1,P_O
,P_Z
, 0,0,0, R_ALL
,
451 FE_INVALID
| FE_INVALID_SQRT
, 0,P_O
,P_1Z
},
452 {__LINE__
,B_SQRT
, 1,P_1Z
,P_1Z1
, 0,0,0, R_ALL
,
453 FE_INVALID
| FE_INVALID_SQRT
, 0,P_O
,P_1Z
},
454 {__LINE__
,B_SQRT
, 1,P_Z
,P_Z1
, 0,0,0, R_ALL
,
455 FE_INVALID
| FE_INVALID_SQRT
, 0,P_O
,P_1Z
},
464 tocheck_t r
, a
, b
, x
;
467 for (i
= 0; i
< sizeof(optests
)/sizeof(optests
[0]); i
++)
469 a
= pattern(optests
[i
].a_sgn
, optests
[i
].a_exp
,
471 b
= pattern(optests
[i
].b_sgn
, optests
[i
].b_exp
,
473 x
= pattern(optests
[i
].x_sgn
, optests
[i
].x_exp
,
475 for (j
= 0; j
< 4; j
++)
476 if (optests
[i
].rmode
& 1<<j
)
479 switch (optests
[i
].op
)
481 case B_ADD
: r
= a
+ b
; break;
482 case B_SUB
: r
= a
- b
; break;
483 case B_MUL
: r
= a
* b
; break;
484 case B_DIV
: r
= a
/ b
; break;
485 case B_NEG
: r
= -a
; break;
486 case B_ABS
: r
= FUNC(fabs
)(a
); break;
487 case B_SQRT
: r
= FUNC(sqrt
)(a
); break;
489 raised
= fetestexcept(all_exceptions
);
490 check_result(optests
[i
].line
,rmnames
[j
],x
,r
);
491 check_excepts(optests
[i
].line
,rmnames
[j
],
492 optests
[i
].excepts
,raised
);
498 fail_xr(int line
, const char *rm
, tocheck_t x
, tocheck_t r
, tocheck_t xx
,
502 unsigned char *cx
, *cr
, *cxx
;
504 printf("%s:%d:round %s:fail\n with x=0x", __FILE__
, line
,rm
);
505 cx
= (unsigned char *)&x
;
506 cr
= (unsigned char *)&r
;
507 cxx
= (unsigned char *)&xx
;
508 for (i
= 0; i
< sizeof(tocheck_t
); i
++)
509 printf("%02x", cx
[i
]);
511 for (i
= 0; i
< sizeof(tocheck_t
); i
++)
512 printf("%02x", cr
[i
]);
514 for (i
= 0; i
< sizeof(tocheck_t
); i
++)
515 printf("%02x", cxx
[i
]);
516 printf(" inexact=%d\n", xflag
!= 0);
521 check_sqrt(tocheck_t a
)
524 tocheck_t r0
, r1
, r2
, x0
, x1
, x2
;
528 for (j
= 0; j
< 4; j
++)
534 excepts
= fetestexcept(all_exceptions
);
535 fesetenv(FE_DFL_ENV
);
536 raised
|= excepts
& ~FE_INEXACT
;
538 if (excepts
& FE_INEXACT
)
540 r0
= delta(r1
,-1); r2
= delta(r1
,1);
544 x0
= r0
* r0
- a
; x2
= r2
* r2
- a
;
545 ok
= fabs(x0
) >= fabs(x1
) && fabs(x1
) <= fabs(x2
);
547 case R_ZERO
: case R_DOWN
:
549 ok
= x1
<= 0 && x2
>= 0;
553 ok
= x1
>= 0 && x0
<= 0;
562 fail_xr(__LINE__
,rmnames
[j
],a
,r1
,x1
,excepts
&FE_INEXACT
);
564 check_excepts(__LINE__
,"all",0,raised
);
567 int main(int argc
, char **argv
)
571 _LIB_VERSION
= _IEEE_
;
573 /* Set up environments for rounding modes. */
574 fesetenv(FE_DFL_ENV
);
575 fesetround(FE_TONEAREST
);
577 fesetround(FE_TOWARDZERO
);
579 fesetround(FE_UPWARD
);
581 fesetround(FE_DOWNWARD
);
584 #if defined(FE_INVALID_SOFTWARE) || defined(FE_INVALID_SQRT)
585 /* There's this really stupid feature of the 601... */
586 fesetenv(FE_DFL_ENV
);
587 feraiseexcept(FE_INVALID_SOFTWARE
);
588 if (!fetestexcept(FE_INVALID_SOFTWARE
))
589 excepts_missing
|= FE_INVALID_SOFTWARE
;
590 fesetenv(FE_DFL_ENV
);
591 feraiseexcept(FE_INVALID_SQRT
);
592 if (!fetestexcept(FE_INVALID_SQRT
))
593 excepts_missing
|= FE_INVALID_SQRT
;
597 for (i
= 0; i
< 100000; i
++)
598 check_sqrt(pattern(0, P_Rno
, P_R
));
599 for (i
= 0; i
< 100; i
++)
600 check_sqrt(pattern(0, P_Z
, P_R
));
601 check_sqrt(pattern(0,P_Z
,P_Z1
));
603 printf("%d errors.\n", nerrors
);
604 return nerrors
== 0 ? 0 : 1;