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

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

build: fix the WTFPL site URL in all code comments.

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