Imported Upstream version 3.1.9
[platform/upstream/Imath.git] / src / ImathTest / testFun.cpp
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5
6 #ifdef NDEBUG
7 #    undef NDEBUG
8 #endif
9
10 #include <ImathFun.h>
11 #if __cplusplus >= 202002L
12 #    include <bit>
13 #endif
14 #include <iostream>
15 #include <assert.h>
16 #include <iostream>
17 #include <cstdint>
18 #include <stdio.h>
19 #include <inttypes.h>
20
21 using namespace std;
22
23 #if __cplusplus < 202002L
24     template <typename To, typename From>
25     static inline To
26     bit_cast (From from)
27     {
28         static_assert (sizeof (From) == sizeof (To), "Type sizes do not match");
29         union
30         {
31             From f;
32             To   t;
33         } u;
34         u.f = from;
35         return u.t;
36     }
37 #endif
38
39 void
40 testf (float f, bool changeExpected = true)
41 {
42     printf ("\n");
43
44     float sf = IMATH_INTERNAL_NAMESPACE::succf (f);
45     float pf = IMATH_INTERNAL_NAMESPACE::predf (f);
46     float spf = IMATH_INTERNAL_NAMESPACE::succf (IMATH_INTERNAL_NAMESPACE::predf (f));
47     float psf = IMATH_INTERNAL_NAMESPACE::predf (IMATH_INTERNAL_NAMESPACE::succf (f));
48
49     printf ("f %.9g %" PRIx32 "\n", f, bit_cast<uint32_t> (f));
50     printf ("sf %.9g %" PRIx32 "\n", sf, bit_cast<uint32_t> (sf));
51     printf ("pf %.9g %" PRIx32 "\n", pf, bit_cast<uint32_t> (pf));
52     printf ("spf %.9g %" PRIx32 "\n", spf, bit_cast<uint32_t> (spf));
53     printf ("psf %.9g %" PRIx32 "\n", psf, bit_cast<uint32_t> (psf));
54
55     fflush (stdout);
56
57     if (changeExpected)
58     {
59         assert (pf < f);
60         assert (f < sf);
61     }
62     else
63     {
64         if (isnan(f))
65         {
66             // If f is nan, pf and sf may be converted from signaling
67             // to quiet nan, but they'll still be nan's.
68             assert (isnan(pf));
69             assert (isnan(sf));
70         }
71         else
72         {
73             // No bit change expected if input was inf.
74             assert (bit_cast<uint32_t> (pf) == bit_cast<uint32_t> (f));
75             assert (bit_cast<uint32_t> (sf) == bit_cast<uint32_t> (f));
76         }
77     }
78 }
79
80 void
81 testd (double d, bool changeExpected = true)
82 {
83     printf ("\n");
84
85     double sd = IMATH_INTERNAL_NAMESPACE::succd (d);
86     double pd = IMATH_INTERNAL_NAMESPACE::predd (d);
87     double spd = IMATH_INTERNAL_NAMESPACE::succd (IMATH_INTERNAL_NAMESPACE::predd (d));
88     double psd = IMATH_INTERNAL_NAMESPACE::predd (IMATH_INTERNAL_NAMESPACE::succd (d));
89
90     printf ("d   %0.18lg %" PRIx64 "\n", d, bit_cast<uint64_t> (d));
91     printf ("sd  %0.18lg %" PRIx64 "\n", sd, bit_cast<uint64_t> (sd));
92     printf ("pd  %0.18lg %" PRIx64 "\n", pd, bit_cast<uint64_t> (pd));
93     printf ("spd %0.18lg %" PRIx64 "\n", spd, bit_cast<uint64_t> (spd));
94     printf ("psd %0.18lg %" PRIx64 "\n", psd, bit_cast<uint64_t> (psd));
95
96     fflush (stdout);
97
98     if (changeExpected)
99     {
100         assert (pd < d);
101         assert (d < sd);
102     }
103     else
104     {
105         if (isnan(d))
106         {
107             // If f is nan, pf and sf may be converted from signaling
108             // to quiet nan, but they'll still be nan's.
109             assert (isnan(pd));
110             assert (isnan(sd));
111         }
112         else
113         {
114             // No bit change expected if input was inf.
115             assert (bit_cast<uint64_t> (pd) == bit_cast<uint64_t> (d));
116             assert (bit_cast<uint64_t> (sd) == bit_cast<uint64_t> (d));
117         }
118     }
119 }
120
121 void
122 testFun()
123 {
124     cout << "Testing functions in ImathFun.h" << endl;
125
126     cout << "floor" << endl;
127
128     assert (IMATH_INTERNAL_NAMESPACE::floor (0.0f) == 0);
129     assert (IMATH_INTERNAL_NAMESPACE::floor (0.5f) == 0);
130     assert (IMATH_INTERNAL_NAMESPACE::floor (-0.5f) == -1);
131     assert (IMATH_INTERNAL_NAMESPACE::floor (1.0f) == 1);
132     assert (IMATH_INTERNAL_NAMESPACE::floor (-1.0f) == -1);
133     assert (IMATH_INTERNAL_NAMESPACE::floor (1.5f) == 1);
134     assert (IMATH_INTERNAL_NAMESPACE::floor (-1.5f) == -2);
135
136     cout << "ceil" << endl;
137
138     assert (IMATH_INTERNAL_NAMESPACE::ceil (0.0f) == 0);
139     assert (IMATH_INTERNAL_NAMESPACE::ceil (0.5f) == 1);
140     assert (IMATH_INTERNAL_NAMESPACE::ceil (-0.5f) == 0);
141     assert (IMATH_INTERNAL_NAMESPACE::ceil (1.0f) == 1);
142     assert (IMATH_INTERNAL_NAMESPACE::ceil (-1.0f) == -1);
143     assert (IMATH_INTERNAL_NAMESPACE::ceil (1.5f) == 2);
144     assert (IMATH_INTERNAL_NAMESPACE::ceil (-1.5f) == -1);
145
146     cout << "trunc" << endl;
147
148     assert (IMATH_INTERNAL_NAMESPACE::trunc (0.0f) == 0);
149     assert (IMATH_INTERNAL_NAMESPACE::trunc (0.5f) == 0);
150     assert (IMATH_INTERNAL_NAMESPACE::trunc (-0.5f) == 0);
151     assert (IMATH_INTERNAL_NAMESPACE::trunc (1.0f) == 1);
152     assert (IMATH_INTERNAL_NAMESPACE::trunc (-1.0f) == -1);
153     assert (IMATH_INTERNAL_NAMESPACE::trunc (1.5f) == 1);
154     assert (IMATH_INTERNAL_NAMESPACE::trunc (-1.5f) == -1);
155
156     cout << "divs / mods" << endl;
157
158     assert (IMATH_INTERNAL_NAMESPACE::divs (5, 2) == 2 &&
159             IMATH_INTERNAL_NAMESPACE::mods (5, 2) == 1);
160     assert (IMATH_INTERNAL_NAMESPACE::divs (4, 2) == 2 &&
161             IMATH_INTERNAL_NAMESPACE::mods (4, 2) == 0);
162     assert (IMATH_INTERNAL_NAMESPACE::divs (3, 2) == 1 &&
163             IMATH_INTERNAL_NAMESPACE::mods (3, 2) == 1);
164     assert (IMATH_INTERNAL_NAMESPACE::divs (2, 2) == 1 &&
165             IMATH_INTERNAL_NAMESPACE::mods (2, 2) == 0);
166     assert (IMATH_INTERNAL_NAMESPACE::divs (1, 2) == 0 &&
167             IMATH_INTERNAL_NAMESPACE::mods (1, 2) == 1);
168     assert (IMATH_INTERNAL_NAMESPACE::divs (0, 2) == 0 &&
169             IMATH_INTERNAL_NAMESPACE::mods (0, 2) == 0);
170     assert (IMATH_INTERNAL_NAMESPACE::divs (-1, 2) == 0 &&
171             IMATH_INTERNAL_NAMESPACE::mods (-1, 2) == -1);
172     assert (IMATH_INTERNAL_NAMESPACE::divs (-2, 2) == -1 &&
173             IMATH_INTERNAL_NAMESPACE::mods (-2, 2) == 0);
174     assert (IMATH_INTERNAL_NAMESPACE::divs (-3, 2) == -1 &&
175             IMATH_INTERNAL_NAMESPACE::mods (-3, 2) == -1);
176     assert (IMATH_INTERNAL_NAMESPACE::divs (-4, 2) == -2 &&
177             IMATH_INTERNAL_NAMESPACE::mods (-4, 2) == 0);
178     assert (IMATH_INTERNAL_NAMESPACE::divs (-5, 2) == -2 &&
179             IMATH_INTERNAL_NAMESPACE::mods (-5, 2) == -1);
180
181     assert (IMATH_INTERNAL_NAMESPACE::divs (5, -2) == -2 &&
182             IMATH_INTERNAL_NAMESPACE::mods (5, -2) == 1);
183     assert (IMATH_INTERNAL_NAMESPACE::divs (4, -2) == -2 &&
184             IMATH_INTERNAL_NAMESPACE::mods (4, -2) == 0);
185     assert (IMATH_INTERNAL_NAMESPACE::divs (3, -2) == -1 &&
186             IMATH_INTERNAL_NAMESPACE::mods (3, -2) == 1);
187     assert (IMATH_INTERNAL_NAMESPACE::divs (2, -2) == -1 &&
188             IMATH_INTERNAL_NAMESPACE::mods (2, -2) == 0);
189     assert (IMATH_INTERNAL_NAMESPACE::divs (1, -2) == 0 &&
190             IMATH_INTERNAL_NAMESPACE::mods (1, -2) == 1);
191     assert (IMATH_INTERNAL_NAMESPACE::divs (0, -2) == 0 &&
192             IMATH_INTERNAL_NAMESPACE::mods (0, -2) == 0);
193     assert (IMATH_INTERNAL_NAMESPACE::divs (-1, -2) == 0 &&
194             IMATH_INTERNAL_NAMESPACE::mods (-1, -2) == -1);
195     assert (IMATH_INTERNAL_NAMESPACE::divs (-2, -2) == 1 &&
196             IMATH_INTERNAL_NAMESPACE::mods (-2, -2) == 0);
197     assert (IMATH_INTERNAL_NAMESPACE::divs (-3, -2) == 1 &&
198             IMATH_INTERNAL_NAMESPACE::mods (-3, -2) == -1);
199     assert (IMATH_INTERNAL_NAMESPACE::divs (-4, -2) == 2 &&
200             IMATH_INTERNAL_NAMESPACE::mods (-4, -2) == 0);
201     assert (IMATH_INTERNAL_NAMESPACE::divs (-5, -2) == 2 &&
202             IMATH_INTERNAL_NAMESPACE::mods (-5, -2) == -1);
203
204     cout << "divp / modp" << endl;
205
206     assert (IMATH_INTERNAL_NAMESPACE::divp (5, 2) == 2 &&
207             IMATH_INTERNAL_NAMESPACE::modp (5, 2) == 1);
208     assert (IMATH_INTERNAL_NAMESPACE::divp (4, 2) == 2 &&
209             IMATH_INTERNAL_NAMESPACE::modp (4, 2) == 0);
210     assert (IMATH_INTERNAL_NAMESPACE::divp (3, 2) == 1 &&
211             IMATH_INTERNAL_NAMESPACE::modp (3, 2) == 1);
212     assert (IMATH_INTERNAL_NAMESPACE::divp (2, 2) == 1 &&
213             IMATH_INTERNAL_NAMESPACE::modp (2, 2) == 0);
214     assert (IMATH_INTERNAL_NAMESPACE::divp (1, 2) == 0 &&
215             IMATH_INTERNAL_NAMESPACE::modp (1, 2) == 1);
216     assert (IMATH_INTERNAL_NAMESPACE::divp (0, 2) == 0 &&
217             IMATH_INTERNAL_NAMESPACE::modp (0, 2) == 0);
218     assert (IMATH_INTERNAL_NAMESPACE::divp (-1, 2) == -1 &&
219             IMATH_INTERNAL_NAMESPACE::modp (-1, 2) == 1);
220     assert (IMATH_INTERNAL_NAMESPACE::divp (-2, 2) == -1 &&
221             IMATH_INTERNAL_NAMESPACE::modp (-2, 2) == 0);
222     assert (IMATH_INTERNAL_NAMESPACE::divp (-3, 2) == -2 &&
223             IMATH_INTERNAL_NAMESPACE::modp (-3, 2) == 1);
224     assert (IMATH_INTERNAL_NAMESPACE::divp (-4, 2) == -2 &&
225             IMATH_INTERNAL_NAMESPACE::modp (-4, 2) == 0);
226     assert (IMATH_INTERNAL_NAMESPACE::divp (-5, 2) == -3 &&
227             IMATH_INTERNAL_NAMESPACE::modp (-5, 2) == 1);
228
229     assert (IMATH_INTERNAL_NAMESPACE::divp (5, -2) == -2 &&
230             IMATH_INTERNAL_NAMESPACE::modp (5, -2) == 1);
231     assert (IMATH_INTERNAL_NAMESPACE::divp (4, -2) == -2 &&
232             IMATH_INTERNAL_NAMESPACE::modp (4, -2) == 0);
233     assert (IMATH_INTERNAL_NAMESPACE::divp (3, -2) == -1 &&
234             IMATH_INTERNAL_NAMESPACE::modp (3, -2) == 1);
235     assert (IMATH_INTERNAL_NAMESPACE::divp (2, -2) == -1 &&
236             IMATH_INTERNAL_NAMESPACE::modp (2, -2) == 0);
237     assert (IMATH_INTERNAL_NAMESPACE::divp (1, -2) == 0 &&
238             IMATH_INTERNAL_NAMESPACE::modp (1, -2) == 1);
239     assert (IMATH_INTERNAL_NAMESPACE::divp (0, -2) == 0 &&
240             IMATH_INTERNAL_NAMESPACE::modp (0, -2) == 0);
241     assert (IMATH_INTERNAL_NAMESPACE::divp (-1, -2) == 1 &&
242             IMATH_INTERNAL_NAMESPACE::modp (-1, -2) == 1);
243     assert (IMATH_INTERNAL_NAMESPACE::divp (-2, -2) == 1 &&
244             IMATH_INTERNAL_NAMESPACE::modp (-2, -2) == 0);
245     assert (IMATH_INTERNAL_NAMESPACE::divp (-3, -2) == 2 &&
246             IMATH_INTERNAL_NAMESPACE::modp (-3, -2) == 1);
247     assert (IMATH_INTERNAL_NAMESPACE::divp (-4, -2) == 2 &&
248             IMATH_INTERNAL_NAMESPACE::modp (-4, -2) == 0);
249     assert (IMATH_INTERNAL_NAMESPACE::divp (-5, -2) == 3 &&
250             IMATH_INTERNAL_NAMESPACE::modp (-5, -2) == 1);
251
252     cout << "successor, predecessor" << endl;
253
254     testf (0);
255     testf (0.0f * -1.0f);
256     testf (1);
257     testf (-1);
258     testf (16);
259     testf (7);
260     testf (0.7f);
261
262     union {float f; uint32_t i;} u;
263     u.i = 0x7f800000; //  inf
264     testf (u.f, false);
265     u.i = 0xff800000; // -inf
266     testf (u.f, false);
267     u.i = 0x7f800001; //  nan
268     testf (u.f, false);
269     u.i = 0x7f7fffff; //  FLT_MAX
270     testf (u.f);
271     u.i = 0xff7fffff; // -FLT_MAX
272     testf (u.f);
273
274     testd (0);
275     testd (0.0 * -1.0);
276     testd (1);
277     testd (-1);
278     testd (16);
279     testd (7);
280     testd (0.7);
281
282     union {double d; uint64_t i;} v;
283     v.i = 0x7ff0000000000000ULL; //  inf
284     testd (v.d, false);
285     v.i = 0xfff0000000000000ULL; // -inf
286     testd (v.d, false);
287     v.i = 0x7ff0000000000001ULL; //  NAN
288     testd (v.d, false);
289     v.i = 0x7fefffffffffffffULL; //  FLT_MAX
290     testd (v.d);
291     v.i = 0xffefffffffffffffULL; // -FLT_MAX
292     testd (v.d);
293
294     cout << "ok\n" << endl;
295 }