Clutter Engine 0.0.1
Loading...
Searching...
No Matches
type_half.inl
1namespace glm{
2namespace detail
3{
4 GLM_FUNC_QUALIFIER float overflow()
5 {
6 volatile float f = 1e10;
7
8 for(int i = 0; i < 10; ++i)
9 f *= f; // this will overflow before the for loop terminates
10 return f;
11 }
12
13 union uif32
14 {
15 GLM_FUNC_QUALIFIER uif32() :
16 i(0)
17 {}
18
19 GLM_FUNC_QUALIFIER uif32(float f_) :
20 f(f_)
21 {}
22
23 GLM_FUNC_QUALIFIER uif32(unsigned int i_) :
24 i(i_)
25 {}
26
27 float f;
28 unsigned int i;
29 };
30
31 GLM_FUNC_QUALIFIER float toFloat32(hdata value)
32 {
33 int s = (value >> 15) & 0x00000001;
34 int e = (value >> 10) & 0x0000001f;
35 int m = value & 0x000003ff;
36
37 if(e == 0)
38 {
39 if(m == 0)
40 {
41 //
42 // Plus or minus zero
43 //
44
45 detail::uif32 result;
46 result.i = static_cast<unsigned int>(s << 31);
47 return result.f;
48 }
49 else
50 {
51 //
52 // Denormalized number -- renormalize it
53 //
54
55 while(!(m & 0x00000400))
56 {
57 m <<= 1;
58 e -= 1;
59 }
60
61 e += 1;
62 m &= ~0x00000400;
63 }
64 }
65 else if(e == 31)
66 {
67 if(m == 0)
68 {
69 //
70 // Positive or negative infinity
71 //
72
73 uif32 result;
74 result.i = static_cast<unsigned int>((s << 31) | 0x7f800000);
75 return result.f;
76 }
77 else
78 {
79 //
80 // Nan -- preserve sign and significand bits
81 //
82
83 uif32 result;
84 result.i = static_cast<unsigned int>((s << 31) | 0x7f800000 | (m << 13));
85 return result.f;
86 }
87 }
88
89 //
90 // Normalized number
91 //
92
93 e = e + (127 - 15);
94 m = m << 13;
95
96 //
97 // Assemble s, e and m.
98 //
99
100 uif32 Result;
101 Result.i = static_cast<unsigned int>((s << 31) | (e << 23) | m);
102 return Result.f;
103 }
104
105 GLM_FUNC_QUALIFIER hdata toFloat16(float const& f)
106 {
107 uif32 Entry;
108 Entry.f = f;
109 int i = static_cast<int>(Entry.i);
110
111 //
112 // Our floating point number, f, is represented by the bit
113 // pattern in integer i. Disassemble that bit pattern into
114 // the sign, s, the exponent, e, and the significand, m.
115 // Shift s into the position where it will go in the
116 // resulting half number.
117 // Adjust e, accounting for the different exponent bias
118 // of float and half (127 versus 15).
119 //
120
121 int s = (i >> 16) & 0x00008000;
122 int e = ((i >> 23) & 0x000000ff) - (127 - 15);
123 int m = i & 0x007fffff;
124
125 //
126 // Now reassemble s, e and m into a half:
127 //
128
129 if(e <= 0)
130 {
131 if(e < -10)
132 {
133 //
134 // E is less than -10. The absolute value of f is
135 // less than half_MIN (f may be a small normalized
136 // float, a denormalized float or a zero).
137 //
138 // We convert f to a half zero.
139 //
140
141 return hdata(s);
142 }
143
144 //
145 // E is between -10 and 0. F is a normalized float,
146 // whose magnitude is less than __half_NRM_MIN.
147 //
148 // We convert f to a denormalized half.
149 //
150
151 m = (m | 0x00800000) >> (1 - e);
152
153 //
154 // Round to nearest, round "0.5" up.
155 //
156 // Rounding may cause the significand to overflow and make
157 // our number normalized. Because of the way a half's bits
158 // are laid out, we don't have to treat this case separately;
159 // the code below will handle it correctly.
160 //
161
162 if(m & 0x00001000)
163 m += 0x00002000;
164
165 //
166 // Assemble the half from s, e (zero) and m.
167 //
168
169 return hdata(s | (m >> 13));
170 }
171 else if(e == 0xff - (127 - 15))
172 {
173 if(m == 0)
174 {
175 //
176 // F is an infinity; convert f to a half
177 // infinity with the same sign as f.
178 //
179
180 return hdata(s | 0x7c00);
181 }
182 else
183 {
184 //
185 // F is a NAN; we produce a half NAN that preserves
186 // the sign bit and the 10 leftmost bits of the
187 // significand of f, with one exception: If the 10
188 // leftmost bits are all zero, the NAN would turn
189 // into an infinity, so we have to set at least one
190 // bit in the significand.
191 //
192
193 m >>= 13;
194
195 return hdata(s | 0x7c00 | m | (m == 0));
196 }
197 }
198 else
199 {
200 //
201 // E is greater than zero. F is a normalized float.
202 // We try to convert f to a normalized half.
203 //
204
205 //
206 // Round to nearest, round "0.5" up
207 //
208
209 if(m & 0x00001000)
210 {
211 m += 0x00002000;
212
213 if(m & 0x00800000)
214 {
215 m = 0; // overflow in significand,
216 e += 1; // adjust exponent
217 }
218 }
219
220 //
221 // Handle exponent overflow
222 //
223
224 if (e > 30)
225 {
226 overflow(); // Cause a hardware floating point overflow;
227
228 return hdata(s | 0x7c00);
229 // if this returns, the half becomes an
230 } // infinity with the same sign as f.
231
232 //
233 // Assemble the half from s, e and m.
234 //
235
236 return hdata(s | (e << 10) | (m >> 13));
237 }
238 }
239
240}//namespace detail
241}//namespace glm
GLM_FUNC_DECL GLM_CONSTEXPR genType e()
Definition constants.inl:102
detail namespace with internal helper functions
Definition json.h:249
Core features
Definition common.hpp:21
Definition type_half.inl:14