1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
/********************************************************************************
* *
* H a l f - F l o a t S u p p o r t *
* *
*********************************************************************************
* Copyright (C) 2008,2022 by Jeroen van der Zijp. All Rights Reserved. *
*********************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/> *
********************************************************************************/
#ifndef FXHALF_H
#define FXHALF_H
// Some important numbers
#define HALF_MIN 5.9604644775391E-08 // Smallest half number
#define HALF_MAX 65504.0 // Largest half number
#define HALF_EPSILON 0.00097656 // Smallest number where (1+e) != 1
namespace FX {
/// Half float (16-bit float)
class FXAPI FXhalf {
private:
FXushort v;
private:
static const FXushort fhb[512];
static const FXuchar fhs[512];
static const FXuint hfm[2048];
static const FXuint hfe[64];
static const FXushort hfw[64];
public:
FXhalf(){}
// Initialize half with half
FXhalf(const FXhalf& h):v(h.v){}
// Initialize half with float
FXhalf(FXfloat f){
union { FXfloat f; FXuint u; } r={f};
v=fhb[(r.u>>23)&0x1ff]+((r.u&0x007fffff)>>fhs[(r.u>>23)&0x1ff]);
}
// Convert half to float
operator FXfloat() const {
union { FXuint u; FXfloat f; } r={hfm[hfw[v>>10]+(v&0x3ff)]+hfe[v>>10]};
return r.f;
}
// Test for zero
FXbool operator!() const { return v==0; }
// Unary
FXhalf operator+() const { return *this; }
FXhalf operator-() const { FXhalf h; h.v=v^0x8000; return h; }
// Equality
FXbool operator==(FXhalf h) const { return v==h.v; }
FXbool operator!=(FXhalf h) const { return v!=h.v; }
// Assignment
FXhalf& operator=(FXhalf h){ v=h.v; return *this; }
FXhalf& operator=(FXfloat f){ *this=FXhalf(f); return *this; }
// Assignment operators
FXhalf& operator+=(FXhalf h){ *this=FXhalf(FXfloat(*this)+FXfloat(h)); return *this; }
FXhalf& operator+=(FXfloat f){ *this=FXhalf(FXfloat(*this)+f); return *this; }
FXhalf& operator-=(FXhalf h){ *this=FXhalf(FXfloat(*this)-FXfloat(h)); return *this; }
FXhalf& operator-=(FXfloat f){ *this=FXhalf(FXfloat(*this)-f); return *this; }
FXhalf& operator*=(FXhalf h){ *this=FXhalf(FXfloat(*this)*FXfloat(h)); return *this; }
FXhalf& operator*=(FXfloat f){ *this=FXhalf(FXfloat(*this)*f); return *this; }
FXhalf& operator/=(FXhalf h){ *this=FXhalf(FXfloat(*this)/FXfloat(h)); return *this; }
FXhalf& operator/=(FXfloat f){ *this=FXhalf(FXfloat(*this)/f); return *this; }
};
}
#endif
|