summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/ieeefp/infinity/infinity.c
blob: 3b1b71ec90b156e7094e4f3906ac5701664c8746 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*	$OpenBSD: infinity.c,v 1.2 2004/01/16 19:34:37 miod Exp $	*/
/*
 * Written by Miodrag Vallat, 2004 - Public Domain
 * Inspired from Perl's t/op/arith test #134
 */

#include <math.h>
#include <signal.h>
#include <unistd.h>

void
sigfpe(int signum)
{
	/* looks like we don't handle fp overflow correctly... */
	_exit(1);
}

int
main(int argc, char *argv[])
{
	int opt;
	double d, two;
	int i;
	char method = 'a';

	while ((opt = getopt(argc, argv, "amnp")) != -1)
		method = (char)opt;

	signal(SIGFPE, sigfpe);

	switch (method) {
	case 'a':
		/* try to produce +Inf through addition */
		d = 1.0;
		for (i = 2000; i != 0; i--) {
			d = d + d;
		}
		/* result should be _positive_ infinity */
		if (!isinf(d) || copysign(1.0, d) < 0.0)
			return (1);
		break;
	case 'm':
		/* try to produce +Inf through multiplication */
		d = 1.0;
		two = 2.0;
		for (i = 2000; i != 0; i--) {
			d = d * two;
		}
		/* result should be _positive_ infinity */
		if (!isinf(d) || copysign(1.0, d) < 0.0)
			return (1);
		break;
	case 'n':
		/* try to produce -Inf through subtraction */
		d = -1.0;
		for (i = 2000; i != 0; i--) {
			d = d + d;
		}
		/* result should be _negative_ infinity */
		if (!isinf(d) || copysign(1.0, d) > 0.0)
			return (1);
		break;
	case 'p':
		/* try to produce -Inf through multiplication */
		d = -1.0;
		two = 2.0;
		for (i = 2000; i != 0; i--) {
			d = d * two;
		}
		/* result should be _negative_ infinity */
		if (!isinf(d) || copysign(1.0, d) > 0.0)
			return (1);
		break;
	}

	return (0);
}