1 /* Test iscanonical and canonicalizel for ldbl-96.
2 Copyright (C) 2016-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <float.h>
20 #include <math.h>
21 #include <math_ldbl.h>
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <stdio.h>
25
26 struct test
27 {
28 bool sign;
29 uint16_t exponent;
30 bool high;
31 uint64_t mantissa;
32 bool canonical;
33 };
34
35 #define M68K_VARIANT (LDBL_MIN_EXP == -16382)
36
37 static const struct test tests[] =
38 {
39 { false, 0, true, 0, M68K_VARIANT },
40 { true, 0, true, 0, M68K_VARIANT },
41 { false, 0, true, 1, M68K_VARIANT },
42 { true, 0, true, 1, M68K_VARIANT },
43 { false, 0, true, 0x100000000ULL, M68K_VARIANT },
44 { true, 0, true, 0x100000000ULL, M68K_VARIANT },
45 { false, 0, false, 0, true },
46 { true, 0, false, 0, true },
47 { false, 0, false, 1, true },
48 { true, 0, false, 1, true },
49 { false, 0, false, 0x100000000ULL, true },
50 { true, 0, false, 0x100000000ULL, true },
51 { false, 1, true, 0, true },
52 { true, 1, true, 0, true },
53 { false, 1, true, 1, true },
54 { true, 1, true, 1, true },
55 { false, 1, true, 0x100000000ULL, true },
56 { true, 1, true, 0x100000000ULL, true },
57 { false, 1, false, 0, false },
58 { true, 1, false, 0, false },
59 { false, 1, false, 1, false },
60 { true, 1, false, 1, false },
61 { false, 1, false, 0x100000000ULL, false },
62 { true, 1, false, 0x100000000ULL, false },
63 { false, 0x7ffe, true, 0, true },
64 { true, 0x7ffe, true, 0, true },
65 { false, 0x7ffe, true, 1, true },
66 { true, 0x7ffe, true, 1, true },
67 { false, 0x7ffe, true, 0x100000000ULL, true },
68 { true, 0x7ffe, true, 0x100000000ULL, true },
69 { false, 0x7ffe, false, 0, false },
70 { true, 0x7ffe, false, 0, false },
71 { false, 0x7ffe, false, 1, false },
72 { true, 0x7ffe, false, 1, false },
73 { false, 0x7ffe, false, 0x100000000ULL, false },
74 { true, 0x7ffe, false, 0x100000000ULL, false },
75 { false, 0x7fff, true, 0, true },
76 { true, 0x7fff, true, 0, true },
77 { false, 0x7fff, true, 1, true },
78 { true, 0x7fff, true, 1, true },
79 { false, 0x7fff, true, 0x100000000ULL, true },
80 { true, 0x7fff, true, 0x100000000ULL, true },
81 { false, 0x7fff, false, 0, M68K_VARIANT },
82 { true, 0x7fff, false, 0, M68K_VARIANT },
83 { false, 0x7fff, false, 1, M68K_VARIANT },
84 { true, 0x7fff, false, 1, M68K_VARIANT },
85 { false, 0x7fff, false, 0x100000000ULL, M68K_VARIANT },
86 { true, 0x7fff, false, 0x100000000ULL, M68K_VARIANT },
87 };
88
89 static int
do_test(void)90 do_test (void)
91 {
92 int result = 0;
93
94 for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
95 {
96 long double ld;
97 SET_LDOUBLE_WORDS (ld, tests[i].exponent | (tests[i].sign << 15),
98 (tests[i].mantissa >> 32) | (tests[i].high << 31),
99 tests[i].mantissa & 0xffffffffULL);
100 bool canonical = iscanonical (ld);
101 if (canonical == tests[i].canonical)
102 {
103 printf ("PASS: iscanonical test %zu\n", i);
104 long double ldc = 12345.0L;
105 bool canonicalize_ret = canonicalizel (&ldc, &ld);
106 if (canonicalize_ret == !canonical)
107 {
108 printf ("PASS: canonicalizel test %zu\n", i);
109 bool canon_ok;
110 if (!canonical)
111 canon_ok = ldc == 12345.0L;
112 else if (isnan (ld))
113 canon_ok = isnan (ldc) && !issignaling (ldc);
114 else
115 canon_ok = ldc == ld;
116 if (canon_ok)
117 printf ("PASS: canonicalized value test %zu\n", i);
118 else
119 {
120 printf ("FAIL: canonicalized value test %zu\n", i);
121 result = 1;
122 }
123 }
124 else
125 {
126 printf ("FAIL: canonicalizel test %zu\n", i);
127 result = 1;
128 }
129 }
130 else
131 {
132 printf ("FAIL: iscanonical test %zu\n", i);
133 result = 1;
134 }
135 }
136
137 return result;
138 }
139
140 #define TEST_FUNCTION do_test ()
141 #include "../test-skeleton.c"
142