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

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

core: allow to build a real number using a string literal.

File size: 10.0 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(StringToReal)
107    {
108        float a1 = real("0");
109        float a2 = real("1");
110        float a3 = real("-1");
111        /* 2^-128 * 2^128 */
112        float a4 = real("0.0000000000000000000000000000000000000029387358770"
113                        "557187699218413430556141945466638919302188037718792"
114                        "6569604314863681793212890625")
115                 * real("340282366920938463463374607431768211456");
116
117        LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
118        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
119        LOLUNIT_ASSERT_EQUAL(a3, -1.0f);
120        LOLUNIT_ASSERT_EQUAL(a4, 1.0f);
121    }
122
123    LOLUNIT_TEST(UnaryMinus)
124    {
125        float a1 = - real(1.0f);
126        float a2 = - real(-1.0f);
127        float a3 = - real(0.0f);
128        float a4 = - real(-0.0f);
129
130        LOLUNIT_ASSERT_EQUAL(a1, -1.0f);
131        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
132        LOLUNIT_ASSERT_EQUAL(a3, -0.0f);
133        LOLUNIT_ASSERT_EQUAL(a4, 0.0f);
134    }
135
136    LOLUNIT_TEST(Comparison)
137    {
138        LOLUNIT_ASSERT(real(1.0f) > real(0.5f));
139        LOLUNIT_ASSERT(real(1.0f) >= real(0.5f));
140        LOLUNIT_ASSERT(real(1.0f) >= real(1.0f));
141
142        LOLUNIT_ASSERT(real(-1.0f) < real(-0.5f));
143        LOLUNIT_ASSERT(real(-1.0f) <= real(-0.5f));
144        LOLUNIT_ASSERT(real(-1.0f) <= real(-1.0f));
145
146        LOLUNIT_ASSERT(real(-1.0f) < real(0.5f));
147        LOLUNIT_ASSERT(real(-0.5f) < real(1.0f));
148        LOLUNIT_ASSERT(real(-1.0f) <= real(0.5f));
149        LOLUNIT_ASSERT(real(-0.5f) <= real(1.0f));
150
151        LOLUNIT_ASSERT(real(1.0f) > real(-0.5f));
152        LOLUNIT_ASSERT(real(0.5f) > real(-1.0f));
153        LOLUNIT_ASSERT(real(1.0f) >= real(-0.5f));
154        LOLUNIT_ASSERT(real(0.5f) >= real(-1.0f));
155    }
156
157    LOLUNIT_TEST(Addition)
158    {
159        float a1 = real(1.0f) + real(0.0f);
160        float a2 = real(0.0f) + real(1.0f);
161        float a3 = real(1.0f) + real(1.0f);
162        float a4 = real(-1.0f) + real(-1.0f);
163        float a5 = real(1.0f) + real(0.125f);
164        double a6 = real(3.13609818956293918)
165                  + real(0.00005972154828114);
166        float a7 = real(1.0f) + real(-0.125f);
167        double a8 = real(0.10000000002) + real(-2.0e-11);
168
169        LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
170        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
171        LOLUNIT_ASSERT_EQUAL(a3, 2.0f);
172        LOLUNIT_ASSERT_EQUAL(a4, -2.0f);
173        LOLUNIT_ASSERT_EQUAL(a5, 1.125f);
174        LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 3.1361579, 0.000001);
175        LOLUNIT_ASSERT_EQUAL(a7, 0.875f);
176        LOLUNIT_ASSERT_DOUBLES_EQUAL(a8, 0.1, 1.0e-13);
177    }
178
179    LOLUNIT_TEST(Subtraction)
180    {
181        float a1 = real(1.0f) + real(1e20f) - real(1e20f);
182
183        LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
184    }
185
186    LOLUNIT_TEST(Multiplication)
187    {
188        real x(1.25f);
189        real y(1.5f);
190        real z(1.99999f);
191        real w(-1.5f);
192
193        float m1 = x * x;
194        float m2 = y * y;
195        float m3 = z * z;
196        float m4 = w * w;
197
198        LOLUNIT_ASSERT_EQUAL(m1, 1.25f * 1.25f);
199        LOLUNIT_ASSERT_EQUAL(m2, 1.5f * 1.5f);
200        LOLUNIT_ASSERT_EQUAL(m3, 1.99999f * 1.99999f);
201        LOLUNIT_ASSERT_EQUAL(m4, -1.5f * -1.5f);
202    }
203
204    LOLUNIT_TEST(ExactDivision)
205    {
206        float m1 = real::R_1 / real::R_1;
207        float m2 = real::R_2 / real::R_1;
208        float m3 = real::R_1 / real::R_2;
209        float m4 = real::R_2 / real::R_2;
210        float m5 = real::R_1 / -real::R_2;
211
212        LOLUNIT_ASSERT_EQUAL(m1, 1.0f);
213        LOLUNIT_ASSERT_EQUAL(m2, 2.0f);
214        LOLUNIT_ASSERT_EQUAL(m3, 0.5f);
215        LOLUNIT_ASSERT_EQUAL(m4, 1.0f);
216        LOLUNIT_ASSERT_EQUAL(m5, -0.5f);
217    }
218
219    LOLUNIT_TEST(InexactDivision)
220    {
221        /* 1 / 3 * 3 should be close to 1... check that it does not differ
222         * by more than 2^-k where k is the number of bits in the mantissa. */
223        real a = real::R_1 / real::R_3 * real::R_3;
224        real b = (real::R_1 - a) << (real::BIGITS * real::BIGIT_BITS);
225
226        LOLUNIT_ASSERT_LEQUAL((double)fabs(b), 1.0);
227    }
228
229    LOLUNIT_TEST(Shift)
230    {
231        real a1(1.5);
232        real a2(-1.5);
233        real a3(0.0);
234
235        LOLUNIT_ASSERT_EQUAL((double)(a1 >> 7), 0.01171875);
236        LOLUNIT_ASSERT_EQUAL((double)(a1 >> -7), 192.0);
237        LOLUNIT_ASSERT_EQUAL((double)(a1 << 7), 192.0);
238        LOLUNIT_ASSERT_EQUAL((double)(a1 << -7), 0.01171875);
239
240        LOLUNIT_ASSERT_EQUAL((double)(a2 >> 7), -0.01171875);
241        LOLUNIT_ASSERT_EQUAL((double)(a2 >> -7), -192.0);
242        LOLUNIT_ASSERT_EQUAL((double)(a2 << 7), -192.0);
243        LOLUNIT_ASSERT_EQUAL((double)(a2 << -7), -0.01171875);
244
245        LOLUNIT_ASSERT_EQUAL((double)(a3 >> 7), 0.0);
246        LOLUNIT_ASSERT_EQUAL((double)(a3 >> -7), 0.0);
247        LOLUNIT_ASSERT_EQUAL((double)(a3 << 7), 0.0);
248        LOLUNIT_ASSERT_EQUAL((double)(a3 << -7), 0.0);
249    }
250
251    LOLUNIT_TEST(Bool)
252    {
253        real a = 0.0;
254        LOLUNIT_ASSERT(!a);
255
256        a = -0.0;
257        LOLUNIT_ASSERT(!a);
258
259        a = 1234.0;
260        LOLUNIT_ASSERT(a);
261        LOLUNIT_ASSERT(!!a);
262
263        a = -1234.0;
264        LOLUNIT_ASSERT(a);
265        LOLUNIT_ASSERT(!!a);
266    }
267
268    LOLUNIT_TEST(AsinAcos)
269    {
270        double tests[] =
271        {
272            -1024.0, -1023.0, -513.0, -512.0, -511.0, -1.0, -0.0,
273            0.0, 1.0, 511.0, 512.0, 513.0, 1023.0, 1024.0
274        };
275
276        for (unsigned int n = 0; n < sizeof(tests) / sizeof(*tests); n++)
277        {
278            double a = tests[n] / 1024;
279            double b = sin(asin((real)a));
280            double c = cos(acos((real)a));
281
282            LOLUNIT_SET_CONTEXT(a);
283            LOLUNIT_ASSERT_DOUBLES_EQUAL(b, a, 1e-100);
284            LOLUNIT_ASSERT_DOUBLES_EQUAL(c, a, 1e-100);
285        }
286    }
287
288    LOLUNIT_TEST(FloorCeilEtc)
289    {
290        double tests[] =
291        {
292            -2.0,  -2.0, -2.0,  -2.0,
293            -1.5,  -2.0, -1.0,  -2.0,
294            -1.0,  -1.0, -1.0,  -1.0,
295            -0.0,  -0.0, -0.0,  -0.0,
296             0.0,   0.0,  0.0,   0.0,
297             0.25,  0.0,  1.0,   0.0,
298             0.375, 0.0,  1.0,   0.0,
299             0.5,   0.0,  1.0,   1.0,
300             1.0,   1.0,  1.0,   1.0,
301             1.5,   1.0,  2.0,   2.0,
302             2.0,   2.0,  2.0,   2.0,
303             2.5,   2.0,  3.0,   3.0,
304             3.0,   3.0,  3.0,   3.0,
305            8192.0,     8192.0, 8192.0, 8192.0,
306            8192.03125, 8192.0, 8193.0, 8192.0,
307            8192.5,     8192.0, 8193.0, 8193.0,
308            8193.0,     8193.0, 8193.0, 8193.0,
309            549755813888.0,     549755813888.0, 549755813888.0, 549755813888.0,
310            549755813888.03125, 549755813888.0, 549755813889.0, 549755813888.0,
311            549755813888.5,     549755813888.0, 549755813889.0, 549755813889.0,
312            549755813889.0,     549755813889.0, 549755813889.0, 549755813889.0,
313        };
314
315        for (unsigned int n = 0; n < sizeof(tests) / sizeof(*tests); n += 4)
316        {
317            double a0 = floor((real)tests[n]);
318            double b0 = tests[n + 1];
319            double a1 = ceil((real)tests[n]);
320            double b1 = tests[n + 2];
321            double a2 = round((real)tests[n]);
322            double b2 = tests[n + 3];
323
324            LOLUNIT_ASSERT_EQUAL(b0, a0);
325            LOLUNIT_ASSERT_EQUAL(b1, a1);
326            LOLUNIT_ASSERT_EQUAL(b2, a2);
327        }
328    }
329};
330
331} /* namespace lol */
332
Note: See TracBrowser for help on using the repository browser.