Line | Branch | Exec | Source |
---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////// | ||
2 | // | ||
3 | // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas | ||
4 | // Digital Ltd. LLC | ||
5 | // | ||
6 | // All rights reserved. | ||
7 | // | ||
8 | // Redistribution and use in source and binary forms, with or without | ||
9 | // modification, are permitted provided that the following conditions are | ||
10 | // met: | ||
11 | // * Redistributions of source code must retain the above copyright | ||
12 | // notice, this list of conditions and the following disclaimer. | ||
13 | // * Redistributions in binary form must reproduce the above | ||
14 | // copyright notice, this list of conditions and the following disclaimer | ||
15 | // in the documentation and/or other materials provided with the | ||
16 | // distribution. | ||
17 | // * Neither the name of Industrial Light & Magic nor the names of | ||
18 | // its contributors may be used to endorse or promote products derived | ||
19 | // from this software without specific prior written permission. | ||
20 | // | ||
21 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
22 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
23 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
24 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
25 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
26 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
27 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
28 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
29 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
31 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | // | ||
33 | /////////////////////////////////////////////////////////////////////////// | ||
34 | |||
35 | // Primary authors: | ||
36 | // Florian Kainz <kainz@ilm.com> | ||
37 | // Rod Bogart <rgb@ilm.com> | ||
38 | |||
39 | //--------------------------------------------------------------------------- | ||
40 | // | ||
41 | // half -- a 16-bit floating point number class: | ||
42 | // | ||
43 | // Type half can represent positive and negative numbers whose | ||
44 | // magnitude is between roughly 6.1e-5 and 6.5e+4 with a relative | ||
45 | // error of 9.8e-4; numbers smaller than 6.1e-5 can be represented | ||
46 | // with an absolute error of 6.0e-8. All integers from -2048 to | ||
47 | // +2048 can be represented exactly. | ||
48 | // | ||
49 | // Type half behaves (almost) like the built-in C++ floating point | ||
50 | // types. In arithmetic expressions, half, float and double can be | ||
51 | // mixed freely. Here are a few examples: | ||
52 | // | ||
53 | // half a (3.5); | ||
54 | // float b (a + sqrt (a)); | ||
55 | // a += b; | ||
56 | // b += a; | ||
57 | // b = a + 7; | ||
58 | // | ||
59 | // Conversions from half to float are lossless; all half numbers | ||
60 | // are exactly representable as floats. | ||
61 | // | ||
62 | // Conversions from float to half may not preserve a float's value | ||
63 | // exactly. If a float is not representable as a half, then the | ||
64 | // float value is rounded to the nearest representable half. If a | ||
65 | // float value is exactly in the middle between the two closest | ||
66 | // representable half values, then the float value is rounded to | ||
67 | // the closest half whose least significant bit is zero. | ||
68 | // | ||
69 | // Overflows during float-to-half conversions cause arithmetic | ||
70 | // exceptions. An overflow occurs when the float value to be | ||
71 | // converted is too large to be represented as a half, or if the | ||
72 | // float value is an infinity or a NAN. | ||
73 | // | ||
74 | // The implementation of type half makes the following assumptions | ||
75 | // about the implementation of the built-in C++ types: | ||
76 | // | ||
77 | // float is an IEEE 754 single-precision number | ||
78 | // sizeof (float) == 4 | ||
79 | // sizeof (unsigned int) == sizeof (float) | ||
80 | // alignof (unsigned int) == alignof (float) | ||
81 | // sizeof (unsigned short) == 2 | ||
82 | // | ||
83 | //--------------------------------------------------------------------------- | ||
84 | |||
85 | #ifndef OPENVDB_MATH_HALF_HAS_BEEN_INCLUDED | ||
86 | #define OPENVDB_MATH_HALF_HAS_BEEN_INCLUDED | ||
87 | |||
88 | #include <openvdb/Platform.h> | ||
89 | #include <openvdb/version.h> | ||
90 | #include <iostream> | ||
91 | |||
92 | namespace openvdb { | ||
93 | OPENVDB_USE_VERSION_NAMESPACE | ||
94 | namespace OPENVDB_VERSION_NAME { | ||
95 | namespace math { | ||
96 | namespace internal { | ||
97 | |||
98 | class OPENVDB_API half | ||
99 | { | ||
100 | public: | ||
101 | |||
102 | //------------- | ||
103 | // Constructors | ||
104 | //------------- | ||
105 | |||
106 | half () = default; // no initialization | ||
107 | half (float f); | ||
108 | // rule of 5 | ||
109 | ~half () = default; | ||
110 | half (const half &) = default; | ||
111 | half (half &&) noexcept = default; | ||
112 | |||
113 | //-------------------- | ||
114 | // Conversion to float | ||
115 | //-------------------- | ||
116 | |||
117 | operator float () const; | ||
118 | |||
119 | |||
120 | //------------ | ||
121 | // Unary minus | ||
122 | //------------ | ||
123 | |||
124 | half operator - () const; | ||
125 | |||
126 | |||
127 | //----------- | ||
128 | // Assignment | ||
129 | //----------- | ||
130 | |||
131 | half & operator = (const half &h) = default; | ||
132 | half & operator = (half &&h) noexcept = default; | ||
133 | half & operator = (float f); | ||
134 | |||
135 | half & operator += (half h); | ||
136 | half & operator += (float f); | ||
137 | |||
138 | half & operator -= (half h); | ||
139 | half & operator -= (float f); | ||
140 | |||
141 | half & operator *= (half h); | ||
142 | half & operator *= (float f); | ||
143 | |||
144 | half & operator /= (half h); | ||
145 | half & operator /= (float f); | ||
146 | |||
147 | |||
148 | //--------------------------------------------------------- | ||
149 | // Round to n-bit precision (n should be between 0 and 10). | ||
150 | // After rounding, the significand's 10-n least significant | ||
151 | // bits will be zero. | ||
152 | //--------------------------------------------------------- | ||
153 | |||
154 | half round (unsigned int n) const; | ||
155 | |||
156 | |||
157 | //-------------------------------------------------------------------- | ||
158 | // Classification: | ||
159 | // | ||
160 | // h.isFinite() returns true if h is a normalized number, | ||
161 | // a denormalized number or zero | ||
162 | // | ||
163 | // h.isNormalized() returns true if h is a normalized number | ||
164 | // | ||
165 | // h.isDenormalized() returns true if h is a denormalized number | ||
166 | // | ||
167 | // h.isZero() returns true if h is zero | ||
168 | // | ||
169 | // h.isNan() returns true if h is a NAN | ||
170 | // | ||
171 | // h.isInfinity() returns true if h is a positive | ||
172 | // or a negative infinity | ||
173 | // | ||
174 | // h.isNegative() returns true if the sign bit of h | ||
175 | // is set (negative) | ||
176 | //-------------------------------------------------------------------- | ||
177 | |||
178 | bool isFinite () const; | ||
179 | bool isNormalized () const; | ||
180 | bool isDenormalized () const; | ||
181 | bool isZero () const; | ||
182 | bool isNan () const; | ||
183 | bool isInfinity () const; | ||
184 | bool isNegative () const; | ||
185 | |||
186 | |||
187 | //-------------------------------------------- | ||
188 | // Special values | ||
189 | // | ||
190 | // posInf() returns +infinity | ||
191 | // | ||
192 | // negInf() returns -infinity | ||
193 | // | ||
194 | // qNan() returns a NAN with the bit | ||
195 | // pattern 0111111111111111 | ||
196 | // | ||
197 | // sNan() returns a NAN with the bit | ||
198 | // pattern 0111110111111111 | ||
199 | //-------------------------------------------- | ||
200 | |||
201 | static half posInf (); | ||
202 | static half negInf (); | ||
203 | static half qNan (); | ||
204 | static half sNan (); | ||
205 | |||
206 | |||
207 | //-------------------------------------- | ||
208 | // Access to the internal representation | ||
209 | //-------------------------------------- | ||
210 | |||
211 | unsigned short bits () const; | ||
212 | void setBits (unsigned short bits); | ||
213 | |||
214 | |||
215 | public: | ||
216 | |||
217 | union uif | ||
218 | { | ||
219 | unsigned int i; | ||
220 | float f; | ||
221 | }; | ||
222 | |||
223 | private: | ||
224 | |||
225 | static short convert (int i); | ||
226 | static float overflow (); | ||
227 | |||
228 | unsigned short _h; | ||
229 | |||
230 | static const uif _toFloat[1 << 16]; | ||
231 | static const unsigned short _eLut[1 << 9]; | ||
232 | }; | ||
233 | |||
234 | |||
235 | |||
236 | //----------- | ||
237 | // Stream I/O | ||
238 | //----------- | ||
239 | |||
240 | OPENVDB_API std::ostream & operator << (std::ostream &os, half h); | ||
241 | OPENVDB_API std::istream & operator >> (std::istream &is, half &h); | ||
242 | |||
243 | |||
244 | //---------- | ||
245 | // Debugging | ||
246 | //---------- | ||
247 | |||
248 | OPENVDB_API void printBits (std::ostream &os, half h); | ||
249 | OPENVDB_API void printBits (std::ostream &os, float f); | ||
250 | OPENVDB_API void printBits (char c[19], half h); | ||
251 | OPENVDB_API void printBits (char c[35], float f); | ||
252 | |||
253 | |||
254 | //------------------------------------------------------------------------- | ||
255 | // Limits | ||
256 | // | ||
257 | // Visual C++ will complain if HALF_MIN, HALF_NRM_MIN etc. are not float | ||
258 | // constants, but at least one other compiler (gcc 2.96) produces incorrect | ||
259 | // results if they are. | ||
260 | //------------------------------------------------------------------------- | ||
261 | |||
262 | #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER | ||
263 | |||
264 | #define VDB_HALF_MIN 5.96046448e-08f // Smallest positive half | ||
265 | |||
266 | #define VDB_HALF_NRM_MIN 6.10351562e-05f // Smallest positive normalized half | ||
267 | |||
268 | #define VDB_HALF_MAX 65504.0f // Largest positive half | ||
269 | |||
270 | #define VDB_HALF_EPSILON 0.00097656f // Smallest positive e for which | ||
271 | // half (1.0 + e) != half (1.0) | ||
272 | #else | ||
273 | |||
274 | #define VDB_HALF_MIN 5.96046448e-08 // Smallest positive half | ||
275 | |||
276 | #define VDB_HALF_NRM_MIN 6.10351562e-05 // Smallest positive normalized half | ||
277 | |||
278 | #define VDB_HALF_MAX 65504.0 // Largest positive half | ||
279 | |||
280 | #define VDB_HALF_EPSILON 0.00097656 // Smallest positive e for which | ||
281 | // half (1.0 + e) != half (1.0) | ||
282 | #endif | ||
283 | |||
284 | |||
285 | #define VDB_HALF_MANT_DIG 11 // Number of digits in mantissa | ||
286 | // (significand + hidden leading 1) | ||
287 | |||
288 | // | ||
289 | // floor( (VDB_HALF_MANT_DIG - 1) * log10(2) ) => 3.01... -> 3 | ||
290 | #define VDB_HALF_DIG 3 // Number of base 10 digits that | ||
291 | // can be represented without change | ||
292 | |||
293 | // ceil(VDB_HALF_MANT_DIG * log10(2) + 1) => 4.31... -> 5 | ||
294 | #define VDB_HALF_DECIMAL_DIG 5 // Number of base-10 digits that are | ||
295 | // necessary to uniquely represent all | ||
296 | // distinct values | ||
297 | |||
298 | #define VDB_HALF_RADIX 2 // Base of the exponent | ||
299 | |||
300 | #define VDB_HALF_MIN_EXP -13 // Minimum negative integer such that | ||
301 | // HALF_RADIX raised to the power of | ||
302 | // one less than that integer is a | ||
303 | // normalized half | ||
304 | |||
305 | #define VDB_HALF_MAX_EXP 16 // Maximum positive integer such that | ||
306 | // HALF_RADIX raised to the power of | ||
307 | // one less than that integer is a | ||
308 | // normalized half | ||
309 | |||
310 | #define VDB_HALF_MIN_10_EXP -4 // Minimum positive integer such | ||
311 | // that 10 raised to that power is | ||
312 | // a normalized half | ||
313 | |||
314 | #define VDB_HALF_MAX_10_EXP 4 // Maximum positive integer such | ||
315 | // that 10 raised to that power is | ||
316 | // a normalized half | ||
317 | |||
318 | |||
319 | //--------------------------------------------------------------------------- | ||
320 | // | ||
321 | // Implementation -- | ||
322 | // | ||
323 | // Representation of a float: | ||
324 | // | ||
325 | // We assume that a float, f, is an IEEE 754 single-precision | ||
326 | // floating point number, whose bits are arranged as follows: | ||
327 | // | ||
328 | // 31 (msb) | ||
329 | // | | ||
330 | // | 30 23 | ||
331 | // | | | | ||
332 | // | | | 22 0 (lsb) | ||
333 | // | | | | | | ||
334 | // X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX | ||
335 | // | ||
336 | // s e m | ||
337 | // | ||
338 | // S is the sign-bit, e is the exponent and m is the significand. | ||
339 | // | ||
340 | // If e is between 1 and 254, f is a normalized number: | ||
341 | // | ||
342 | // s e-127 | ||
343 | // f = (-1) * 2 * 1.m | ||
344 | // | ||
345 | // If e is 0, and m is not zero, f is a denormalized number: | ||
346 | // | ||
347 | // s -126 | ||
348 | // f = (-1) * 2 * 0.m | ||
349 | // | ||
350 | // If e and m are both zero, f is zero: | ||
351 | // | ||
352 | // f = 0.0 | ||
353 | // | ||
354 | // If e is 255, f is an "infinity" or "not a number" (NAN), | ||
355 | // depending on whether m is zero or not. | ||
356 | // | ||
357 | // Examples: | ||
358 | // | ||
359 | // 0 00000000 00000000000000000000000 = 0.0 | ||
360 | // 0 01111110 00000000000000000000000 = 0.5 | ||
361 | // 0 01111111 00000000000000000000000 = 1.0 | ||
362 | // 0 10000000 00000000000000000000000 = 2.0 | ||
363 | // 0 10000000 10000000000000000000000 = 3.0 | ||
364 | // 1 10000101 11110000010000000000000 = -124.0625 | ||
365 | // 0 11111111 00000000000000000000000 = +infinity | ||
366 | // 1 11111111 00000000000000000000000 = -infinity | ||
367 | // 0 11111111 10000000000000000000000 = NAN | ||
368 | // 1 11111111 11111111111111111111111 = NAN | ||
369 | // | ||
370 | // Representation of a half: | ||
371 | // | ||
372 | // Here is the bit-layout for a half number, h: | ||
373 | // | ||
374 | // 15 (msb) | ||
375 | // | | ||
376 | // | 14 10 | ||
377 | // | | | | ||
378 | // | | | 9 0 (lsb) | ||
379 | // | | | | | | ||
380 | // X XXXXX XXXXXXXXXX | ||
381 | // | ||
382 | // s e m | ||
383 | // | ||
384 | // S is the sign-bit, e is the exponent and m is the significand. | ||
385 | // | ||
386 | // If e is between 1 and 30, h is a normalized number: | ||
387 | // | ||
388 | // s e-15 | ||
389 | // h = (-1) * 2 * 1.m | ||
390 | // | ||
391 | // If e is 0, and m is not zero, h is a denormalized number: | ||
392 | // | ||
393 | // S -14 | ||
394 | // h = (-1) * 2 * 0.m | ||
395 | // | ||
396 | // If e and m are both zero, h is zero: | ||
397 | // | ||
398 | // h = 0.0 | ||
399 | // | ||
400 | // If e is 31, h is an "infinity" or "not a number" (NAN), | ||
401 | // depending on whether m is zero or not. | ||
402 | // | ||
403 | // Examples: | ||
404 | // | ||
405 | // 0 00000 0000000000 = 0.0 | ||
406 | // 0 01110 0000000000 = 0.5 | ||
407 | // 0 01111 0000000000 = 1.0 | ||
408 | // 0 10000 0000000000 = 2.0 | ||
409 | // 0 10000 1000000000 = 3.0 | ||
410 | // 1 10101 1111000001 = -124.0625 | ||
411 | // 0 11111 0000000000 = +infinity | ||
412 | // 1 11111 0000000000 = -infinity | ||
413 | // 0 11111 1000000000 = NAN | ||
414 | // 1 11111 1111111111 = NAN | ||
415 | // | ||
416 | // Conversion: | ||
417 | // | ||
418 | // Converting from a float to a half requires some non-trivial bit | ||
419 | // manipulations. In some cases, this makes conversion relatively | ||
420 | // slow, but the most common case is accelerated via table lookups. | ||
421 | // | ||
422 | // Converting back from a half to a float is easier because we don't | ||
423 | // have to do any rounding. In addition, there are only 65536 | ||
424 | // different half numbers; we can convert each of those numbers once | ||
425 | // and store the results in a table. Later, all conversions can be | ||
426 | // done using only simple table lookups. | ||
427 | // | ||
428 | //--------------------------------------------------------------------------- | ||
429 | |||
430 | |||
431 | //---------------------------- | ||
432 | // Half-from-float constructor | ||
433 | //---------------------------- | ||
434 | |||
435 | inline | ||
436 | 6676871 | half::half (float f) | |
437 | { | ||
438 | uif x; | ||
439 | |||
440 | x.f = f; | ||
441 | |||
442 |
2/2✓ Branch 0 taken 11629 times.
✓ Branch 1 taken 6665217 times.
|
6676846 | if (f == 0) |
443 | { | ||
444 | // | ||
445 | // Common special case - zero. | ||
446 | // Preserve the zero's sign bit. | ||
447 | // | ||
448 | |||
449 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
11632 | _h = (unsigned short)(x.i >> 16); |
450 | } | ||
451 | else | ||
452 | { | ||
453 | // | ||
454 | // We extract the combined sign and exponent, e, from our | ||
455 | // floating-point number, f. Then we convert e to the sign | ||
456 | // and exponent of the half number via a table lookup. | ||
457 | // | ||
458 | // For the most common case, where a normalized half is produced, | ||
459 | // the table lookup returns a non-zero value; in this case, all | ||
460 | // we have to do is round f's significand to 10 bits and combine | ||
461 | // the result with e. | ||
462 | // | ||
463 | // For all other cases (overflow, zeroes, denormalized numbers | ||
464 | // resulting from underflow, infinities and NANs), the table | ||
465 | // lookup returns zero, and we call a longer, non-inline function | ||
466 | // to do the float-to-half conversion. | ||
467 | // | ||
468 | |||
469 | 6665217 | int e = (x.i >> 23) & 0x000001ff; | |
470 | |||
471 | 6665236 | e = _eLut[e]; | |
472 | |||
473 |
18/26✓ Branch 0 taken 6665196 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 13 times.
✓ Branch 17 taken 10 times.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
|
6665238 | if (e) |
474 | { | ||
475 | // | ||
476 | // Simple case - round the significand, m, to 10 | ||
477 | // bits and combine it with the sign and exponent. | ||
478 | // | ||
479 | |||
480 | 6665207 | int m = x.i & 0x007fffff; | |
481 | 6665218 | _h = (unsigned short)(e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13)); | |
482 | } | ||
483 | else | ||
484 | { | ||
485 | // | ||
486 | // Difficult case - call a function. | ||
487 | // | ||
488 | |||
489 |
8/26✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
|
20 | _h = convert (x.i); |
490 | } | ||
491 | } | ||
492 | 6676846 | } | |
493 | |||
494 | |||
495 | //------------------------------------------ | ||
496 | // Half-to-float conversion via table lookup | ||
497 | //------------------------------------------ | ||
498 | |||
499 | inline | ||
500 | half::operator float () const | ||
501 | { | ||
502 |
19/32✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 25 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
|
524347 | return _toFloat[_h].f; |
503 | } | ||
504 | |||
505 | |||
506 | //------------------------- | ||
507 | // Round to n-bit precision | ||
508 | //------------------------- | ||
509 | |||
510 | inline half | ||
511 | half::round (unsigned int n) const | ||
512 | { | ||
513 | // | ||
514 | // Parameter check. | ||
515 | // | ||
516 | |||
517 | if (n >= 10) | ||
518 | return *this; | ||
519 | |||
520 | // | ||
521 | // Disassemble h into the sign, s, | ||
522 | // and the combined exponent and significand, e. | ||
523 | // | ||
524 | |||
525 | unsigned short s = _h & 0x8000; | ||
526 | unsigned short e = _h & 0x7fff; | ||
527 | |||
528 | // | ||
529 | // Round the exponent and significand to the nearest value | ||
530 | // where ones occur only in the (10-n) most significant bits. | ||
531 | // Note that the exponent adjusts automatically if rounding | ||
532 | // up causes the significand to overflow. | ||
533 | // | ||
534 | |||
535 | e = (unsigned short)(e >> (9 - n)); | ||
536 | e = (unsigned short)(e + (e & 1)); | ||
537 | e = (unsigned short)(e << (9 - n)); | ||
538 | |||
539 | // | ||
540 | // Check for exponent overflow. | ||
541 | // | ||
542 | |||
543 | if (e >= 0x7c00) | ||
544 | { | ||
545 | // | ||
546 | // Overflow occurred -- truncate instead of rounding. | ||
547 | // | ||
548 | |||
549 | e = _h; | ||
550 | e = (unsigned short)(e >> (10 - n)); | ||
551 | e = (unsigned short)(e << (10 - n)); | ||
552 | } | ||
553 | |||
554 | // | ||
555 | // Put the original sign bit back. | ||
556 | // | ||
557 | |||
558 | half h; | ||
559 | h._h = (unsigned short)(s | e); | ||
560 | |||
561 | return h; | ||
562 | } | ||
563 | |||
564 | |||
565 | //----------------------- | ||
566 | // Other inline functions | ||
567 | //----------------------- | ||
568 | |||
569 | inline half | ||
570 | half::operator - () const | ||
571 | { | ||
572 | half h; | ||
573 | h._h = _h ^ 0x8000; | ||
574 | return h; | ||
575 | } | ||
576 | |||
577 | |||
578 | inline half & | ||
579 | half::operator = (float f) | ||
580 | { | ||
581 | *this = half (f); | ||
582 | return *this; | ||
583 | } | ||
584 | |||
585 | |||
586 | inline half & | ||
587 | half::operator += (half h) | ||
588 | { | ||
589 | *this = half (float (*this) + float (h)); | ||
590 | return *this; | ||
591 | } | ||
592 | |||
593 | |||
594 | inline half & | ||
595 | half::operator += (float f) | ||
596 | { | ||
597 | *this = half (float (*this) + f); | ||
598 | return *this; | ||
599 | } | ||
600 | |||
601 | |||
602 | inline half & | ||
603 | half::operator -= (half h) | ||
604 | { | ||
605 | *this = half (float (*this) - float (h)); | ||
606 | return *this; | ||
607 | } | ||
608 | |||
609 | |||
610 | inline half & | ||
611 | half::operator -= (float f) | ||
612 | { | ||
613 | *this = half (float (*this) - f); | ||
614 | return *this; | ||
615 | } | ||
616 | |||
617 | |||
618 | inline half & | ||
619 | half::operator *= (half h) | ||
620 | { | ||
621 | *this = half (float (*this) * float (h)); | ||
622 | return *this; | ||
623 | } | ||
624 | |||
625 | |||
626 | inline half & | ||
627 | half::operator *= (float f) | ||
628 | { | ||
629 | *this = half (float (*this) * f); | ||
630 | return *this; | ||
631 | } | ||
632 | |||
633 | |||
634 | inline half & | ||
635 | half::operator /= (half h) | ||
636 | { | ||
637 | *this = half (float (*this) / float (h)); | ||
638 | return *this; | ||
639 | } | ||
640 | |||
641 | |||
642 | inline half & | ||
643 | half::operator /= (float f) | ||
644 | { | ||
645 | *this = half (float (*this) / f); | ||
646 | return *this; | ||
647 | } | ||
648 | |||
649 | |||
650 | inline bool | ||
651 | half::isFinite () const | ||
652 | { | ||
653 | unsigned short e = (_h >> 10) & 0x001f; | ||
654 | return e < 31; | ||
655 | } | ||
656 | |||
657 | |||
658 | inline bool | ||
659 | half::isNormalized () const | ||
660 | { | ||
661 | unsigned short e = (_h >> 10) & 0x001f; | ||
662 | return e > 0 && e < 31; | ||
663 | } | ||
664 | |||
665 | |||
666 | inline bool | ||
667 | half::isDenormalized () const | ||
668 | { | ||
669 | unsigned short e = (_h >> 10) & 0x001f; | ||
670 | unsigned short m = _h & 0x3ff; | ||
671 | return e == 0 && m != 0; | ||
672 | } | ||
673 | |||
674 | |||
675 | inline bool | ||
676 | half::isZero () const | ||
677 | { | ||
678 | return (_h & 0x7fff) == 0; | ||
679 | } | ||
680 | |||
681 | |||
682 | inline bool | ||
683 | half::isNan () const | ||
684 | { | ||
685 | unsigned short e = (_h >> 10) & 0x001f; | ||
686 | unsigned short m = _h & 0x3ff; | ||
687 | return e == 31 && m != 0; | ||
688 | } | ||
689 | |||
690 | |||
691 | inline bool | ||
692 | half::isInfinity () const | ||
693 | { | ||
694 | unsigned short e = (_h >> 10) & 0x001f; | ||
695 | unsigned short m = _h & 0x3ff; | ||
696 | return e == 31 && m == 0; | ||
697 | } | ||
698 | |||
699 | |||
700 | inline bool | ||
701 | half::isNegative () const | ||
702 | { | ||
703 | return (_h & 0x8000) != 0; | ||
704 | } | ||
705 | |||
706 | |||
707 | inline half | ||
708 | half::posInf () | ||
709 | { | ||
710 | half h; | ||
711 | h._h = 0x7c00; | ||
712 | return h; | ||
713 | } | ||
714 | |||
715 | |||
716 | inline half | ||
717 | half::negInf () | ||
718 | { | ||
719 | half h; | ||
720 | h._h = 0xfc00; | ||
721 | return h; | ||
722 | } | ||
723 | |||
724 | |||
725 | inline half | ||
726 | half::qNan () | ||
727 | { | ||
728 | half h; | ||
729 | h._h = 0x7fff; | ||
730 | return h; | ||
731 | } | ||
732 | |||
733 | |||
734 | inline half | ||
735 | half::sNan () | ||
736 | { | ||
737 | half h; | ||
738 | h._h = 0x7dff; | ||
739 | return h; | ||
740 | } | ||
741 | |||
742 | |||
743 | inline unsigned short | ||
744 | half::bits () const | ||
745 | { | ||
746 | ✗ | return _h; | |
747 | } | ||
748 | |||
749 | |||
750 | inline void | ||
751 | half::setBits (unsigned short bits) | ||
752 | { | ||
753 | _h = bits; | ||
754 | } | ||
755 | |||
756 | } // namespace internal | ||
757 | } // namespace math | ||
758 | } // namespace OPENVDB_VERSION_NAME | ||
759 | } // namespace openvdb | ||
760 | |||
761 | #endif // OPENVDB_MATH_HALF_HAS_BEEN_INCLUDED | ||
762 |