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