]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/netbsd-tests/lib/libm/t_fe_round.c
Upgrade to version 3.1.4
[FreeBSD/FreeBSD.git] / contrib / netbsd-tests / lib / libm / t_fe_round.c
1 /*
2  * Written by Maya Rashish <maya@NetBSD.org>
3  * Public domain.
4  *
5  * Testing IEEE-754 rounding modes (and lrint)
6  */
7
8 #include <atf-c.h>
9 #include <fenv.h>
10 #ifdef __HAVE_FENV
11 #include <math.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 /*#pragma STDC FENV_ACCESS ON gcc?? */
16
17 #define INT 9223L
18
19 #define EPSILON 0.001
20
21 static const struct {
22         int round_mode;
23         double input;
24         long int expected;
25 } values[] = {
26         { FE_DOWNWARD,          3.7,            3},
27         { FE_DOWNWARD,          -3.7,           -4},
28         { FE_DOWNWARD,          +0,             0},
29         { FE_DOWNWARD,          -INT-0.01,      -INT-1},
30         { FE_DOWNWARD,          +INT-0.01,      INT-1},
31         { FE_DOWNWARD,          -INT+0.01,      -INT},
32         { FE_DOWNWARD,          +INT+0.01,      INT},
33 #if 0 /* cpu bugs? */
34         { FE_DOWNWARD,          -0,             -1},
35
36         { FE_UPWARD,            +0,             1},
37 #endif
38         { FE_UPWARD,            -0,             0},
39         { FE_UPWARD,            -123.7,         -123},
40         { FE_UPWARD,            123.999,        124},
41         { FE_UPWARD,            -INT-0.01,      -INT},
42         { FE_UPWARD,            +INT-0.01,      INT},
43         { FE_UPWARD,            -INT+0.01,      -INT+1},
44         { FE_UPWARD,            +INT+0.01,      INT+1},
45
46         { FE_TOWARDZERO,        1.99,           1},
47         { FE_TOWARDZERO,        -1.99,          -1},
48         { FE_TOWARDZERO,        0.2,            0},
49         { FE_TOWARDZERO,        INT+0.01,       INT},
50         { FE_TOWARDZERO,        INT-0.01,       INT - 1},
51         { FE_TOWARDZERO,        -INT+0.01,      -INT + 1},
52         { FE_TOWARDZERO,        +0,             0},
53         { FE_TOWARDZERO,        -0,             0},
54
55         { FE_TONEAREST,         -INT-0.01,      -INT},
56         { FE_TONEAREST,         +INT-0.01,      INT},
57         { FE_TONEAREST,         -INT+0.01,      -INT},
58         { FE_TONEAREST,         +INT+0.01,      INT},
59         { FE_TONEAREST,         -INT-0.501,     -INT-1},
60         { FE_TONEAREST,         +INT-0.501,     INT-1},
61         { FE_TONEAREST,         -INT+0.501,     -INT+1},
62         { FE_TONEAREST,         +INT+0.501,     INT+1},
63         { FE_TONEAREST,         +0,             0},
64         { FE_TONEAREST,         -0,             0},
65 };
66
67 ATF_TC(fe_round);
68 ATF_TC_HEAD(fe_round, tc)
69 {
70         atf_tc_set_md_var(tc, "descr","Checking IEEE 754 rounding modes using lrint");
71 }
72
73 ATF_TC_BODY(fe_round, tc)
74 {
75         long int received;
76
77         for (unsigned int i = 0; i < __arraycount(values); i++) {
78                 fesetround(values[i].round_mode);
79
80                 received = lrint(values[i].input);
81                 ATF_CHECK_MSG(
82                     (labs(received - values[i].expected) < EPSILON),
83                     "lrint rounding wrong, difference too large\n"
84                     "input: %f (index %d): got %ld, expected %ld\n",
85                     values[i].input, i, received, values[i].expected);
86
87                 /* Do we get the same rounding mode out? */
88                 ATF_CHECK_MSG(
89                     (fegetround() == values[i].round_mode),
90                     "Didn't get the same rounding mode out!\n"
91                     "(index %d) fed in %d rounding mode, got %d out\n",
92                     i, fegetround(), values[i].round_mode);
93         }
94 }
95
96 ATF_TP_ADD_TCS(tp)
97 {
98
99         ATF_TP_ADD_TC(tp, fe_round);
100
101         return atf_no_error();
102 }
103 #else
104 ATF_TC(t_nofe_round);
105
106 ATF_TC_HEAD(t_nofe_round, tc)
107 {
108         atf_tc_set_md_var(tc, "descr",
109             "dummy test case - no fenv.h support");
110 }
111
112
113 ATF_TC_BODY(t_nofe_round, tc)
114 {
115         atf_tc_skip("no fenv.h support on this architecture");
116 }
117
118 ATF_TP_ADD_TCS(tp)
119 {
120         ATF_TP_ADD_TC(tp, t_nofe_round);
121         return atf_no_error();
122 }
123
124 #endif