📄 half.h
字号:
// If e is 0, and m is not zero, h is a denormalized number://// S -14// h = (-1) * 2 * 0.m//// If e and m are both zero, h is zero://// h = 0.0//// If e is 31, h is an "infinity" or "not a number" (NAN),// depending on whether m is zero or not.//// Examples://// 0 00000 0000000000 = 0.0// 0 01110 0000000000 = 0.5// 0 01111 0000000000 = 1.0// 0 10000 0000000000 = 2.0// 0 10000 1000000000 = 3.0// 1 10101 1111000001 = -124.0625// 0 11111 0000000000 = +infinity// 1 11111 0000000000 = -infinity// 0 11111 1000000000 = NAN// 1 11111 1111111111 = NAN//// Conversion://// Converting from a float to a half requires some non-trivial bit// manipulations. In some cases, this makes conversion relatively// slow, but the most common case is accelerated via table lookups.//// Converting back from a half to a float is easier because we don't// have to do any rounding. In addition, there are only 65536// different half numbers; we can convert each of those numbers once// and store the results in a table. Later, all conversions can be// done using only simple table lookups.////---------------------------------------------------------------------------//--------------------// Simple constructors//--------------------inlinehalf::half (){ // no initialization}//----------------------------// Half-from-float constructor//----------------------------inlinehalf::half (float f){ uif x; x.f = f; if (f == 0) { // // Common special case - zero. // Preserve the zero's sign bit. // _h = (x.i >> 16); } else { // // We extract the combined sign and exponent, e, from our // floating-point number, f. Then we convert e to the sign // and exponent of the half number via a table lookup. // // For the most common case, where a normalized half is produced, // the table lookup returns a non-zero value; in this case, all // we have to do is round f's significand to 10 bits and combine // the result with e. // // For all other cases (overflow, zeroes, denormalized numbers // resulting from underflow, infinities and NANs), the table // lookup returns zero, and we call a longer, non-inline function // to do the float-to-half conversion. // register int e = (x.i >> 23) & 0x000001ff; e = _eLut[e]; if (e) { // // Simple case - round the significand, m, to 10 // bits and combine it with the sign and exponent. // register int m = x.i & 0x007fffff; _h = e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13); } else { // // Difficult case - call a function. // _h = convert (x.i); } }}//------------------------------------------// Half-to-float conversion via table lookup//------------------------------------------inlinehalf::operator float () const{ return _toFloat[_h].f;}//-------------------------// Round to n-bit precision//-------------------------inline halfhalf::round (unsigned int n) const{ // // Parameter check. // if (n >= 10) return *this; // // Disassemble h into the sign, s, // and the combined exponent and significand, e. // unsigned short s = _h & 0x8000; unsigned short e = _h & 0x7fff; // // Round the exponent and significand to the nearest value // where ones occur only in the (10-n) most significant bits. // Note that the exponent adjusts automatically if rounding // up causes the significand to overflow. // e >>= 9 - n; e += e & 1; e <<= 9 - n; // // Check for exponent overflow. // if (e >= 0x7c00) { // // Overflow occurred -- truncate instead of rounding. // e = _h; e >>= 10 - n; e <<= 10 - n; } // // Put the original sign bit back. // half h; h._h = s | e; return h;}//-----------------------// Other inline functions//-----------------------inline half half::operator - () const{ half h; h._h = _h ^ 0x8000; return h;}inline half &half::operator = (half h){ _h = h._h; return *this;}inline half &half::operator = (float f){ *this = half (f); return *this;}inline half &half::operator += (half h){ *this = half (float (*this) + float (h)); return *this;}inline half &half::operator += (float f){ *this = half (float (*this) + f); return *this;}inline half &half::operator -= (half h){ *this = half (float (*this) - float (h)); return *this;}inline half &half::operator -= (float f){ *this = half (float (*this) - f); return *this;}inline half &half::operator *= (half h){ *this = half (float (*this) * float (h)); return *this;}inline half &half::operator *= (float f){ *this = half (float (*this) * f); return *this;}inline half &half::operator /= (half h){ *this = half (float (*this) / float (h)); return *this;}inline half &half::operator /= (float f){ *this = half (float (*this) / f); return *this;}inline bool half::isFinite () const{ unsigned short e = (_h >> 10) & 0x001f; return e < 31;}inline boolhalf::isNormalized () const{ unsigned short e = (_h >> 10) & 0x001f; return e > 0 && e < 31;}inline boolhalf::isDenormalized () const{ unsigned short e = (_h >> 10) & 0x001f; unsigned short m = _h & 0x3ff; return e == 0 && m != 0;}inline boolhalf::isZero () const{ return (_h & 0x7fff) == 0;}inline boolhalf::isNan () const{ unsigned short e = (_h >> 10) & 0x001f; unsigned short m = _h & 0x3ff; return e == 31 && m != 0;}inline boolhalf::isInfinity () const{ unsigned short e = (_h >> 10) & 0x001f; unsigned short m = _h & 0x3ff; return e == 31 && m == 0;}inline bool half::isNegative () const{ return (_h & 0x8000) != 0;}inline halfhalf::posInf (){ half h; h._h = 0x7c00; return h;}inline halfhalf::negInf (){ half h; h._h = 0xfc00; return h;}inline halfhalf::qNan (){ half h; h._h = 0x7fff; return h;}inline halfhalf::sNan (){ half h; h._h = 0x7dff; return h;}inline unsigned shorthalf::bits () const{ return _h;}inline voidhalf::setBits (unsigned short bits){ _h = bits;}#undef HALF_EXPORT_CONST#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -