All Classes Files Functions Variables Typedefs Pages
half.hpp
Go to the documentation of this file.
1 #pragma once
2 
11 #include <limits>
12 #include <cstdint>
13 #include <cstring>
14 #include <type_traits>
15 
16 // check float implementation
17 static_assert(
18  std::numeric_limits<float>::is_iec559,
19  "Half-precision float implementation requires IEC 559 compliant format");
20 
21 namespace lumina {
22 
23 class half {
24 public:
25  // constructors
26  half() : m_data(0) {}
27 
28  half(float v) {
29  uint32_t in;
30  memcpy(&in, &v, 4);
31 
32  // extract components
33  m_data = (in >> 16) & 0x8000; // sign bit
34  uint8_t ex = (in >> 23) & 0xFF; // exponent
35  uint32_t ma = in & 0x007FFFFF; // mantissa
36 
37  if(ex == 255 && ma != 0) { // NaN
38  m_data |= 0x1F << 10;
39  m_data |= 1;
40  }
41  else if(ex > 127 + 15) { // to big values
42  m_data |= 0x1F << 10;
43  }
44  else if(ex < 127 - 24) { // to small values
45  m_data |= 0;
46  }
47  else if(ex < 127 - 14) { // conversion to subnormal
48  m_data |= (ma | 0x00800000) >> (126 - ex);
49  }
50  else {
51  m_data |= (ex - 127 + 15) << 10;
52  m_data |= ma >> 13;
53  }
54  }
55 
56  // conversion to float
57  operator float() const {
58  // extract components
59  uint32_t out = (m_data & 0x8000) << 16; // sign bit
60  uint8_t ex = (m_data >> 10) & 0x1F; // exponent
61  uint16_t ma = m_data & 0x03FF; // mantissa
62 
63  if(ex == 0x1F) { // inf or NaN
64  out |= 0xFF << 23;
65  if(ma)
66  out |= 1; // NaN
67  }
68  else if(ex == 0) { // zero or subnormal
69  if(ma != 0) // normalize number
70  {
71  for(ex = 0; (ma & 0x0400) == 0; ++ex)
72  ma <<= 1;
73  out |= (0x71 - ex) << 23;
74  out |= (ma & 0x03FF) << 13;
75  }
76  }
77  else { // normalized values
78  out |= (ex + 127 - 15) << 23;
79  out |= ma << 13;
80  }
81  float outf;
82  memcpy(&outf, &out, 4);
83  return outf;
84  }
85 
86 private:
87  uint16_t m_data;
88 };
89 
90 } // namespace lumina
91 
92 // traits
93 namespace std {
94 template <> struct is_floating_point<lumina::half> : true_type {};
95 }
Definition: half.hpp:23