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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| #include <iostream> #include <cstdint>
#define uint unsigned int #define uint16 short int class Float16XYZ { public: Float16XYZ(); Float16XYZ( float x, float y, float z );
inline void packXYZ( float x, float y, float z ); inline void unpackXYZ( float & x, float & y, float & z ) const;
inline void dx( float value ); inline float dx() const; inline void dy( float value ); inline float dy() const; inline void dz( float value ); inline float dz() const;
private: union MultiType { float asFloat; uint asUint; int asInt; }; unsigned char data_x_[2], data_y_[2], data_z_[2]; };
/** * Constructor. */ inline Float16XYZ::Float16XYZ() { }
/** * Constructor. */ inline Float16XYZ::Float16XYZ( float x, float y, float z ) { this->dx( x ); this->dy( y ); this->dz( z ); }
/** * This method packs the three input floats into this object. */ inline void Float16XYZ::packXYZ( float x, float y, float z ) { this->dx( x ); this->dy( y ); this->dz( z ); }
/** * This method unpacks this object into the three input floats. */ inline void Float16XYZ::unpackXYZ( float & x, float & y, float & z ) const { x = this->dx(); y = this->dy(); z = this->dz(); }
/** * This method sets the packed a value from a float. */ #define SET_ATTR_DATA( ATTR_NAME ) inline void Float16XYZ::d##ATTR_NAME( float ATTR_NAME ) \ { \ const float addValues[] = { 2.f, -2.f }; \ MultiType a; a.asFloat = ATTR_NAME; \ a.asFloat += addValues[ a.asInt < 0 ]; \ uint16& aDataInt = *(uint16*)data_##ATTR_NAME##_; \ aDataInt = (a.asUint >> 12) & 0x7fff; \ aDataInt |= ((a.asUint >> 16) & 0x8000); \ } SET_ATTR_DATA(x) SET_ATTR_DATA(y) SET_ATTR_DATA(z) /** * This method returns the packed a value as a float. */ #define GET_ATTR_DATA( ATTR_NAME ) inline float Float16XYZ::d##ATTR_NAME() const \ { \ MultiType a; \ a.asUint = 0x40000000; \ uint16& aDataInt = *(uint16*)data_##ATTR_NAME##_; \ a.asUint |= (aDataInt & 0x7fff) << 12; \ a.asFloat -= 2.f; \ a.asUint |= (aDataInt & 0x8000) << 16; \ return a.asFloat; \ }
GET_ATTR_DATA(x) GET_ATTR_DATA(y) GET_ATTR_DATA(z)
int main( int argc, char * argv[] ) { float x = 10.34; float y = 1.25; float z = 53.89; Float16XYZ a; a.packXYZ(x,y,z); std::cout << "float input: "<< x << "," << y << "," << z << std::endl; a.unpackXYZ(x,y,z); std::cout << "sizeof before:" << 3 * sizeof(x) << ", after" << sizeof(a) << std::endl; std::cout << "result:" << x << "," << y << "," << z << std::endl; }
|