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

Last change on this file since 1017 was 1017, checked in by sam, 9 years ago

core: fix an accuracy error in real::re() and real::sqrt() introduced in
the 16-to-32-bit refactoring.

File size: 9.2 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 b0 = log(real::R_E);
38        LOLUNIT_ASSERT_EQUAL(b0, 1.0);
39
40        double b1 = exp(re(real::R_LOG2E));
41        LOLUNIT_ASSERT_EQUAL(b1, 2.0);
42
43        double b2 = exp(re(real::R_LOG10E));
44        LOLUNIT_ASSERT_EQUAL(b2, 10.0);
45
46        double b3 = exp(real::R_LN2);
47        LOLUNIT_ASSERT_EQUAL(b3, 2.0);
48
49        double b4 = exp(real::R_LN10);
50        LOLUNIT_ASSERT_EQUAL(b4, 10.0);
51
52        double b5 = sin(real::R_PI);
53        double b6 = cos(real::R_PI);
54        LOLUNIT_ASSERT_DOUBLES_EQUAL(b5, 0.0, 1e-100);
55        LOLUNIT_ASSERT_EQUAL(b6, -1.0);
56
57        double b7 = sin(real::R_PI_2);
58        double b8 = cos(real::R_PI_2);
59        LOLUNIT_ASSERT_EQUAL(b7, 1.0);
60        LOLUNIT_ASSERT_DOUBLES_EQUAL(b8, 0.0, 1e-100);
61
62        double b9 = sin(real::R_PI_4) * sin(real::R_PI_4);
63        double b10 = cos(real::R_PI_4) * cos(real::R_PI_4);
64        LOLUNIT_ASSERT_EQUAL(b9, 0.5);
65        LOLUNIT_ASSERT_EQUAL(b10, 0.5);
66    }
67
68    LOLUNIT_TEST(FloatToReal)
69    {
70        float a1 = real(0.0f);
71        float a2 = real(-0.0f);
72        float a3 = real(1.0f);
73        float a4 = real(-1.0f);
74        float a5 = real(1.5f);
75        float a6 = real(12345678.0f);
76
77        LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
78        LOLUNIT_ASSERT_EQUAL(a2, -0.0f);
79        LOLUNIT_ASSERT_EQUAL(a3, 1.0f);
80        LOLUNIT_ASSERT_EQUAL(a4, -1.0f);
81        LOLUNIT_ASSERT_EQUAL(a5, 1.5f);
82        LOLUNIT_ASSERT_EQUAL(a6, 12345678.0f);
83    }
84
85    LOLUNIT_TEST(DoubleToReal)
86    {
87        double a1 = real(0.0);
88        double a2 = real(-0.0);
89        double a3 = real(1.0);
90        double a4 = real(-1.0);
91        double a5 = real(1.5);
92        double a6 = real(1234567876543210.0);
93
94        LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, 0.0, 0.0);
95        LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, -0.0, 0.0);
96        LOLUNIT_ASSERT_DOUBLES_EQUAL(a3, 1.0, 0.0);
97        LOLUNIT_ASSERT_DOUBLES_EQUAL(a4, -1.0, 0.0);
98        LOLUNIT_ASSERT_DOUBLES_EQUAL(a5, 1.5, 0.0);
99        LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 1234567876543210.0, 0.0);
100    }
101
102    LOLUNIT_TEST(UnaryMinus)
103    {
104        float a1 = - real(1.0f);
105        float a2 = - real(-1.0f);
106        float a3 = - real(0.0f);
107        float a4 = - real(-0.0f);
108
109        LOLUNIT_ASSERT_EQUAL(a1, -1.0f);
110        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
111        LOLUNIT_ASSERT_EQUAL(a3, -0.0f);
112        LOLUNIT_ASSERT_EQUAL(a4, 0.0f);
113    }
114
115    LOLUNIT_TEST(Comparison)
116    {
117        LOLUNIT_ASSERT(real(1.0f) > real(0.5f));
118        LOLUNIT_ASSERT(real(1.0f) >= real(0.5f));
119        LOLUNIT_ASSERT(real(1.0f) >= real(1.0f));
120
121        LOLUNIT_ASSERT(real(-1.0f) < real(-0.5f));
122        LOLUNIT_ASSERT(real(-1.0f) <= real(-0.5f));
123        LOLUNIT_ASSERT(real(-1.0f) <= real(-1.0f));
124
125        LOLUNIT_ASSERT(real(-1.0f) < real(0.5f));
126        LOLUNIT_ASSERT(real(-0.5f) < real(1.0f));
127        LOLUNIT_ASSERT(real(-1.0f) <= real(0.5f));
128        LOLUNIT_ASSERT(real(-0.5f) <= real(1.0f));
129
130        LOLUNIT_ASSERT(real(1.0f) > real(-0.5f));
131        LOLUNIT_ASSERT(real(0.5f) > real(-1.0f));
132        LOLUNIT_ASSERT(real(1.0f) >= real(-0.5f));
133        LOLUNIT_ASSERT(real(0.5f) >= real(-1.0f));
134    }
135
136    LOLUNIT_TEST(Addition)
137    {
138        float a1 = real(1.0f) + real(0.0f);
139        float a2 = real(0.0f) + real(1.0f);
140        float a3 = real(1.0f) + real(1.0f);
141        float a4 = real(-1.0f) + real(-1.0f);
142        float a5 = real(1.0f) + real(0.125f);
143        double a6 = real(3.13609818956293918)
144                  + real(0.00005972154828114);
145        float a7 = real(1.0f) + real(-0.125f);
146        double a8 = real(0.10000000002) + real(-2.0e-11);
147
148        LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
149        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
150        LOLUNIT_ASSERT_EQUAL(a3, 2.0f);
151        LOLUNIT_ASSERT_EQUAL(a4, -2.0f);
152        LOLUNIT_ASSERT_EQUAL(a5, 1.125f);
153        LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 3.1361579, 0.000001);
154        LOLUNIT_ASSERT_EQUAL(a7, 0.875f);
155        LOLUNIT_ASSERT_DOUBLES_EQUAL(a8, 0.1, 1.0e-13);
156    }
157
158    LOLUNIT_TEST(Subtraction)
159    {
160        float a1 = real(1.0f) + real(1e20f) - real(1e20f);
161
162        LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
163    }
164
165    LOLUNIT_TEST(Multiplication)
166    {
167        real x(1.25f);
168        real y(1.5f);
169        real z(1.99999f);
170        real w(-1.5f);
171
172        float m1 = x * x;
173        float m2 = y * y;
174        float m3 = z * z;
175        float m4 = w * w;
176
177        LOLUNIT_ASSERT_EQUAL(m1, 1.25f * 1.25f);
178        LOLUNIT_ASSERT_EQUAL(m2, 1.5f * 1.5f);
179        LOLUNIT_ASSERT_EQUAL(m3, 1.99999f * 1.99999f);
180        LOLUNIT_ASSERT_EQUAL(m4, -1.5f * -1.5f);
181    }
182
183    LOLUNIT_TEST(ExactDivision)
184    {
185        float m1 = real::R_1 / real::R_1;
186        float m2 = real::R_2 / real::R_1;
187        float m3 = real::R_1 / real::R_2;
188        float m4 = real::R_2 / real::R_2;
189        float m5 = real::R_1 / -real::R_2;
190
191        LOLUNIT_ASSERT_EQUAL(m1, 1.0f);
192        LOLUNIT_ASSERT_EQUAL(m2, 2.0f);
193        LOLUNIT_ASSERT_EQUAL(m3, 0.5f);
194        LOLUNIT_ASSERT_EQUAL(m4, 1.0f);
195        LOLUNIT_ASSERT_EQUAL(m5, -0.5f);
196    }
197
198    LOLUNIT_TEST(InexactDivision)
199    {
200        /* 1 / 3 * 3 should be close to 1... check that it does not differ
201         * by more than 2^-k where k is the number of bits in the mantissa. */
202        real a = real::R_1 / real::R_3 * real::R_3;
203        real b = (real::R_1 - a) << (real::BIGITS * real::BIGIT_BITS);
204
205        LOLUNIT_ASSERT_LEQUAL((double)fabs(b), 1.0);
206    }
207
208    LOLUNIT_TEST(Shift)
209    {
210        real a1(1.5);
211        real a2(-1.5);
212        real a3(0.0);
213
214        LOLUNIT_ASSERT_EQUAL((double)(a1 >> 7), 0.01171875);
215        LOLUNIT_ASSERT_EQUAL((double)(a1 >> -7), 192.0);
216        LOLUNIT_ASSERT_EQUAL((double)(a1 << 7), 192.0);
217        LOLUNIT_ASSERT_EQUAL((double)(a1 << -7), 0.01171875);
218
219        LOLUNIT_ASSERT_EQUAL((double)(a2 >> 7), -0.01171875);
220        LOLUNIT_ASSERT_EQUAL((double)(a2 >> -7), -192.0);
221        LOLUNIT_ASSERT_EQUAL((double)(a2 << 7), -192.0);
222        LOLUNIT_ASSERT_EQUAL((double)(a2 << -7), -0.01171875);
223
224        LOLUNIT_ASSERT_EQUAL((double)(a3 >> 7), 0.0);
225        LOLUNIT_ASSERT_EQUAL((double)(a3 >> -7), 0.0);
226        LOLUNIT_ASSERT_EQUAL((double)(a3 << 7), 0.0);
227        LOLUNIT_ASSERT_EQUAL((double)(a3 << -7), 0.0);
228    }
229
230    LOLUNIT_TEST(Bool)
231    {
232        real a = 0.0;
233        LOLUNIT_ASSERT(!a);
234
235        a = -0.0;
236        LOLUNIT_ASSERT(!a);
237
238        a = 1234.0;
239        LOLUNIT_ASSERT(a);
240        LOLUNIT_ASSERT(!!a);
241
242        a = -1234.0;
243        LOLUNIT_ASSERT(a);
244        LOLUNIT_ASSERT(!!a);
245    }
246
247    LOLUNIT_TEST(AsinAcos)
248    {
249        double tests[] =
250        {
251            -1024.0, -1023.0, -513.0, -512.0, -511.0, -1.0, -0.0,
252            0.0, 1.0, 511.0, 512.0, 513.0, 1023.0, 1024.0
253        };
254
255        for (unsigned int n = 0; n < sizeof(tests) / sizeof(*tests); n++)
256        {
257            double a = tests[n] / 1024;
258            double b = sin(asin((real)a));
259            double c = cos(acos((real)a));
260
261            LOLUNIT_SET_CONTEXT(a);
262            LOLUNIT_ASSERT_DOUBLES_EQUAL(b, a, 1e-100);
263            LOLUNIT_ASSERT_DOUBLES_EQUAL(c, a, 1e-100);
264        }
265    }
266
267    LOLUNIT_TEST(FloorCeilEtc)
268    {
269        double tests[] =
270        {
271            -2.0,  -2.0, -2.0,  -2.0,
272            -1.5,  -2.0, -1.0,  -2.0,
273            -1.0,  -1.0, -1.0,  -1.0,
274            -0.0,  -0.0, -0.0,  -0.0,
275             0.0,   0.0,  0.0,   0.0,
276             0.25,  0.0,  1.0,   0.0,
277             0.375, 0.0,  1.0,   0.0,
278             0.5,   0.0,  1.0,   1.0,
279             1.0,   1.0,  1.0,   1.0,
280             1.5,   1.0,  2.0,   2.0,
281             2.0,   2.0,  2.0,   2.0,
282             2.5,   2.0,  3.0,   3.0,
283             3.0,   3.0,  3.0,   3.0,
284            8192.0,     8192.0, 8192.0, 8192.0,
285            8192.03125, 8192.0, 8193.0, 8192.0,
286            8192.5,     8192.0, 8193.0, 8193.0,
287            8193.0,     8193.0, 8193.0, 8193.0,
288            549755813888.0,     549755813888.0, 549755813888.0, 549755813888.0,
289            549755813888.03125, 549755813888.0, 549755813889.0, 549755813888.0,
290            549755813888.5,     549755813888.0, 549755813889.0, 549755813889.0,
291            549755813889.0,     549755813889.0, 549755813889.0, 549755813889.0,
292        };
293
294        for (unsigned int n = 0; n < sizeof(tests) / sizeof(*tests); n += 4)
295        {
296            double a0 = floor((real)tests[n]);
297            double b0 = tests[n + 1];
298            double a1 = ceil((real)tests[n]);
299            double b1 = tests[n + 2];
300            double a2 = round((real)tests[n]);
301            double b2 = tests[n + 3];
302
303            LOLUNIT_ASSERT_EQUAL(b0, a0);
304            LOLUNIT_ASSERT_EQUAL(b1, a1);
305            LOLUNIT_ASSERT_EQUAL(b2, a2);
306        }
307    }
308};
309
310} /* namespace lol */
311
Note: See TracBrowser for help on using the repository browser.