source: trunk/test/unit/half.cpp @ 969

Last change on this file since 969 was 942, checked in by sam, 11 years ago

test: reorganise test suite and benchmark code.

  • Property svn:keywords set to Id
File size: 8.4 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(HalfTest)
24{
25public:
26    LOLUNIT_TEST(test_half_from_float)
27    {
28        for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
29        {
30            half a = (half)pairs[i].f;
31            uint16_t b = pairs[i].x;
32            LOLUNIT_SET_CONTEXT(i);
33            LOLUNIT_ASSERT_EQUAL(a.bits, b);
34        }
35    }
36
37    LOLUNIT_TEST(test_half_makeaccurate)
38    {
39        for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
40        {
41            half a = half::makeaccurate(pairs[i].f);
42            uint16_t b = pairs[i].x;
43            LOLUNIT_SET_CONTEXT(i);
44            LOLUNIT_ASSERT_EQUAL(a.bits, b);
45        }
46    }
47
48    LOLUNIT_TEST(test_half_makebits)
49    {
50        for (unsigned int i = 0; i < 0x10000; i++)
51        {
52            half a = half::makebits(i);
53            uint16_t b = i;
54            LOLUNIT_SET_CONTEXT(i);
55            LOLUNIT_ASSERT_EQUAL(a.bits, b);
56        }
57    }
58
59    LOLUNIT_TEST(test_half_is_nan)
60    {
61        LOLUNIT_ASSERT(half::makebits(0x7c01).is_nan());
62        LOLUNIT_ASSERT(half::makebits(0xfc01).is_nan());
63        LOLUNIT_ASSERT(half::makebits(0x7e00).is_nan());
64        LOLUNIT_ASSERT(half::makebits(0xfe00).is_nan());
65
66        LOLUNIT_ASSERT(!half::makebits(0x7c00).is_nan());
67        LOLUNIT_ASSERT(!half::makebits(0xfc00).is_nan());
68
69        LOLUNIT_ASSERT(!half(0.0f).is_nan());
70        LOLUNIT_ASSERT(!half(-0.0f).is_nan());
71        LOLUNIT_ASSERT(!half(2.0f).is_nan());
72        LOLUNIT_ASSERT(!half(-2.0f).is_nan());
73    }
74
75    LOLUNIT_TEST(test_half_is_inf)
76    {
77        LOLUNIT_ASSERT(half(65536.0f).is_inf());
78        LOLUNIT_ASSERT(half(-65536.0f).is_inf());
79
80        LOLUNIT_ASSERT(!half(0.0f).is_inf());
81        LOLUNIT_ASSERT(!half(-0.0f).is_inf());
82        LOLUNIT_ASSERT(!half(65535.0f).is_inf());
83        LOLUNIT_ASSERT(!half(-65535.0f).is_inf());
84
85        LOLUNIT_ASSERT(half::makebits(0x7c00).is_inf());
86        LOLUNIT_ASSERT(half::makebits(0xfc00).is_inf());
87
88        LOLUNIT_ASSERT(!half::makebits(0x7e00).is_inf());
89        LOLUNIT_ASSERT(!half::makebits(0xfe00).is_inf());
90    }
91
92    LOLUNIT_TEST(test_half_is_finite)
93    {
94        LOLUNIT_ASSERT(half(0.0f).is_finite());
95        LOLUNIT_ASSERT(half(-0.0f).is_finite());
96        LOLUNIT_ASSERT(half(65535.0f).is_finite());
97        LOLUNIT_ASSERT(half(-65535.0f).is_finite());
98
99        LOLUNIT_ASSERT(!half(65536.0f).is_finite());
100        LOLUNIT_ASSERT(!half(-65536.0f).is_finite());
101
102        LOLUNIT_ASSERT(!half::makebits(0x7c00).is_finite());
103        LOLUNIT_ASSERT(!half::makebits(0xfc00).is_finite());
104
105        LOLUNIT_ASSERT(!half::makebits(0x7e00).is_finite());
106        LOLUNIT_ASSERT(!half::makebits(0xfe00).is_finite());
107    }
108
109    LOLUNIT_TEST(test_half_is_normal)
110    {
111        LOLUNIT_ASSERT(half(0.0f).is_normal());
112        LOLUNIT_ASSERT(half(-0.0f).is_normal());
113        LOLUNIT_ASSERT(half(65535.0f).is_normal());
114        LOLUNIT_ASSERT(half(-65535.0f).is_normal());
115
116        LOLUNIT_ASSERT(!half(65536.0f).is_normal());
117        LOLUNIT_ASSERT(!half(-65536.0f).is_normal());
118
119        LOLUNIT_ASSERT(!half::makebits(0x7c00).is_normal());
120        LOLUNIT_ASSERT(!half::makebits(0xfc00).is_normal());
121
122        LOLUNIT_ASSERT(!half::makebits(0x7e00).is_normal());
123        LOLUNIT_ASSERT(!half::makebits(0xfe00).is_normal());
124    }
125
126    LOLUNIT_TEST(test_half_classify)
127    {
128        for (uint32_t i = 0; i < 0x10000; i++)
129        {
130            LOLUNIT_SET_CONTEXT(i);
131            half h = half::makebits(i);
132            if (h.is_nan())
133            {
134                LOLUNIT_ASSERT(!h.is_inf());
135                LOLUNIT_ASSERT(!h.is_normal());
136                LOLUNIT_ASSERT(!h.is_finite());
137            }
138            else if (h.is_inf())
139            {
140                LOLUNIT_ASSERT(!h.is_normal());
141                LOLUNIT_ASSERT(!h.is_finite());
142            }
143            else
144            {
145                LOLUNIT_ASSERT(h.is_finite());
146            }
147        }
148    }
149
150    LOLUNIT_TEST(test_half_to_float)
151    {
152        for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
153        {
154            float a = (float)half::makebits(pairs[i].x);
155            float b = pairs[i].f;
156            LOLUNIT_SET_CONTEXT(i);
157            LOLUNIT_ASSERT_EQUAL(a, b);
158        }
159
160        for (uint32_t i = 0; i < 0x10000; i++)
161        {
162            half h = half::makebits(i);
163            float f = (float)h;
164            half g = (half)f;
165            LOLUNIT_SET_CONTEXT(i);
166            if (h.is_nan())
167            {
168                LOLUNIT_ASSERT(isnan(f));
169                LOLUNIT_ASSERT(g.is_nan());
170            }
171            else
172            {
173                LOLUNIT_ASSERT(!isnan(f));
174                LOLUNIT_ASSERT_EQUAL(g.bits, h.bits);
175            }
176        }
177    }
178
179    LOLUNIT_TEST(test_half_to_int)
180    {
181        LOLUNIT_ASSERT_EQUAL((int)(half)(0.0f), 0);
182        LOLUNIT_ASSERT_EQUAL((int)(half)(-0.0f), 0);
183        LOLUNIT_ASSERT_EQUAL((int)(half)(0.9f), 0);
184        LOLUNIT_ASSERT_EQUAL((int)(half)(-0.9f), 0);
185        LOLUNIT_ASSERT_EQUAL((int)(half)(1.0f), 1);
186        LOLUNIT_ASSERT_EQUAL((int)(half)(-1.0f), -1);
187        LOLUNIT_ASSERT_EQUAL((int)(half)(1.9f), 1);
188        LOLUNIT_ASSERT_EQUAL((int)(half)(-1.9f), -1);
189        LOLUNIT_ASSERT_EQUAL((int)(half)(65504.0f), 65504);
190        LOLUNIT_ASSERT_EQUAL((int)(half)(-65504.0f), -65504);
191    }
192
193    LOLUNIT_TEST(test_float_op_half)
194    {
195        half zero = 0;
196        half one = 1;
197        half two = 2;
198
199        float a = zero + one;
200        LOLUNIT_ASSERT_EQUAL(1.0f, a);
201        a += zero;
202        LOLUNIT_ASSERT_EQUAL(1.0f, a);
203        a -= zero;
204        LOLUNIT_ASSERT_EQUAL(1.0f, a);
205        a *= one;
206        LOLUNIT_ASSERT_EQUAL(1.0f, a);
207        a /= one;
208        LOLUNIT_ASSERT_EQUAL(1.0f, a);
209
210        float b = one + zero;
211        LOLUNIT_ASSERT_EQUAL(1.0f, b);
212        b += one;
213        LOLUNIT_ASSERT_EQUAL(2.0f, b);
214        b *= two;
215        LOLUNIT_ASSERT_EQUAL(4.0f, b);
216        b -= two;
217        LOLUNIT_ASSERT_EQUAL(2.0f, b);
218        b /= two;
219        LOLUNIT_ASSERT_EQUAL(1.0f, b);
220
221        float c = one - zero;
222        LOLUNIT_ASSERT_EQUAL(1.0f, c);
223
224        float d = two - one;
225        LOLUNIT_ASSERT_EQUAL(1.0f, d);
226
227        float e = two + (-one);
228        LOLUNIT_ASSERT_EQUAL(1.0f, e);
229
230        float f = (two * two) / (one + one);
231        LOLUNIT_ASSERT_EQUAL(2.0f, f);
232    }
233
234    LOLUNIT_TEST(test_half_op_float)
235    {
236        half zero = 0;
237        half one = 1;
238        half two = 2;
239        half four = 4;
240
241        half a = one + 0.0f;
242        LOLUNIT_ASSERT_EQUAL(one.bits, a.bits);
243        a += 0.0f;
244        LOLUNIT_ASSERT_EQUAL(one.bits, a.bits);
245        a -= 0.0f;
246        LOLUNIT_ASSERT_EQUAL(one.bits, a.bits);
247        a *= 1.0f;
248        LOLUNIT_ASSERT_EQUAL(one.bits, a.bits);
249        a /= 1.0f;
250        LOLUNIT_ASSERT_EQUAL(one.bits, a.bits);
251
252        half b = one + 0.0f;
253        LOLUNIT_ASSERT_EQUAL(one.bits, b.bits);
254        b += 1.0f;
255        LOLUNIT_ASSERT_EQUAL(two.bits, b.bits);
256        b *= 2.0f;
257        LOLUNIT_ASSERT_EQUAL(four.bits, b.bits);
258        b -= 2.0f;
259        LOLUNIT_ASSERT_EQUAL(two.bits, b.bits);
260        b /= 2.0f;
261        LOLUNIT_ASSERT_EQUAL(one.bits, b.bits);
262
263        half c = 1.0f - zero;
264        LOLUNIT_ASSERT_EQUAL(one.bits, c.bits);
265
266        half d = 2.0f - one;
267        LOLUNIT_ASSERT_EQUAL(one.bits, d.bits);
268
269        half e = 2.0f + (-one);
270        LOLUNIT_ASSERT_EQUAL(one.bits, e.bits);
271
272        half f = (2.0f * two) / (1.0f + one);
273        LOLUNIT_ASSERT_EQUAL(two.bits, f.bits);
274    }
275
276private:
277    struct TestPair { float f; uint16_t x; };
278
279    static TestPair const pairs[11];
280};
281
282HalfTest::TestPair const HalfTest::pairs[] =
283{
284    /* All these values have exact half representations */
285    { 0.0f,      0x0000 },
286    { -0.0f,     0x8000 }, /* negative zero */
287    { 1.0f,      0x3c00 },
288    { -1.0f,     0xbc00 },
289    { 2.0f,      0x4000 },
290    { 0.5f,      0x3800 },
291    { 0.125f,    0x3000 },
292    { 15.9375f,  0x4bf8 },
293    { 31.0f / (1 << 14), 0x17c0 }, /* 0x1.fp-10 */
294    { 31.0f / (1 << 18), 0x07c0 }, /* 0x1.fp-14, normal float, denormal half */
295    { 31.0f / (1 << 19), 0x03e0 }, /* 0x1.fp-15, normal float, denormal half */
296};
297
298} /* namespace lol */
299
Note: See TracBrowser for help on using the repository browser.