1 /*	$OpenBSD: infinity.c,v 1.2 2004/01/16 19:34:37 miod Exp $	*/
2 /*
3  * Written by Miodrag Vallat, 2004 - Public Domain
4  * Inspired from Perl's t/op/arith test #134
5  */
6 
7 #include <math.h>
8 #include <signal.h>
9 #include <unistd.h>
10 
11 void
12 sigfpe(int signum)
13 {
14 	/* looks like we don't handle fp overflow correctly... */
15 	_exit(1);
16 }
17 
18 int
19 main(int argc, char *argv[])
20 {
21 	int opt;
22 	double d, two;
23 	int i;
24 	char method = 'a';
25 
26 	while ((opt = getopt(argc, argv, "amnp")) != -1)
27 		method = (char)opt;
28 
29 	signal(SIGFPE, sigfpe);
30 
31 	switch (method) {
32 	case 'a':
33 		/* try to produce +Inf through addition */
34 		d = 1.0;
35 		for (i = 2000; i != 0; i--) {
36 			d = d + d;
37 		}
38 		/* result should be _positive_ infinity */
39 		if (!isinf(d) || copysign(1.0, d) < 0.0)
40 			return (1);
41 		break;
42 	case 'm':
43 		/* try to produce +Inf through multiplication */
44 		d = 1.0;
45 		two = 2.0;
46 		for (i = 2000; i != 0; i--) {
47 			d = d * two;
48 		}
49 		/* result should be _positive_ infinity */
50 		if (!isinf(d) || copysign(1.0, d) < 0.0)
51 			return (1);
52 		break;
53 	case 'n':
54 		/* try to produce -Inf through subtraction */
55 		d = -1.0;
56 		for (i = 2000; i != 0; i--) {
57 			d = d + d;
58 		}
59 		/* result should be _negative_ infinity */
60 		if (!isinf(d) || copysign(1.0, d) > 0.0)
61 			return (1);
62 		break;
63 	case 'p':
64 		/* try to produce -Inf through multiplication */
65 		d = -1.0;
66 		two = 2.0;
67 		for (i = 2000; i != 0; i--) {
68 			d = d * two;
69 		}
70 		/* result should be _negative_ infinity */
71 		if (!isinf(d) || copysign(1.0, d) > 0.0)
72 			return (1);
73 		break;
74 	}
75 
76 	return (0);
77 }
78