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 
20 static 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 
42 static 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 
52 ATF_TC(signbit);
ATF_TC_HEAD(signbit,tc)53 ATF_TC_HEAD(signbit, tc)
54 {
55           atf_tc_set_md_var(tc, "descr",
56               "Check that signbit functions correctly");
57 }
58 
ATF_TC_BODY(signbit,tc)59 ATF_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 
ATF_TP_ADD_TCS(tp)105 ATF_TP_ADD_TCS(tp)
106 {
107 
108           ATF_TP_ADD_TC(tp, signbit);
109 
110           return atf_no_error();
111 }
112