xref: /openbsd-src/regress/lib/libc/ieeefp/infinity/infinity.c (revision aacd8666e216205bbafef302a97807a41d42ccd8)
1*aacd8666Smiod /*	$OpenBSD: infinity.c,v 1.2 2004/01/16 19:34:37 miod Exp $	*/
297b76745Smiod /*
397b76745Smiod  * Written by Miodrag Vallat, 2004 - Public Domain
497b76745Smiod  * Inspired from Perl's t/op/arith test #134
597b76745Smiod  */
697b76745Smiod 
797b76745Smiod #include <math.h>
897b76745Smiod #include <signal.h>
9*aacd8666Smiod #include <unistd.h>
1097b76745Smiod 
1197b76745Smiod void
sigfpe(int signum)1297b76745Smiod sigfpe(int signum)
1397b76745Smiod {
1497b76745Smiod 	/* looks like we don't handle fp overflow correctly... */
1597b76745Smiod 	_exit(1);
1697b76745Smiod }
1797b76745Smiod 
1897b76745Smiod int
main(int argc,char * argv[])1997b76745Smiod main(int argc, char *argv[])
2097b76745Smiod {
21*aacd8666Smiod 	int opt;
22*aacd8666Smiod 	double d, two;
2397b76745Smiod 	int i;
24*aacd8666Smiod 	char method = 'a';
25*aacd8666Smiod 
26*aacd8666Smiod 	while ((opt = getopt(argc, argv, "amnp")) != -1)
27*aacd8666Smiod 		method = (char)opt;
2897b76745Smiod 
2997b76745Smiod 	signal(SIGFPE, sigfpe);
3097b76745Smiod 
31*aacd8666Smiod 	switch (method) {
32*aacd8666Smiod 	case 'a':
33*aacd8666Smiod 		/* try to produce +Inf through addition */
3497b76745Smiod 		d = 1.0;
3597b76745Smiod 		for (i = 2000; i != 0; i--) {
36*aacd8666Smiod 			d = d + d;
37*aacd8666Smiod 		}
38*aacd8666Smiod 		/* result should be _positive_ infinity */
39*aacd8666Smiod 		if (!isinf(d) || copysign(1.0, d) < 0.0)
40*aacd8666Smiod 			return (1);
41*aacd8666Smiod 		break;
42*aacd8666Smiod 	case 'm':
43*aacd8666Smiod 		/* try to produce +Inf through multiplication */
44*aacd8666Smiod 		d = 1.0;
45*aacd8666Smiod 		two = 2.0;
46*aacd8666Smiod 		for (i = 2000; i != 0; i--) {
47*aacd8666Smiod 			d = d * two;
48*aacd8666Smiod 		}
49*aacd8666Smiod 		/* result should be _positive_ infinity */
50*aacd8666Smiod 		if (!isinf(d) || copysign(1.0, d) < 0.0)
51*aacd8666Smiod 			return (1);
52*aacd8666Smiod 		break;
53*aacd8666Smiod 	case 'n':
54*aacd8666Smiod 		/* try to produce -Inf through subtraction */
55*aacd8666Smiod 		d = -1.0;
56*aacd8666Smiod 		for (i = 2000; i != 0; i--) {
57*aacd8666Smiod 			d = d + d;
58*aacd8666Smiod 		}
59*aacd8666Smiod 		/* result should be _negative_ infinity */
60*aacd8666Smiod 		if (!isinf(d) || copysign(1.0, d) > 0.0)
61*aacd8666Smiod 			return (1);
62*aacd8666Smiod 		break;
63*aacd8666Smiod 	case 'p':
64*aacd8666Smiod 		/* try to produce -Inf through multiplication */
65*aacd8666Smiod 		d = -1.0;
66*aacd8666Smiod 		two = 2.0;
67*aacd8666Smiod 		for (i = 2000; i != 0; i--) {
68*aacd8666Smiod 			d = d * two;
69*aacd8666Smiod 		}
70*aacd8666Smiod 		/* result should be _negative_ infinity */
71*aacd8666Smiod 		if (!isinf(d) || copysign(1.0, d) > 0.0)
72*aacd8666Smiod 			return (1);
73*aacd8666Smiod 		break;
7497b76745Smiod 	}
7597b76745Smiod 
76*aacd8666Smiod 	return (0);
7797b76745Smiod }
78