1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // mathutil_unittest:
7 // Unit tests for the utils defined in mathutil.h
8 //
9
10 #include "mathutil.h"
11
12 #include <gtest/gtest.h>
13
14 using namespace gl;
15
16 namespace
17 {
18
19 // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions.
20 // For floats f1 and f2, unpackSnorm2x16(packSnorm2x16(f1, f2)) should be same as f1 and f2.
TEST(MathUtilTest,packAndUnpackSnorm2x16)21 TEST(MathUtilTest, packAndUnpackSnorm2x16)
22 {
23 const float input[8][2] = {
24 {0.0f, 0.0f}, {1.0f, 1.0f}, {-1.0f, 1.0f}, {-1.0f, -1.0f},
25 {0.875f, 0.75f}, {0.00392f, -0.99215f}, {-0.000675f, 0.004954f}, {-0.6937f, -0.02146f}};
26 const float floatFaultTolerance = 0.0001f;
27 float outputVal1, outputVal2;
28
29 for (size_t i = 0; i < 8; i++)
30 {
31 unpackSnorm2x16(packSnorm2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2);
32 EXPECT_NEAR(input[i][0], outputVal1, floatFaultTolerance);
33 EXPECT_NEAR(input[i][1], outputVal2, floatFaultTolerance);
34 }
35 }
36
37 // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions with infinity values,
38 // result should be clamped to [-1, 1].
TEST(MathUtilTest,packAndUnpackSnorm2x16Infinity)39 TEST(MathUtilTest, packAndUnpackSnorm2x16Infinity)
40 {
41 const float floatFaultTolerance = 0.0001f;
42 float outputVal1, outputVal2;
43
44 unpackSnorm2x16(packSnorm2x16(std::numeric_limits<float>::infinity(),
45 std::numeric_limits<float>::infinity()),
46 &outputVal1, &outputVal2);
47 EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
48 EXPECT_NEAR(1.0f, outputVal2, floatFaultTolerance);
49
50 unpackSnorm2x16(packSnorm2x16(std::numeric_limits<float>::infinity(),
51 -std::numeric_limits<float>::infinity()),
52 &outputVal1, &outputVal2);
53 EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
54 EXPECT_NEAR(-1.0f, outputVal2, floatFaultTolerance);
55
56 unpackSnorm2x16(packSnorm2x16(-std::numeric_limits<float>::infinity(),
57 -std::numeric_limits<float>::infinity()),
58 &outputVal1, &outputVal2);
59 EXPECT_NEAR(-1.0f, outputVal1, floatFaultTolerance);
60 EXPECT_NEAR(-1.0f, outputVal2, floatFaultTolerance);
61 }
62
63 // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions.
64 // For floats f1 and f2, unpackUnorm2x16(packUnorm2x16(f1, f2)) should be same as f1 and f2.
TEST(MathUtilTest,packAndUnpackUnorm2x16)65 TEST(MathUtilTest, packAndUnpackUnorm2x16)
66 {
67 const float input[8][2] = {
68 {0.0f, 0.0f}, {1.0f, 1.0f}, {-1.0f, 1.0f}, {-1.0f, -1.0f},
69 {0.875f, 0.75f}, {0.00392f, -0.99215f}, {-0.000675f, 0.004954f}, {-0.6937f, -0.02146f}};
70 const float floatFaultTolerance = 0.0001f;
71 float outputVal1, outputVal2;
72
73 for (size_t i = 0; i < 8; i++)
74 {
75 unpackUnorm2x16(packUnorm2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2);
76 float expected = input[i][0] < 0.0f ? 0.0f : input[i][0];
77 EXPECT_NEAR(expected, outputVal1, floatFaultTolerance);
78 expected = input[i][1] < 0.0f ? 0.0f : input[i][1];
79 EXPECT_NEAR(expected, outputVal2, floatFaultTolerance);
80 }
81 }
82
83 // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions with infinity values,
84 // result should be clamped to [0, 1].
TEST(MathUtilTest,packAndUnpackUnorm2x16Infinity)85 TEST(MathUtilTest, packAndUnpackUnorm2x16Infinity)
86 {
87 const float floatFaultTolerance = 0.0001f;
88 float outputVal1, outputVal2;
89
90 unpackUnorm2x16(packUnorm2x16(std::numeric_limits<float>::infinity(),
91 std::numeric_limits<float>::infinity()),
92 &outputVal1, &outputVal2);
93 EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
94 EXPECT_NEAR(1.0f, outputVal2, floatFaultTolerance);
95
96 unpackUnorm2x16(packUnorm2x16(std::numeric_limits<float>::infinity(),
97 -std::numeric_limits<float>::infinity()),
98 &outputVal1, &outputVal2);
99 EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
100 EXPECT_NEAR(0.0f, outputVal2, floatFaultTolerance);
101
102 unpackUnorm2x16(packUnorm2x16(-std::numeric_limits<float>::infinity(),
103 -std::numeric_limits<float>::infinity()),
104 &outputVal1, &outputVal2);
105 EXPECT_NEAR(0.0f, outputVal1, floatFaultTolerance);
106 EXPECT_NEAR(0.0f, outputVal2, floatFaultTolerance);
107 }
108
109 // Test the correctness of packHalf2x16 and unpackHalf2x16 functions.
110 // For floats f1 and f2, unpackHalf2x16(packHalf2x16(f1, f2)) should be same as f1 and f2.
TEST(MathUtilTest,packAndUnpackHalf2x16)111 TEST(MathUtilTest, packAndUnpackHalf2x16)
112 {
113 const float input[8][2] = {
114 {0.0f, 0.0f}, {1.0f, 1.0f}, {-1.0f, 1.0f}, {-1.0f, -1.0f},
115 {0.875f, 0.75f}, {0.00392f, -0.99215f}, {-0.000675f, 0.004954f}, {-0.6937f, -0.02146f},
116 };
117 const float floatFaultTolerance = 0.0005f;
118 float outputVal1, outputVal2;
119
120 for (size_t i = 0; i < 8; i++)
121 {
122 unpackHalf2x16(packHalf2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2);
123 EXPECT_NEAR(input[i][0], outputVal1, floatFaultTolerance);
124 EXPECT_NEAR(input[i][1], outputVal2, floatFaultTolerance);
125 }
126 }
127
128 // Test the correctness of packUnorm4x8 and unpackUnorm4x8 functions.
129 // For floats f1 to f4, unpackUnorm4x8(packUnorm4x8(f1, f2, f3, f4)) should be same as f1 to f4.
TEST(MathUtilTest,packAndUnpackUnorm4x8)130 TEST(MathUtilTest, packAndUnpackUnorm4x8)
131 {
132 const float input[5][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
133 {1.0f, 1.0f, 1.0f, 1.0f},
134 {-1.0f, 1.0f, -1.0f, 1.0f},
135 {-1.0f, -1.0f, -1.0f, -1.0f},
136 {64.0f / 255.0f, 128.0f / 255.0f, 32.0f / 255.0f, 16.0f / 255.0f}};
137
138 const float floatFaultTolerance = 0.005f;
139 float outputVals[4];
140
141 for (size_t i = 0; i < 5; i++)
142 {
143 UnpackUnorm4x8(PackUnorm4x8(input[i][0], input[i][1], input[i][2], input[i][3]),
144 outputVals);
145 for (size_t j = 0; j < 4; j++)
146 {
147 float expected = input[i][j] < 0.0f ? 0.0f : input[i][j];
148 EXPECT_NEAR(expected, outputVals[j], floatFaultTolerance);
149 }
150 }
151 }
152
153 // Test the correctness of packSnorm4x8 and unpackSnorm4x8 functions.
154 // For floats f1 to f4, unpackSnorm4x8(packSnorm4x8(f1, f2, f3, f4)) should be same as f1 to f4.
TEST(MathUtilTest,packAndUnpackSnorm4x8)155 TEST(MathUtilTest, packAndUnpackSnorm4x8)
156 {
157 const float input[5][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
158 {1.0f, 1.0f, 1.0f, 1.0f},
159 {-1.0f, 1.0f, -1.0f, 1.0f},
160 {-1.0f, -1.0f, -1.0f, -1.0f},
161 {64.0f / 127.0f, -8.0f / 127.0f, 32.0f / 127.0f, 16.0f / 127.0f}};
162
163 const float floatFaultTolerance = 0.01f;
164 float outputVals[4];
165
166 for (size_t i = 0; i < 5; i++)
167 {
168 UnpackSnorm4x8(PackSnorm4x8(input[i][0], input[i][1], input[i][2], input[i][3]),
169 outputVals);
170 for (size_t j = 0; j < 4; j++)
171 {
172 float expected = input[i][j];
173 EXPECT_NEAR(expected, outputVals[j], floatFaultTolerance);
174 }
175 }
176 }
177
178 // Test the correctness of gl::isNaN function.
TEST(MathUtilTest,isNaN)179 TEST(MathUtilTest, isNaN)
180 {
181 EXPECT_TRUE(isNaN(bitCast<float>(0xffu << 23 | 1u)));
182 EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 1u)));
183 EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 0x400000u)));
184 EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 0x7fffffu)));
185 EXPECT_FALSE(isNaN(0.0f));
186 EXPECT_FALSE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23)));
187 EXPECT_FALSE(isNaN(bitCast<float>(0xffu << 23)));
188 }
189
190 // Test the correctness of gl::isInf function.
TEST(MathUtilTest,isInf)191 TEST(MathUtilTest, isInf)
192 {
193 EXPECT_TRUE(isInf(bitCast<float>(0xffu << 23)));
194 EXPECT_TRUE(isInf(bitCast<float>(1u << 31 | 0xffu << 23)));
195 EXPECT_FALSE(isInf(0.0f));
196 EXPECT_FALSE(isInf(bitCast<float>(0xffu << 23 | 1u)));
197 EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 1u)));
198 EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x400000u)));
199 EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x7fffffu)));
200 EXPECT_FALSE(isInf(bitCast<float>(0xfeu << 23 | 0x7fffffu)));
201 EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xfeu << 23 | 0x7fffffu)));
202 }
203
TEST(MathUtilTest,CountLeadingZeros)204 TEST(MathUtilTest, CountLeadingZeros)
205 {
206 for (unsigned int i = 0; i < 32u; ++i)
207 {
208 uint32_t iLeadingZeros = 1u << (31u - i);
209 EXPECT_EQ(i, CountLeadingZeros(iLeadingZeros));
210 }
211 EXPECT_EQ(32u, CountLeadingZeros(0));
212 }
213
214 // Some basic tests. Pow2 roundUp test and test that rounding up zero produces zero.
TEST(MathUtilTest,Pow2RoundUp)215 TEST(MathUtilTest, Pow2RoundUp)
216 {
217 EXPECT_EQ(0u, rx::roundUpPow2(0u, 4u));
218 EXPECT_EQ(4u, rx::roundUpPow2(1u, 4u));
219 EXPECT_EQ(4u, rx::roundUpPow2(4u, 4u));
220 }
221
222 // Non-pow2 test.
TEST(MathUtilTest,BasicRoundUp)223 TEST(MathUtilTest, BasicRoundUp)
224 {
225 EXPECT_EQ(0u, rx::roundUp(0u, 5u));
226 EXPECT_EQ(5u, rx::roundUp(1u, 5u));
227 EXPECT_EQ(5u, rx::roundUp(4u, 5u));
228 EXPECT_EQ(5u, rx::roundUp(5u, 5u));
229 }
230
231 // Test that rounding up zero produces zero for checked ints.
TEST(MathUtilTest,CheckedRoundUpZero)232 TEST(MathUtilTest, CheckedRoundUpZero)
233 {
234 auto checkedValue = rx::CheckedRoundUp(0u, 4u);
235 ASSERT_TRUE(checkedValue.IsValid());
236 ASSERT_EQ(0u, checkedValue.ValueOrDie());
237 }
238
239 // Test out-of-bounds with CheckedRoundUp
TEST(MathUtilTest,CheckedRoundUpInvalid)240 TEST(MathUtilTest, CheckedRoundUpInvalid)
241 {
242 // The answer to this query is out of bounds.
243 auto limit = std::numeric_limits<unsigned int>::max();
244 auto checkedValue = rx::CheckedRoundUp(limit, limit - 1);
245 ASSERT_FALSE(checkedValue.IsValid());
246
247 // Our implementation can't handle this query, despite the parameters being in range.
248 auto checkedLimit = rx::CheckedRoundUp(limit - 1, limit);
249 ASSERT_FALSE(checkedLimit.IsValid());
250 }
251
252 // Test BitfieldReverse which reverses the order of the bits in an integer.
TEST(MathUtilTest,BitfieldReverse)253 TEST(MathUtilTest, BitfieldReverse)
254 {
255 EXPECT_EQ(0u, gl::BitfieldReverse(0u));
256 EXPECT_EQ(0x80000000u, gl::BitfieldReverse(1u));
257 EXPECT_EQ(0x1u, gl::BitfieldReverse(0x80000000u));
258 uint32_t bits = (1u << 4u) | (1u << 7u);
259 uint32_t reversed = (1u << (31u - 4u)) | (1u << (31u - 7u));
260 EXPECT_EQ(reversed, gl::BitfieldReverse(bits));
261 }
262
263 // Test BitCount, which counts 1 bits in an integer.
TEST(MathUtilTest,BitCount)264 TEST(MathUtilTest, BitCount)
265 {
266 EXPECT_EQ(0, gl::BitCount(0u));
267 EXPECT_EQ(32, gl::BitCount(0xFFFFFFFFu));
268 EXPECT_EQ(10, gl::BitCount(0x17103121u));
269
270 EXPECT_EQ(0, gl::BitCount(static_cast<uint64_t>(0ull)));
271 EXPECT_EQ(32, gl::BitCount(static_cast<uint64_t>(0xFFFFFFFFull)));
272 EXPECT_EQ(10, gl::BitCount(static_cast<uint64_t>(0x17103121ull)));
273
274 EXPECT_EQ(33, gl::BitCount(static_cast<uint64_t>(0xFFFFFFFF80000000ull)));
275 EXPECT_EQ(11, gl::BitCount(static_cast<uint64_t>(0x1710312180000000ull)));
276 }
277
278 // Test ScanForward, which scans for the least significant 1 bit from a non-zero integer.
TEST(MathUtilTest,ScanForward)279 TEST(MathUtilTest, ScanForward)
280 {
281 EXPECT_EQ(0ul, gl::ScanForward(1u));
282 EXPECT_EQ(16ul, gl::ScanForward(0x80010000u));
283 EXPECT_EQ(31ul, gl::ScanForward(0x80000000u));
284
285 EXPECT_EQ(0ul, gl::ScanForward(static_cast<uint64_t>(1ull)));
286 EXPECT_EQ(16ul, gl::ScanForward(static_cast<uint64_t>(0x80010000ull)));
287 EXPECT_EQ(31ul, gl::ScanForward(static_cast<uint64_t>(0x80000000ull)));
288
289 EXPECT_EQ(32ul, gl::ScanForward(static_cast<uint64_t>(0x100000000ull)));
290 EXPECT_EQ(48ul, gl::ScanForward(static_cast<uint64_t>(0x8001000000000000ull)));
291 EXPECT_EQ(63ul, gl::ScanForward(static_cast<uint64_t>(0x8000000000000000ull)));
292 }
293
294 // Test ScanReverse, which scans for the most significant 1 bit from a non-zero integer.
TEST(MathUtilTest,ScanReverse)295 TEST(MathUtilTest, ScanReverse)
296 {
297 EXPECT_EQ(0ul, gl::ScanReverse(1u));
298 EXPECT_EQ(16ul, gl::ScanReverse(static_cast<uint64_t>(0x00010030ull)));
299 EXPECT_EQ(31ul, gl::ScanReverse(static_cast<uint64_t>(0x80000000ull)));
300
301 EXPECT_EQ(32ul, gl::ScanReverse(static_cast<uint64_t>(0x100000000ull)));
302 EXPECT_EQ(48ul, gl::ScanReverse(static_cast<uint64_t>(0x0001080000000000ull)));
303 EXPECT_EQ(63ul, gl::ScanReverse(static_cast<uint64_t>(0x8000000000000000ull)));
304 }
305
306 // Test FindLSB, which finds the least significant 1 bit.
TEST(MathUtilTest,FindLSB)307 TEST(MathUtilTest, FindLSB)
308 {
309 EXPECT_EQ(-1, gl::FindLSB(0u));
310 EXPECT_EQ(0, gl::FindLSB(1u));
311 EXPECT_EQ(16, gl::FindLSB(0x80010000u));
312 EXPECT_EQ(31, gl::FindLSB(0x80000000u));
313 }
314
315 // Test FindMSB, which finds the most significant 1 bit.
TEST(MathUtilTest,FindMSB)316 TEST(MathUtilTest, FindMSB)
317 {
318 EXPECT_EQ(-1, gl::FindMSB(0u));
319 EXPECT_EQ(0, gl::FindMSB(1u));
320 EXPECT_EQ(16, gl::FindMSB(0x00010030u));
321 EXPECT_EQ(31, gl::FindMSB(0x80000000u));
322 }
323
324 // Test Ldexp, which combines mantissa and exponent into a floating-point number.
TEST(MathUtilTest,Ldexp)325 TEST(MathUtilTest, Ldexp)
326 {
327 EXPECT_EQ(2.5f, Ldexp(0.625f, 2));
328 EXPECT_EQ(-5.0f, Ldexp(-0.625f, 3));
329 EXPECT_EQ(std::numeric_limits<float>::infinity(), Ldexp(0.625f, 129));
330 EXPECT_EQ(0.0f, Ldexp(1.0f, -129));
331 }
332
333 // Test that Range::extend works as expected.
TEST(MathUtilTest,RangeExtend)334 TEST(MathUtilTest, RangeExtend)
335 {
336 RangeI range(0, 0);
337
338 range.extend(5);
339 EXPECT_EQ(0, range.low());
340 EXPECT_EQ(6, range.high());
341 EXPECT_EQ(6, range.length());
342
343 range.extend(-1);
344 EXPECT_EQ(-1, range.low());
345 EXPECT_EQ(6, range.high());
346 EXPECT_EQ(7, range.length());
347
348 range.extend(10);
349 EXPECT_EQ(-1, range.low());
350 EXPECT_EQ(11, range.high());
351 EXPECT_EQ(12, range.length());
352 }
353
354 // Test that Range iteration works as expected.
TEST(MathUtilTest,RangeIteration)355 TEST(MathUtilTest, RangeIteration)
356 {
357 RangeI range(0, 10);
358 int expected = 0;
359 for (int value : range)
360 {
361 EXPECT_EQ(expected, value);
362 expected++;
363 }
364 EXPECT_EQ(range.length(), expected);
365 }
366
367 // Tests for float32 to float16 conversion
TEST(MathUtilTest,Float32ToFloat16)368 TEST(MathUtilTest, Float32ToFloat16)
369 {
370 ASSERT_EQ(float32ToFloat16(0.0f), 0x0000);
371 ASSERT_EQ(float32ToFloat16(-0.0f), 0x8000);
372
373 float inf = std::numeric_limits<float>::infinity();
374
375 ASSERT_EQ(float32ToFloat16(inf), 0x7C00);
376 ASSERT_EQ(float32ToFloat16(-inf), 0xFC00);
377
378 // Check that NaN is converted to a value in one of the float16 NaN ranges
379 float nan = std::numeric_limits<float>::quiet_NaN();
380 uint16_t nan16 = float32ToFloat16(nan);
381 ASSERT_TRUE(nan16 > 0xFC00 || (nan16 < 0x8000 && nan16 > 0x7C00));
382
383 ASSERT_EQ(float32ToFloat16(1.0f), 0x3C00);
384 }
385
386 // Tests the RGB float to 999E5 conversion
TEST(MathUtilTest,convertRGBFloatsTo999E5)387 TEST(MathUtilTest, convertRGBFloatsTo999E5)
388 {
389 const int numTests = 18;
390 const float input[numTests][3] = {// The basics
391 {0.0f, 0.0f, 0.0f},
392 {0.0f, 0.0f, 1.0f},
393 {0.0f, 1.0f, 0.0f},
394 {0.0f, 1.0f, 1.0f},
395 {1.0f, 0.0f, 0.0f},
396 {1.0f, 0.0f, 1.0f},
397 {1.0f, 1.0f, 0.0f},
398 {1.0f, 1.0f, 1.0f},
399 // Extended range
400 {0.0f, 0.0f, 1.5f},
401 {0.0f, 2.0f, 0.0f},
402 {0.0f, 2.5f, 3.0f},
403 {3.5f, 0.0f, 0.0f},
404 {4.0f, 0.0f, 4.5f},
405 {5.0f, 5.5f, 0.0f},
406 {6.0f, 6.5f, 7.0f},
407 // Random
408 {0.1f, 9.6f, 3.2f},
409 {2.0f, 1.7f, 8.6f},
410 {0.7f, 4.2f, 9.1f}};
411 const unsigned int result[numTests] = {// The basics
412 0x00000000, 0x84000000, 0x80020000, 0x84020000,
413 0x80000100, 0x84000100, 0x80020100, 0x84020100,
414 // Extended range
415 0x86000000, 0x88020000, 0x8E028000, 0x880001C0,
416 0x94800100, 0x9002C140, 0x97034180,
417 // Random
418 0x999A6603, 0x9C4C6C40, 0x9C8D0C16};
419
420 for (int i = 0; i < numTests; i++)
421 {
422 EXPECT_EQ(convertRGBFloatsTo999E5(input[i][0], input[i][1], input[i][2]), result[i]);
423 }
424 }
425
426 // Tests the 999E5 to RGB float conversion
TEST(MathUtilTest,convert999E5toRGBFloats)427 TEST(MathUtilTest, convert999E5toRGBFloats)
428 {
429 const int numTests = 18;
430 const float result[numTests][3] = {// The basics
431 {0.0f, 0.0f, 0.0f},
432 {0.0f, 0.0f, 1.0f},
433 {0.0f, 1.0f, 0.0f},
434 {0.0f, 1.0f, 1.0f},
435 {1.0f, 0.0f, 0.0f},
436 {1.0f, 0.0f, 1.0f},
437 {1.0f, 1.0f, 0.0f},
438 {1.0f, 1.0f, 1.0f},
439 // Extended range
440 {0.0f, 0.0f, 1.5f},
441 {0.0f, 2.0f, 0.0f},
442 {0.0f, 2.5f, 3.0f},
443 {3.5f, 0.0f, 0.0f},
444 {4.0f, 0.0f, 4.5f},
445 {5.0f, 5.5f, 0.0f},
446 {6.0f, 6.5f, 7.0f},
447 // Random
448 {0.1f, 9.6f, 3.2f},
449 {2.0f, 1.7f, 8.6f},
450 {0.7f, 4.2f, 9.1f}};
451 const unsigned int input[numTests] = {// The basics
452 0x00000000, 0x84000000, 0x80020000, 0x84020000,
453 0x80000100, 0x84000100, 0x80020100, 0x84020100,
454 // Extended range
455 0x86000000, 0x88020000, 0x8E028000, 0x880001C0,
456 0x94800100, 0x9002C140, 0x97034180,
457 // Random
458 0x999A6603, 0x9C4C6C40, 0x9C8D0C16};
459 // Note: quite a low tolerance is required
460 const float floatFaultTolerance = 0.05f;
461 float outR, outG, outB;
462
463 for (int i = 0; i < numTests; i++)
464 {
465 convert999E5toRGBFloats(input[i], &outR, &outG, &outB);
466 EXPECT_NEAR(result[i][0], outR, floatFaultTolerance);
467 EXPECT_NEAR(result[i][1], outG, floatFaultTolerance);
468 EXPECT_NEAR(result[i][2], outB, floatFaultTolerance);
469 }
470 }
471
472 } // anonymous namespace
473