/src/opencv/3rdparty/openexr/Half/half.h
Line | Count | 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 _HALF_H_ |
86 | | #define _HALF_H_ |
87 | | |
88 | | #include "halfExport.h" // for definition of HALF_EXPORT |
89 | | #include <iostream> |
90 | | |
91 | | class half |
92 | | { |
93 | | public: |
94 | | |
95 | | //------------- |
96 | | // Constructors |
97 | | //------------- |
98 | | |
99 | | half (); // no initialization |
100 | | half (float f); |
101 | | |
102 | | |
103 | | //-------------------- |
104 | | // Conversion to float |
105 | | //-------------------- |
106 | | |
107 | | operator float () const; |
108 | | |
109 | | |
110 | | //------------ |
111 | | // Unary minus |
112 | | //------------ |
113 | | |
114 | | half operator - () const; |
115 | | |
116 | | |
117 | | //----------- |
118 | | // Assignment |
119 | | //----------- |
120 | | |
121 | | half & operator = (half h); |
122 | | half & operator = (float f); |
123 | | |
124 | | half & operator += (half h); |
125 | | half & operator += (float f); |
126 | | |
127 | | half & operator -= (half h); |
128 | | half & operator -= (float f); |
129 | | |
130 | | half & operator *= (half h); |
131 | | half & operator *= (float f); |
132 | | |
133 | | half & operator /= (half h); |
134 | | half & operator /= (float f); |
135 | | |
136 | | |
137 | | //--------------------------------------------------------- |
138 | | // Round to n-bit precision (n should be between 0 and 10). |
139 | | // After rounding, the significand's 10-n least significant |
140 | | // bits will be zero. |
141 | | //--------------------------------------------------------- |
142 | | |
143 | | half round (unsigned int n) const; |
144 | | |
145 | | |
146 | | //-------------------------------------------------------------------- |
147 | | // Classification: |
148 | | // |
149 | | // h.isFinite() returns true if h is a normalized number, |
150 | | // a denormalized number or zero |
151 | | // |
152 | | // h.isNormalized() returns true if h is a normalized number |
153 | | // |
154 | | // h.isDenormalized() returns true if h is a denormalized number |
155 | | // |
156 | | // h.isZero() returns true if h is zero |
157 | | // |
158 | | // h.isNan() returns true if h is a NAN |
159 | | // |
160 | | // h.isInfinity() returns true if h is a positive |
161 | | // or a negative infinity |
162 | | // |
163 | | // h.isNegative() returns true if the sign bit of h |
164 | | // is set (negative) |
165 | | //-------------------------------------------------------------------- |
166 | | |
167 | | bool isFinite () const; |
168 | | bool isNormalized () const; |
169 | | bool isDenormalized () const; |
170 | | bool isZero () const; |
171 | | bool isNan () const; |
172 | | bool isInfinity () const; |
173 | | bool isNegative () const; |
174 | | |
175 | | |
176 | | //-------------------------------------------- |
177 | | // Special values |
178 | | // |
179 | | // posInf() returns +infinity |
180 | | // |
181 | | // negInf() returns -infinity |
182 | | // |
183 | | // qNan() returns a NAN with the bit |
184 | | // pattern 0111111111111111 |
185 | | // |
186 | | // sNan() returns a NAN with the bit |
187 | | // pattern 0111110111111111 |
188 | | //-------------------------------------------- |
189 | | |
190 | | static half posInf (); |
191 | | static half negInf (); |
192 | | static half qNan (); |
193 | | static half sNan (); |
194 | | |
195 | | |
196 | | //-------------------------------------- |
197 | | // Access to the internal representation |
198 | | //-------------------------------------- |
199 | | |
200 | | HALF_EXPORT unsigned short bits () const; |
201 | | HALF_EXPORT void setBits (unsigned short bits); |
202 | | |
203 | | |
204 | | public: |
205 | | |
206 | | union uif |
207 | | { |
208 | | unsigned int i; |
209 | | float f; |
210 | | }; |
211 | | |
212 | | private: |
213 | | |
214 | | HALF_EXPORT static short convert (int i); |
215 | | HALF_EXPORT static float overflow (); |
216 | | |
217 | | unsigned short _h; |
218 | | |
219 | | HALF_EXPORT static const uif _toFloat[1 << 16]; |
220 | | HALF_EXPORT static const unsigned short _eLut[1 << 9]; |
221 | | }; |
222 | | |
223 | | |
224 | | |
225 | | //----------- |
226 | | // Stream I/O |
227 | | //----------- |
228 | | |
229 | | HALF_EXPORT std::ostream & operator << (std::ostream &os, half h); |
230 | | HALF_EXPORT std::istream & operator >> (std::istream &is, half &h); |
231 | | |
232 | | |
233 | | //---------- |
234 | | // Debugging |
235 | | //---------- |
236 | | |
237 | | HALF_EXPORT void printBits (std::ostream &os, half h); |
238 | | HALF_EXPORT void printBits (std::ostream &os, float f); |
239 | | HALF_EXPORT void printBits (char c[19], half h); |
240 | | HALF_EXPORT void printBits (char c[35], float f); |
241 | | |
242 | | |
243 | | //------------------------------------------------------------------------- |
244 | | // Limits |
245 | | // |
246 | | // Visual C++ will complain if HALF_MIN, HALF_NRM_MIN etc. are not float |
247 | | // constants, but at least one other compiler (gcc 2.96) produces incorrect |
248 | | // results if they are. |
249 | | //------------------------------------------------------------------------- |
250 | | |
251 | | #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER |
252 | | |
253 | | #define HALF_MIN 5.96046448e-08f // Smallest positive half |
254 | | |
255 | | #define HALF_NRM_MIN 6.10351562e-05f // Smallest positive normalized half |
256 | | |
257 | | #define HALF_MAX 65504.0f // Largest positive half |
258 | | |
259 | | #define HALF_EPSILON 0.00097656f // Smallest positive e for which |
260 | | // half (1.0 + e) != half (1.0) |
261 | | #else |
262 | | |
263 | | #define HALF_MIN 5.96046448e-08 // Smallest positive half |
264 | | |
265 | | #define HALF_NRM_MIN 6.10351562e-05 // Smallest positive normalized half |
266 | | |
267 | 0 | #define HALF_MAX 65504.0 // Largest positive half |
268 | | |
269 | | #define HALF_EPSILON 0.00097656 // Smallest positive e for which |
270 | | // half (1.0 + e) != half (1.0) |
271 | | #endif |
272 | | |
273 | | |
274 | | #define HALF_MANT_DIG 11 // Number of digits in mantissa |
275 | | // (significand + hidden leading 1) |
276 | | |
277 | | #define HALF_DIG 2 // Number of base 10 digits that |
278 | | // can be represented without change |
279 | | |
280 | | #define HALF_DECIMAL_DIG 5 // Number of base-10 digits that are |
281 | | // necessary to uniquely represent all |
282 | | // distinct values |
283 | | |
284 | | #define HALF_RADIX 2 // Base of the exponent |
285 | | |
286 | | #define HALF_MIN_EXP -13 // Minimum negative integer such that |
287 | | // HALF_RADIX raised to the power of |
288 | | // one less than that integer is a |
289 | | // normalized half |
290 | | |
291 | | #define HALF_MAX_EXP 16 // Maximum positive integer such that |
292 | | // HALF_RADIX raised to the power of |
293 | | // one less than that integer is a |
294 | | // normalized half |
295 | | |
296 | | #define HALF_MIN_10_EXP -4 // Minimum positive integer such |
297 | | // that 10 raised to that power is |
298 | | // a normalized half |
299 | | |
300 | | #define HALF_MAX_10_EXP 4 // Maximum positive integer such |
301 | | // that 10 raised to that power is |
302 | | // a normalized half |
303 | | |
304 | | |
305 | | //--------------------------------------------------------------------------- |
306 | | // |
307 | | // Implementation -- |
308 | | // |
309 | | // Representation of a float: |
310 | | // |
311 | | // We assume that a float, f, is an IEEE 754 single-precision |
312 | | // floating point number, whose bits are arranged as follows: |
313 | | // |
314 | | // 31 (msb) |
315 | | // | |
316 | | // | 30 23 |
317 | | // | | | |
318 | | // | | | 22 0 (lsb) |
319 | | // | | | | | |
320 | | // X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX |
321 | | // |
322 | | // s e m |
323 | | // |
324 | | // S is the sign-bit, e is the exponent and m is the significand. |
325 | | // |
326 | | // If e is between 1 and 254, f is a normalized number: |
327 | | // |
328 | | // s e-127 |
329 | | // f = (-1) * 2 * 1.m |
330 | | // |
331 | | // If e is 0, and m is not zero, f is a denormalized number: |
332 | | // |
333 | | // s -126 |
334 | | // f = (-1) * 2 * 0.m |
335 | | // |
336 | | // If e and m are both zero, f is zero: |
337 | | // |
338 | | // f = 0.0 |
339 | | // |
340 | | // If e is 255, f is an "infinity" or "not a number" (NAN), |
341 | | // depending on whether m is zero or not. |
342 | | // |
343 | | // Examples: |
344 | | // |
345 | | // 0 00000000 00000000000000000000000 = 0.0 |
346 | | // 0 01111110 00000000000000000000000 = 0.5 |
347 | | // 0 01111111 00000000000000000000000 = 1.0 |
348 | | // 0 10000000 00000000000000000000000 = 2.0 |
349 | | // 0 10000000 10000000000000000000000 = 3.0 |
350 | | // 1 10000101 11110000010000000000000 = -124.0625 |
351 | | // 0 11111111 00000000000000000000000 = +infinity |
352 | | // 1 11111111 00000000000000000000000 = -infinity |
353 | | // 0 11111111 10000000000000000000000 = NAN |
354 | | // 1 11111111 11111111111111111111111 = NAN |
355 | | // |
356 | | // Representation of a half: |
357 | | // |
358 | | // Here is the bit-layout for a half number, h: |
359 | | // |
360 | | // 15 (msb) |
361 | | // | |
362 | | // | 14 10 |
363 | | // | | | |
364 | | // | | | 9 0 (lsb) |
365 | | // | | | | | |
366 | | // X XXXXX XXXXXXXXXX |
367 | | // |
368 | | // s e m |
369 | | // |
370 | | // S is the sign-bit, e is the exponent and m is the significand. |
371 | | // |
372 | | // If e is between 1 and 30, h is a normalized number: |
373 | | // |
374 | | // s e-15 |
375 | | // h = (-1) * 2 * 1.m |
376 | | // |
377 | | // If e is 0, and m is not zero, h is a denormalized number: |
378 | | // |
379 | | // S -14 |
380 | | // h = (-1) * 2 * 0.m |
381 | | // |
382 | | // If e and m are both zero, h is zero: |
383 | | // |
384 | | // h = 0.0 |
385 | | // |
386 | | // If e is 31, h is an "infinity" or "not a number" (NAN), |
387 | | // depending on whether m is zero or not. |
388 | | // |
389 | | // Examples: |
390 | | // |
391 | | // 0 00000 0000000000 = 0.0 |
392 | | // 0 01110 0000000000 = 0.5 |
393 | | // 0 01111 0000000000 = 1.0 |
394 | | // 0 10000 0000000000 = 2.0 |
395 | | // 0 10000 1000000000 = 3.0 |
396 | | // 1 10101 1111000001 = -124.0625 |
397 | | // 0 11111 0000000000 = +infinity |
398 | | // 1 11111 0000000000 = -infinity |
399 | | // 0 11111 1000000000 = NAN |
400 | | // 1 11111 1111111111 = NAN |
401 | | // |
402 | | // Conversion: |
403 | | // |
404 | | // Converting from a float to a half requires some non-trivial bit |
405 | | // manipulations. In some cases, this makes conversion relatively |
406 | | // slow, but the most common case is accelerated via table lookups. |
407 | | // |
408 | | // Converting back from a half to a float is easier because we don't |
409 | | // have to do any rounding. In addition, there are only 65536 |
410 | | // different half numbers; we can convert each of those numbers once |
411 | | // and store the results in a table. Later, all conversions can be |
412 | | // done using only simple table lookups. |
413 | | // |
414 | | //--------------------------------------------------------------------------- |
415 | | |
416 | | |
417 | | //-------------------- |
418 | | // Simple constructors |
419 | | //-------------------- |
420 | | |
421 | | inline |
422 | | half::half () |
423 | 0 | { |
424 | | // no initialization |
425 | 0 | } |
426 | | |
427 | | |
428 | | //---------------------------- |
429 | | // Half-from-float constructor |
430 | | //---------------------------- |
431 | | |
432 | | inline |
433 | | half::half (float f) |
434 | 0 | { |
435 | 0 | uif x; |
436 | |
|
437 | 0 | x.f = f; |
438 | |
|
439 | 0 | if (f == 0) |
440 | 0 | { |
441 | | // |
442 | | // Common special case - zero. |
443 | | // Preserve the zero's sign bit. |
444 | | // |
445 | |
|
446 | 0 | _h = (x.i >> 16); |
447 | 0 | } |
448 | 0 | else |
449 | 0 | { |
450 | | // |
451 | | // We extract the combined sign and exponent, e, from our |
452 | | // floating-point number, f. Then we convert e to the sign |
453 | | // and exponent of the half number via a table lookup. |
454 | | // |
455 | | // For the most common case, where a normalized half is produced, |
456 | | // the table lookup returns a non-zero value; in this case, all |
457 | | // we have to do is round f's significand to 10 bits and combine |
458 | | // the result with e. |
459 | | // |
460 | | // For all other cases (overflow, zeroes, denormalized numbers |
461 | | // resulting from underflow, infinities and NANs), the table |
462 | | // lookup returns zero, and we call a longer, non-inline function |
463 | | // to do the float-to-half conversion. |
464 | | // |
465 | |
|
466 | 0 | int e = (x.i >> 23) & 0x000001ff; |
467 | |
|
468 | 0 | e = _eLut[e]; |
469 | |
|
470 | 0 | if (e) |
471 | 0 | { |
472 | | // |
473 | | // Simple case - round the significand, m, to 10 |
474 | | // bits and combine it with the sign and exponent. |
475 | | // |
476 | |
|
477 | 0 | int m = x.i & 0x007fffff; |
478 | 0 | _h = (unsigned short)(e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13)); |
479 | 0 | } |
480 | 0 | else |
481 | 0 | { |
482 | | // |
483 | | // Difficult case - call a function. |
484 | | // |
485 | |
|
486 | 0 | _h = convert (x.i); |
487 | 0 | } |
488 | 0 | } |
489 | 0 | } |
490 | | |
491 | | |
492 | | //------------------------------------------ |
493 | | // Half-to-float conversion via table lookup |
494 | | //------------------------------------------ |
495 | | |
496 | | inline |
497 | | half::operator float () const |
498 | 0 | { |
499 | 0 | return _toFloat[_h].f; |
500 | 0 | } |
501 | | |
502 | | |
503 | | //------------------------- |
504 | | // Round to n-bit precision |
505 | | //------------------------- |
506 | | |
507 | | inline half |
508 | | half::round (unsigned int n) const |
509 | 0 | { |
510 | 0 | // |
511 | 0 | // Parameter check. |
512 | 0 | // |
513 | 0 |
|
514 | 0 | if (n >= 10) |
515 | 0 | return *this; |
516 | 0 |
|
517 | 0 | // |
518 | 0 | // Disassemble h into the sign, s, |
519 | 0 | // and the combined exponent and significand, e. |
520 | 0 | // |
521 | 0 |
|
522 | 0 | unsigned short s = _h & 0x8000; |
523 | 0 | unsigned short e = _h & 0x7fff; |
524 | 0 |
|
525 | 0 | // |
526 | 0 | // Round the exponent and significand to the nearest value |
527 | 0 | // where ones occur only in the (10-n) most significant bits. |
528 | 0 | // Note that the exponent adjusts automatically if rounding |
529 | 0 | // up causes the significand to overflow. |
530 | 0 | // |
531 | 0 |
|
532 | 0 | e >>= 9 - n; |
533 | 0 | e += e & 1; |
534 | 0 | e <<= 9 - n; |
535 | 0 |
|
536 | 0 | // |
537 | 0 | // Check for exponent overflow. |
538 | 0 | // |
539 | 0 |
|
540 | 0 | if (e >= 0x7c00) |
541 | 0 | { |
542 | 0 | // |
543 | 0 | // Overflow occurred -- truncate instead of rounding. |
544 | 0 | // |
545 | 0 |
|
546 | 0 | e = _h; |
547 | 0 | e >>= 10 - n; |
548 | 0 | e <<= 10 - n; |
549 | 0 | } |
550 | 0 |
|
551 | 0 | // |
552 | 0 | // Put the original sign bit back. |
553 | 0 | // |
554 | 0 |
|
555 | 0 | half h; |
556 | 0 | h._h = s | e; |
557 | 0 |
|
558 | 0 | return h; |
559 | 0 | } |
560 | | |
561 | | |
562 | | //----------------------- |
563 | | // Other inline functions |
564 | | //----------------------- |
565 | | |
566 | | inline half |
567 | | half::operator - () const |
568 | 0 | { |
569 | 0 | half h; |
570 | 0 | h._h = _h ^ 0x8000; |
571 | 0 | return h; |
572 | 0 | } |
573 | | |
574 | | |
575 | | inline half & |
576 | | half::operator = (half h) |
577 | 0 | { |
578 | 0 | _h = h._h; |
579 | 0 | return *this; |
580 | 0 | } |
581 | | |
582 | | |
583 | | inline half & |
584 | | half::operator = (float f) |
585 | 0 | { |
586 | 0 | *this = half (f); |
587 | 0 | return *this; |
588 | 0 | } |
589 | | |
590 | | |
591 | | inline half & |
592 | | half::operator += (half h) |
593 | 0 | { |
594 | 0 | *this = half (float (*this) + float (h)); |
595 | 0 | return *this; |
596 | 0 | } |
597 | | |
598 | | |
599 | | inline half & |
600 | | half::operator += (float f) |
601 | 0 | { |
602 | 0 | *this = half (float (*this) + f); |
603 | 0 | return *this; |
604 | 0 | } |
605 | | |
606 | | |
607 | | inline half & |
608 | | half::operator -= (half h) |
609 | 0 | { |
610 | 0 | *this = half (float (*this) - float (h)); |
611 | 0 | return *this; |
612 | 0 | } |
613 | | |
614 | | |
615 | | inline half & |
616 | | half::operator -= (float f) |
617 | 0 | { |
618 | 0 | *this = half (float (*this) - f); |
619 | 0 | return *this; |
620 | 0 | } |
621 | | |
622 | | |
623 | | inline half & |
624 | | half::operator *= (half h) |
625 | 0 | { |
626 | 0 | *this = half (float (*this) * float (h)); |
627 | 0 | return *this; |
628 | 0 | } |
629 | | |
630 | | |
631 | | inline half & |
632 | | half::operator *= (float f) |
633 | 0 | { |
634 | 0 | *this = half (float (*this) * f); |
635 | 0 | return *this; |
636 | 0 | } |
637 | | |
638 | | |
639 | | inline half & |
640 | | half::operator /= (half h) |
641 | 0 | { |
642 | 0 | *this = half (float (*this) / float (h)); |
643 | 0 | return *this; |
644 | 0 | } |
645 | | |
646 | | |
647 | | inline half & |
648 | | half::operator /= (float f) |
649 | 0 | { |
650 | 0 | *this = half (float (*this) / f); |
651 | 0 | return *this; |
652 | 0 | } |
653 | | |
654 | | |
655 | | inline bool |
656 | | half::isFinite () const |
657 | 0 | { |
658 | 0 | unsigned short e = (_h >> 10) & 0x001f; |
659 | 0 | return e < 31; |
660 | 0 | } |
661 | | |
662 | | |
663 | | inline bool |
664 | | half::isNormalized () const |
665 | 0 | { |
666 | 0 | unsigned short e = (_h >> 10) & 0x001f; |
667 | 0 | return e > 0 && e < 31; |
668 | 0 | } |
669 | | |
670 | | |
671 | | inline bool |
672 | | half::isDenormalized () const |
673 | 0 | { |
674 | 0 | unsigned short e = (_h >> 10) & 0x001f; |
675 | 0 | unsigned short m = _h & 0x3ff; |
676 | 0 | return e == 0 && m != 0; |
677 | 0 | } |
678 | | |
679 | | |
680 | | inline bool |
681 | | half::isZero () const |
682 | 0 | { |
683 | 0 | return (_h & 0x7fff) == 0; |
684 | 0 | } |
685 | | |
686 | | |
687 | | inline bool |
688 | | half::isNan () const |
689 | 0 | { |
690 | 0 | unsigned short e = (_h >> 10) & 0x001f; |
691 | 0 | unsigned short m = _h & 0x3ff; |
692 | 0 | return e == 31 && m != 0; |
693 | 0 | } |
694 | | |
695 | | |
696 | | inline bool |
697 | | half::isInfinity () const |
698 | 0 | { |
699 | 0 | unsigned short e = (_h >> 10) & 0x001f; |
700 | 0 | unsigned short m = _h & 0x3ff; |
701 | 0 | return e == 31 && m == 0; |
702 | 0 | } |
703 | | |
704 | | |
705 | | inline bool |
706 | | half::isNegative () const |
707 | 0 | { |
708 | 0 | return (_h & 0x8000) != 0; |
709 | 0 | } |
710 | | |
711 | | |
712 | | inline half |
713 | | half::posInf () |
714 | 0 | { |
715 | 0 | half h; |
716 | 0 | h._h = 0x7c00; |
717 | 0 | return h; |
718 | 0 | } |
719 | | |
720 | | |
721 | | inline half |
722 | | half::negInf () |
723 | 0 | { |
724 | 0 | half h; |
725 | 0 | h._h = 0xfc00; |
726 | 0 | return h; |
727 | 0 | } |
728 | | |
729 | | |
730 | | inline half |
731 | | half::qNan () |
732 | 0 | { |
733 | 0 | half h; |
734 | 0 | h._h = 0x7fff; |
735 | 0 | return h; |
736 | 0 | } |
737 | | |
738 | | |
739 | | inline half |
740 | | half::sNan () |
741 | 0 | { |
742 | 0 | half h; |
743 | 0 | h._h = 0x7dff; |
744 | 0 | return h; |
745 | 0 | } |
746 | | |
747 | | |
748 | | inline unsigned short |
749 | | half::bits () const |
750 | 0 | { |
751 | 0 | return _h; |
752 | 0 | } |
753 | | |
754 | | |
755 | | inline void |
756 | | half::setBits (unsigned short bits) |
757 | 0 | { |
758 | 0 | _h = bits; |
759 | 0 | } |
760 | | |
761 | | #endif |