1 /*-
2 * Copyright (c) 2008 David Schultz <das@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: src/tools/regression/lib/msun/test-conj.c,v 1.1 2009/01/31 18:31:57 das Exp $
27 */
28
29 /*
30 * Tests for conj{,f,l}()
31 */
32
33 #include <assert.h>
34 #include <complex.h>
35 #include <fenv.h>
36 #include <math.h>
37 #include <stdio.h>
38
39 #pragma STDC CX_LIMITED_RANGE off
40
41 /* Make sure gcc doesn't use builtin versions of these or honor __pure2. */
42 static float complex (*libconjf)(float complex) = conjf;
43 static double complex (*libconj)(double complex) = conj;
44 static long double complex (*libconjl)(long double complex) = conjl;
45 static float (*libcrealf)(float complex) = crealf;
46 static double (*libcreal)(double complex) = creal;
47 static long double (*libcreall)(long double complex) = creall;
48 static float (*libcimagf)(float complex) = cimagf;
49 static double (*libcimag)(double complex) = cimag;
50 static long double (*libcimagl)(long double complex) = cimagl;
51
52 /*
53 * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
54 * Fail an assertion if they differ.
55 */
56 static int
fpequal(long double d1,long double d2)57 fpequal(long double d1, long double d2)
58 {
59
60 if (d1 != d2)
61 return (isnan(d1) && isnan(d2));
62 return (copysignl(1.0, d1) == copysignl(1.0, d2));
63 }
64
65 static int
cfpequal(long double complex d1,long double complex d2)66 cfpequal(long double complex d1, long double complex d2)
67 {
68
69 return (fpequal(creall(d1), creall(d2)) &&
70 fpequal(cimagl(d1), cimagl(d2)));
71 }
72
73 static const double tests[] = {
74 /* a + bI */
75 0.0, 0.0,
76 0.0, 1.0,
77 1.0, 0.0,
78 -1.0, 0.0,
79 1.0, -0.0,
80 0.0, -1.0,
81 2.0, 4.0,
82 0.0, INFINITY,
83 0.0, -INFINITY,
84 INFINITY, 0.0,
85 NAN, 1.0,
86 1.0, NAN,
87 NAN, NAN,
88 -INFINITY, INFINITY,
89 };
90
91 int
main(int argc,char * argv[])92 main(int argc, char *argv[])
93 {
94 static const int ntests = sizeof(tests) / sizeof(tests[0]) / 2;
95 complex float in;
96 complex long double expected;
97 int i;
98
99 printf("1..%d\n", ntests * 3);
100
101 for (i = 0; i < ntests; i++) {
102 __real__ expected = __real__ in = tests[2 * i];
103 __imag__ in = tests[2 * i + 1];
104 __imag__ expected = -cimag(in);
105
106 assert(fpequal(libcrealf(in), __real__ in));
107 assert(fpequal(libcreal(in), __real__ in));
108 assert(fpequal(libcreall(in), __real__ in));
109 assert(fpequal(libcimagf(in), __imag__ in));
110 assert(fpequal(libcimag(in), __imag__ in));
111 assert(fpequal(libcimagl(in), __imag__ in));
112
113 feclearexcept(FE_ALL_EXCEPT);
114 if (!cfpequal(libconjf(in), expected)) {
115 printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
116 "wrong value\n",
117 3 * i + 1, creal(in), cimag(in));
118 } else if (fetestexcept(FE_ALL_EXCEPT)) {
119 printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
120 "threw an exception\n",
121 3 * i + 1, creal(in), cimag(in));
122 } else {
123 printf("ok %d\t\t# conjf(%#.2g + %#.2gI)\n",
124 3 * i + 1, creal(in), cimag(in));
125 }
126
127 feclearexcept(FE_ALL_EXCEPT);
128 if (!cfpequal(libconj(in), expected)) {
129 printf("not ok %d\t# conj(%#.2g + %#.2gI): "
130 "wrong value\n",
131 3 * i + 2, creal(in), cimag(in));
132 } else if (fetestexcept(FE_ALL_EXCEPT)) {
133 printf("not ok %d\t# conj(%#.2g + %#.2gI): "
134 "threw an exception\n",
135 3 * i + 2, creal(in), cimag(in));
136 } else {
137 printf("ok %d\t\t# conj(%#.2g + %#.2gI)\n",
138 3 * i + 2, creal(in), cimag(in));
139 }
140
141 feclearexcept(FE_ALL_EXCEPT);
142 if (!cfpequal(libconjl(in), expected)) {
143 printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
144 "wrong value\n",
145 3 * i + 3, creal(in), cimag(in));
146 } else if (fetestexcept(FE_ALL_EXCEPT)) {
147 printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
148 "threw an exception\n",
149 3 * i + 3, creal(in), cimag(in));
150 } else {
151 printf("ok %d\t\t# conjl(%#.2g + %#.2gI)\n",
152 3 * i + 3, creal(in), cimag(in));
153 }
154 }
155
156 return (0);
157 }
158