1/*	$NetBSD: t_bit.c,v 1.2 2024/05/06 18:41:23 riastradh Exp $	*/
2
3/*
4 * Written by Maya Rashish <maya@NetBSD.org>
5 * Public domain.
6 *
7 * Testing signbit{,f,l} function correctly
8 */
9
10#include <sys/cdefs.h>
11__RCSID("$NetBSD: t_bit.c,v 1.2 2024/05/06 18:41:23 riastradh Exp $");
12
13#include <atf-c.h>
14#include <float.h>
15#include <math.h>
16#include <stdio.h>
17#include <stdint.h>
18#include <stdbool.h>
19
20static const struct {
21	double input;
22	bool is_negative;
23} values[] = {
24	{ -1,		true },
25	{ -123,		true },
26	{ -123E6,	true },
27	{ -INFINITY,	true },
28	{ INFINITY,	false },
29	{ 123E6,	false },
30	{ 0,		false },
31	{ -0.,		true },
32	{ -FLT_MIN,	true },
33	{ FLT_MIN,	false },
34	/*
35	 * Cannot be accurately represented as float,
36	 * but sign should be preserved
37	 */
38	{ DBL_MAX,	false },
39	{ -DBL_MAX,	true },
40};
41
42static const struct {
43	long double input;
44	bool is_negative;
45} ldbl_values[] = {
46	{ -LDBL_MIN,	true },
47	{ LDBL_MIN,	false },
48	{ LDBL_MAX,	false },
49	{ -LDBL_MAX,	true },
50};
51
52ATF_TC(signbit);
53ATF_TC_HEAD(signbit, tc)
54{
55	atf_tc_set_md_var(tc, "descr",
56	    "Check that signbit functions correctly");
57}
58
59ATF_TC_BODY(signbit, tc)
60{
61	unsigned i;
62
63	for (i = 0; i < __arraycount(values); i++) {
64		const float iterator_f = values[i].input;
65		const double iterator_d = values[i].input;
66		const long double iterator_l = values[i].input;
67
68		if (signbit(iterator_f) != values[i].is_negative) {
69			atf_tc_fail("%s:%d iteration %d signbitf is wrong"
70			    " about the sign of %f", __func__, __LINE__, i,
71			    iterator_f);
72		}
73		if (signbit(iterator_d) != values[i].is_negative) {
74			atf_tc_fail("%s:%d iteration %d signbit is wrong"
75			    "about the sign of %f", __func__, __LINE__, i,
76			    iterator_d);
77		}
78		if (signbit(iterator_l) != values[i].is_negative) {
79			atf_tc_fail("%s:%d iteration %d signbitl is wrong"
80			    " about the sign of %Lf", __func__, __LINE__, i,
81			    iterator_l);
82		}
83	}
84
85	for (i = 0; i < __arraycount(ldbl_values); i++) {
86		if (signbit(ldbl_values[i].input) !=
87		    ldbl_values[i].is_negative) {
88			atf_tc_fail("%s:%d iteration %d signbitl is"
89			    "wrong about the sign of %Lf",
90			    __func__, __LINE__, i,
91			    ldbl_values[i].input);
92		}
93	}
94
95#ifdef NAN
96	ATF_CHECK_EQ(signbit(copysignf(NAN, -1)), true);
97	ATF_CHECK_EQ(signbit(copysignf(NAN, +1)), false);
98	ATF_CHECK_EQ(signbit(copysign(NAN, -1)), true);
99	ATF_CHECK_EQ(signbit(copysign(NAN, +1)), false);
100	ATF_CHECK_EQ(signbit(copysignl(NAN, -1)), true);
101	ATF_CHECK_EQ(signbit(copysignl(NAN, +1)), false);
102#endif
103}
104
105ATF_TP_ADD_TCS(tp)
106{
107
108	ATF_TP_ADD_TC(tp, signbit);
109
110	return atf_no_error();
111}
112