source: trunk/test/unit/real.cpp @ 1893

Last change on this file since 1893 was 1893, checked in by sam, 7 years ago

math: refactor real number constant declarations so that they are only
computed on demand with static initialisation.

File size: 10.5 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cmath>
16
17#include "core.h"
18#include "lol/unit.h"
19
20namespace lol
21{
22
23LOLUNIT_FIXTURE(RealTest)
24{
25    LOLUNIT_TEST(Constants)
26    {
27        double a0 = real::R_0();
28        double a1 = real::R_1();
29        double a2 = real::R_2();
30        double a10 = real::R_10();
31
32        LOLUNIT_ASSERT_EQUAL(a0, 0.0);
33        LOLUNIT_ASSERT_EQUAL(a1, 1.0);
34        LOLUNIT_ASSERT_EQUAL(a2, 2.0);
35        LOLUNIT_ASSERT_EQUAL(a10, 10.0);
36
37        double b1 = log(real::R_E());
38        double b2 = log2(real::R_2());
39        LOLUNIT_ASSERT_EQUAL(b1, 1.0);
40        LOLUNIT_ASSERT_EQUAL(b2, 1.0);
41
42        double c1 = exp(re(real::R_LOG2E()));
43        double c2 = log(exp2(real::R_LOG2E()));
44        LOLUNIT_ASSERT_EQUAL(c1, 2.0);
45        LOLUNIT_ASSERT_EQUAL(c2, 1.0);
46
47        double d1 = exp(re(real::R_LOG10E()));
48        LOLUNIT_ASSERT_EQUAL(d1, 10.0);
49
50        double e1 = exp(real::R_LN2());
51        LOLUNIT_ASSERT_EQUAL(e1, 2.0);
52
53        double f1 = exp(real::R_LN10());
54        LOLUNIT_ASSERT_EQUAL(f1, 10.0);
55
56        double g1 = sin(real::R_PI());
57        double g2 = cos(real::R_PI());
58        LOLUNIT_ASSERT_DOUBLES_EQUAL(g1, 0.0, 1e-100);
59        LOLUNIT_ASSERT_EQUAL(g2, -1.0);
60
61        double h1 = sin(real::R_PI_2());
62        double h2 = cos(real::R_PI_2());
63        LOLUNIT_ASSERT_EQUAL(h1, 1.0);
64        LOLUNIT_ASSERT_DOUBLES_EQUAL(h2, 0.0, 1e-100);
65
66        double i1 = sin(real::R_PI_4()) * sin(real::R_PI_4());
67        double i2 = cos(real::R_PI_4()) * cos(real::R_PI_4());
68        LOLUNIT_ASSERT_EQUAL(i1, 0.5);
69        LOLUNIT_ASSERT_EQUAL(i2, 0.5);
70    }
71
72    LOLUNIT_TEST(FloatToReal)
73    {
74        float a1 = real(0.0f);
75        float a2 = real(-0.0f);
76        float a3 = real(1.0f);
77        float a4 = real(-1.0f);
78        float a5 = real(1.5f);
79        float a6 = real(12345678.0f);
80
81        LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
82        LOLUNIT_ASSERT_EQUAL(a2, -0.0f);
83        LOLUNIT_ASSERT_EQUAL(a3, 1.0f);
84        LOLUNIT_ASSERT_EQUAL(a4, -1.0f);
85        LOLUNIT_ASSERT_EQUAL(a5, 1.5f);
86        LOLUNIT_ASSERT_EQUAL(a6, 12345678.0f);
87    }
88
89    LOLUNIT_TEST(DoubleToReal)
90    {
91        double a1 = real(0.0);
92        double a2 = real(-0.0);
93        double a3 = real(1.0);
94        double a4 = real(-1.0);
95        double a5 = real(1.5);
96        double a6 = real(1234567876543210.0);
97
98        LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, 0.0, 0.0);
99        LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, -0.0, 0.0);
100        LOLUNIT_ASSERT_DOUBLES_EQUAL(a3, 1.0, 0.0);
101        LOLUNIT_ASSERT_DOUBLES_EQUAL(a4, -1.0, 0.0);
102        LOLUNIT_ASSERT_DOUBLES_EQUAL(a5, 1.5, 0.0);
103        LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 1234567876543210.0, 0.0);
104    }
105
106    LOLUNIT_TEST(Init)
107    {
108        real r;
109        float f1 = (float)r;
110
111        LOLUNIT_ASSERT_EQUAL(f1, 0.0f);
112
113        rcmplx q;
114        float f2 = (float)q.x;
115        float f3 = (float)q.y;
116
117        LOLUNIT_ASSERT_EQUAL(f2, 0.0f);
118        LOLUNIT_ASSERT_EQUAL(f3, 0.0f);
119    }
120
121    LOLUNIT_TEST(StringToReal)
122    {
123        float a1 = real("0");
124        float a2 = real("1");
125        float a3 = real("-1");
126        /* 2^-128 * 2^128 */
127        float a4 = real("0.0000000000000000000000000000000000000029387358770"
128                        "557187699218413430556141945466638919302188037718792"
129                        "6569604314863681793212890625")
130                 * real("340282366920938463463374607431768211456");
131
132        LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
133        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
134        LOLUNIT_ASSERT_EQUAL(a3, -1.0f);
135        LOLUNIT_ASSERT_EQUAL(a4, 1.0f);
136    }
137
138    LOLUNIT_TEST(UnaryMinus)
139    {
140        float a1 = - real(1.0f);
141        float a2 = - real(-1.0f);
142        float a3 = - real(0.0f);
143        float a4 = - real(-0.0f);
144
145        LOLUNIT_ASSERT_EQUAL(a1, -1.0f);
146        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
147        LOLUNIT_ASSERT_EQUAL(a3, -0.0f);
148        LOLUNIT_ASSERT_EQUAL(a4, 0.0f);
149    }
150
151    LOLUNIT_TEST(Comparison)
152    {
153        LOLUNIT_ASSERT(real(1.0f) > real(0.5f));
154        LOLUNIT_ASSERT(real(1.0f) >= real(0.5f));
155        LOLUNIT_ASSERT(real(1.0f) >= real(1.0f));
156
157        LOLUNIT_ASSERT(real(-1.0f) < real(-0.5f));
158        LOLUNIT_ASSERT(real(-1.0f) <= real(-0.5f));
159        LOLUNIT_ASSERT(real(-1.0f) <= real(-1.0f));
160
161        LOLUNIT_ASSERT(real(-1.0f) < real(0.5f));
162        LOLUNIT_ASSERT(real(-0.5f) < real(1.0f));
163        LOLUNIT_ASSERT(real(-1.0f) <= real(0.5f));
164        LOLUNIT_ASSERT(real(-0.5f) <= real(1.0f));
165
166        LOLUNIT_ASSERT(real(1.0f) > real(-0.5f));
167        LOLUNIT_ASSERT(real(0.5f) > real(-1.0f));
168        LOLUNIT_ASSERT(real(1.0f) >= real(-0.5f));
169        LOLUNIT_ASSERT(real(0.5f) >= real(-1.0f));
170    }
171
172    LOLUNIT_TEST(Addition)
173    {
174        float a1 = real(1.0f) + real(0.0f);
175        float a2 = real(0.0f) + real(1.0f);
176        float a3 = real(1.0f) + real(1.0f);
177        float a4 = real(-1.0f) + real(-1.0f);
178        float a5 = real(1.0f) + real(0.125f);
179        double a6 = real(3.13609818956293918)
180                  + real(0.00005972154828114);
181        float a7 = real(1.0f) + real(-0.125f);
182        double a8 = real(0.10000000002) + real(-2.0e-11);
183
184        LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
185        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
186        LOLUNIT_ASSERT_EQUAL(a3, 2.0f);
187        LOLUNIT_ASSERT_EQUAL(a4, -2.0f);
188        LOLUNIT_ASSERT_EQUAL(a5, 1.125f);
189        LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 3.1361579, 0.000001);
190        LOLUNIT_ASSERT_EQUAL(a7, 0.875f);
191        LOLUNIT_ASSERT_DOUBLES_EQUAL(a8, 0.1, 1.0e-13);
192    }
193
194    LOLUNIT_TEST(Subtraction)
195    {
196        float a1 = real(1.0f) + real(1e20f) - real(1e20f);
197
198        LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
199    }
200
201    LOLUNIT_TEST(Multiplication)
202    {
203        real x(1.25f);
204        real y(1.5f);
205        real z(1.99999f);
206        real w(-1.5f);
207
208        float m1 = x * x;
209        float m2 = y * y;
210        float m3 = z * z;
211        float m4 = w * w;
212
213        LOLUNIT_ASSERT_EQUAL(m1, 1.25f * 1.25f);
214        LOLUNIT_ASSERT_EQUAL(m2, 1.5f * 1.5f);
215        LOLUNIT_ASSERT_EQUAL(m3, 1.99999f * 1.99999f);
216        LOLUNIT_ASSERT_EQUAL(m4, -1.5f * -1.5f);
217    }
218
219    LOLUNIT_TEST(ExactDivision)
220    {
221        float m1 = real::R_1() / real::R_1();
222        float m2 = real::R_2() / real::R_1();
223        float m3 = real::R_1() / real::R_2();
224        float m4 = real::R_2() / real::R_2();
225        float m5 = real::R_1() / -real::R_2();
226
227        LOLUNIT_ASSERT_EQUAL(m1, 1.0f);
228        LOLUNIT_ASSERT_EQUAL(m2, 2.0f);
229        LOLUNIT_ASSERT_EQUAL(m3, 0.5f);
230        LOLUNIT_ASSERT_EQUAL(m4, 1.0f);
231        LOLUNIT_ASSERT_EQUAL(m5, -0.5f);
232    }
233
234    LOLUNIT_TEST(InexactDivision)
235    {
236        /* 1 / 3 * 3 should be close to 1... check that it does not differ
237         * by more than 2^-k where k is the number of bits in the mantissa. */
238        real a = real::R_1() / real::R_3() * real::R_3();
239        real b = ldexp(real::R_1() - a, real::BIGITS * real::BIGIT_BITS);
240
241        LOLUNIT_ASSERT_LEQUAL((double)fabs(b), 1.0);
242    }
243
244    LOLUNIT_TEST(LoadExp)
245    {
246        real a1(1.5);
247        real a2(-1.5);
248        real a3(0.0);
249
250        LOLUNIT_ASSERT_EQUAL((double)ldexp(a1, 7), 192.0);
251        LOLUNIT_ASSERT_EQUAL((double)ldexp(a1, -7), 0.01171875);
252
253        LOLUNIT_ASSERT_EQUAL((double)ldexp(a2, 7), -192.0);
254        LOLUNIT_ASSERT_EQUAL((double)ldexp(a2, -7), -0.01171875);
255
256        LOLUNIT_ASSERT_EQUAL((double)ldexp(a3, 7), 0.0);
257        LOLUNIT_ASSERT_EQUAL((double)ldexp(a3, -7), 0.0);
258    }
259
260    LOLUNIT_TEST(Ulp)
261    {
262        real a1 = real::R_PI();
263
264        LOLUNIT_ASSERT_NOT_EQUAL((double)(a1 + ulp(a1) - a1), 0.0);
265        LOLUNIT_ASSERT_EQUAL((double)(a1 + ulp(a1) / 2 - a1), 0.0);
266    }
267
268    LOLUNIT_TEST(Bool)
269    {
270        real a = 0.0;
271        LOLUNIT_ASSERT(!a);
272
273        a = -0.0;
274        LOLUNIT_ASSERT(!a);
275
276        a = 1234.0;
277        LOLUNIT_ASSERT(a);
278        LOLUNIT_ASSERT(!!a);
279
280        a = -1234.0;
281        LOLUNIT_ASSERT(a);
282        LOLUNIT_ASSERT(!!a);
283    }
284
285    LOLUNIT_TEST(AsinAcos)
286    {
287        double tests[] =
288        {
289            -1024.0, -1023.0, -513.0, -512.0, -511.0, -1.0, -0.0,
290            0.0, 1.0, 511.0, 512.0, 513.0, 1023.0, 1024.0
291        };
292
293        for (unsigned int n = 0; n < sizeof(tests) / sizeof(*tests); n++)
294        {
295            double a = tests[n] / 1024;
296            double b = sin(asin((real)a));
297            double c = cos(acos((real)a));
298
299            LOLUNIT_SET_CONTEXT(a);
300            LOLUNIT_ASSERT_DOUBLES_EQUAL(b, a, 1e-100);
301            LOLUNIT_ASSERT_DOUBLES_EQUAL(c, a, 1e-100);
302        }
303    }
304
305    LOLUNIT_TEST(FloorCeilEtc)
306    {
307        double tests[] =
308        {
309            -2.0,  -2.0, -2.0,  -2.0,
310            -1.5,  -2.0, -1.0,  -2.0,
311            -1.0,  -1.0, -1.0,  -1.0,
312            -0.0,  -0.0, -0.0,  -0.0,
313             0.0,   0.0,  0.0,   0.0,
314             0.25,  0.0,  1.0,   0.0,
315             0.375, 0.0,  1.0,   0.0,
316             0.5,   0.0,  1.0,   1.0,
317             1.0,   1.0,  1.0,   1.0,
318             1.5,   1.0,  2.0,   2.0,
319             2.0,   2.0,  2.0,   2.0,
320             2.5,   2.0,  3.0,   3.0,
321             3.0,   3.0,  3.0,   3.0,
322            8192.0,     8192.0, 8192.0, 8192.0,
323            8192.03125, 8192.0, 8193.0, 8192.0,
324            8192.5,     8192.0, 8193.0, 8193.0,
325            8193.0,     8193.0, 8193.0, 8193.0,
326            549755813888.0,     549755813888.0, 549755813888.0, 549755813888.0,
327            549755813888.03125, 549755813888.0, 549755813889.0, 549755813888.0,
328            549755813888.5,     549755813888.0, 549755813889.0, 549755813889.0,
329            549755813889.0,     549755813889.0, 549755813889.0, 549755813889.0,
330        };
331
332        for (unsigned int n = 0; n < sizeof(tests) / sizeof(*tests); n += 4)
333        {
334            double a0 = floor((real)tests[n]);
335            double b0 = tests[n + 1];
336            double a1 = ceil((real)tests[n]);
337            double b1 = tests[n + 2];
338            double a2 = round((real)tests[n]);
339            double b2 = tests[n + 3];
340
341            LOLUNIT_ASSERT_EQUAL(b0, a0);
342            LOLUNIT_ASSERT_EQUAL(b1, a1);
343            LOLUNIT_ASSERT_EQUAL(b2, a2);
344        }
345    }
346
347    LOLUNIT_TEST(Pow)
348    {
349        double a1 = pow(-real::R_2(), real::R_2());
350        double b1 = 4.0;
351        LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, b1, 1.0e-13);
352
353        double a2 = pow(-real::R_2(), real::R_3());
354        double b2 = -8.0;
355        LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, b2, 1.0e-13);
356    }
357};
358
359} /* namespace lol */
360
Note: See TracBrowser for help on using the repository browser.