00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef BITFLOAT_H
00020 #define BITFLOAT_H
00021
00022 #include <typeinfo>
00023 #include <stdexcept>
00024
00025 #include <bit/enums.h>
00026 #include <bit/utility.h>
00027 #include <bit/pointer.h>
00028 #include <bit/data.h>
00029
00030 namespace bit
00031 {
00032
00033 template <typename F> class Float;
00034
00035 class FloatingPoint
00036 {
00037 public:
00038
00039 typedef BitPointer<FloatingPoint> pointer;
00040
00041 FloatingPoint( ByteOrder bo=BYTEORDER_HOST ): byte_order(bo) { }
00042
00043 virtual ~FloatingPoint() { }
00044
00045 virtual Data as_data() const = 0;
00046
00047 virtual size_t size() const = 0;
00048
00049 virtual const void* voidptr() const = 0;
00050
00051 virtual pointer clone() const = 0;
00052
00058 virtual void set_value( const Data d ) = 0;
00059
00060 virtual void set_value( const void* mem, size_t size ) = 0;
00061
00067 virtual void set_value( const Data d, ByteOrder databo ) = 0;
00068
00069 template <typename T> operator T();
00070
00071 template <typename T> FloatingPoint& operator = ( T f );
00072
00073 virtual const std::type_info& int_type() = 0;
00074
00075 ByteOrder byte_order;
00076 };
00077
00078 template <typename F>
00079 class Float: public FloatingPoint {
00080 public:
00081
00082 typedef BitPointer< Float<F> > pointer;
00083
00084 Float(F v=0, ByteOrder bo=BYTEORDER_HOST): FloatingPoint(bo), value(v) { }
00085
00086 Float(ByteOrder bo): FloatingPoint(bo), value(0) { }
00087
00094 Float(const Data d, ByteOrder databo=BYTEORDER_HOST, ByteOrder bo=BYTEORDER_HOST): FloatingPoint(bo) {
00095 this->set_value(d, databo);
00096 }
00097
00098 static pointer create(F v=0, ByteOrder bo=BYTEORDER_HOST) { return pointer(new Float<F>(v,bo)); }
00099
00100 static pointer create(ByteOrder bo) { return pointer(new Float<F>(bo)); }
00101
00102 static pointer create(const Data d, ByteOrder databo=BYTEORDER_HOST, ByteOrder bo=BYTEORDER_HOST) {
00103 return pointer(new Float<F>(d,databo,bo));
00104 }
00105
00106 ~Float() { }
00107
00108 virtual FloatingPoint::pointer clone() const {
00109 pointer p = this->create(value, byte_order);
00110 return p;
00111 }
00112
00113 operator F() const { return this->host(); }
00114
00115 bool operator < ( F f ) const { return this->host() < f; }
00116 bool operator <= ( F f ) const { return this->host() <= f; }
00117 bool operator == ( F f ) const { return this->host() == f; }
00118 bool operator != ( F f ) const { return this->host() != f; }
00119 bool operator >= ( F f ) const { return this->host() >= f; }
00120 bool operator > ( F f ) const { return this->host() > f; }
00121
00122 Float<F>& operator = ( F f )
00123 {
00124 value = f;
00125 this->convert_value_from_host_to_type();
00126 return *this;
00127 }
00128
00129 const Float<F>& operator + ( F f ) const
00130 {
00131 this->convert_value_from_type_to_host();
00132 value += f;
00133 this->convert_value_from_host_to_type();
00134 return *this;
00135 }
00136
00137 const Float<F>& operator - ( F f ) const
00138 {
00139 this->convert_value_from_type_to_host();
00140 value -= f;
00141 this->convert_value_from_host_to_type();
00142 return *this;
00143 }
00144
00145 const Float<F>& operator * ( F f ) const
00146 {
00147 this->convert_value_from_type_to_host();
00148 value *= f;
00149 this->convert_value_from_host_to_type();
00150 return *this;
00151 }
00152
00153 const Float<F>& operator / ( F f ) const
00154 {
00155 this->convert_value_from_type_to_host();
00156 value /= f;
00157 this->convert_value_from_host_to_type();
00158 return *this;
00159 }
00160
00161 Float<F>& operator += ( F f )
00162 {
00163 this->convert_value_from_type_to_host();
00164 value += f;
00165 this->convert_value_from_host_to_type();
00166 return *this;
00167 }
00168
00169 Float<F>& operator -= ( F f )
00170 {
00171 this->convert_value_from_type_to_host();
00172 value -= f;
00173 this->convert_value_from_host_to_type();
00174 return *this;
00175 }
00176
00177 Float<F>& operator *= ( F f )
00178 {
00179 this->convert_value_from_type_to_host();
00180 value *= f;
00181 this->convert_value_from_host_to_type();
00182 return *this;
00183 }
00184
00185 Float<F>& operator /= ( F f )
00186 {
00187 this->convert_value_from_type_to_host();
00188 value /= f;
00189 this->convert_value_from_host_to_type();
00190 return *this;
00191 }
00192
00198 virtual void set_value( const Data d ) {
00199 if ( d.size() < sizeof(F) )
00200 throw;
00201
00202 memcpy( &value, d.data(), sizeof(F) );
00203 }
00204
00210 virtual void set_value( const void* mem, size_t size ) {
00211 if ( size < sizeof(F) )
00212 throw;
00213
00214 memcpy( &value, mem, sizeof(F) );
00215 }
00216
00222 virtual void set_value( const Data d, ByteOrder databo ) {
00223 if ( d.size() < sizeof(F) )
00224 throw;
00225
00226 memcpy( &value, d.data(), sizeof(F) );
00227
00228 switch ( byte_order ) {
00229 case BYTEORDER_HOST:
00230 switch ( databo ) {
00231 case BYTEORDER_HOST:
00232 break;
00233 case BYTEORDER_NETWORK:
00234 case BYTEORDER_BIG_ENDIAN:
00235 value = be_to_host(value);
00236 break;
00237 case BYTEORDER_LITTLE_ENDIAN:
00238 value = le_to_host(value);
00239 break;
00240 }
00241 break;
00242 case BYTEORDER_NETWORK:
00243 case BYTEORDER_BIG_ENDIAN:
00244 switch ( databo ) {
00245 case BYTEORDER_HOST:
00246 value = host_to_net(value);
00247 break;
00248 case BYTEORDER_NETWORK:
00249 case BYTEORDER_BIG_ENDIAN:
00250 break;
00251 case BYTEORDER_LITTLE_ENDIAN:
00252 value = le_to_net(value);
00253 break;
00254 }
00255 break;
00256 case BYTEORDER_LITTLE_ENDIAN:
00257 switch ( databo ) {
00258 case BYTEORDER_HOST:
00259 value = host_to_le(value);
00260 break;
00261 case BYTEORDER_NETWORK:
00262 case BYTEORDER_BIG_ENDIAN:
00263 value = net_to_le(value);
00264 break;
00265 case BYTEORDER_LITTLE_ENDIAN:
00266 break;
00267 }
00268 break;
00269 }
00270 }
00271
00272 virtual Data as_data() const
00273 {
00274 Data d( sizeof(F) );
00275 memcpy( d.data(), &value, sizeof(F) );
00276 return d;
00277 }
00278
00279 virtual size_t size() const { return sizeof(F); }
00280
00281 virtual const void* voidptr() const { return &value; }
00282
00283 virtual const std::type_info& int_type() { return typeid(F); }
00284
00285 F host() const {
00286 switch ( byte_order )
00287 {
00288 case BYTEORDER_HOST:
00289 return value;
00290 case BYTEORDER_NETWORK:
00291 case BYTEORDER_BIG_ENDIAN:
00292 return net_to_host(value);
00293 case BYTEORDER_LITTLE_ENDIAN:
00294 return le_to_host(value);
00295 }
00296 throw;
00297 }
00298
00299 F network() const {
00300 switch ( byte_order )
00301 {
00302 case BYTEORDER_HOST:
00303 return host_to_net(value);
00304 case BYTEORDER_NETWORK:
00305 case BYTEORDER_BIG_ENDIAN:
00306 return value;
00307 case BYTEORDER_LITTLE_ENDIAN:
00308 return le_to_net(value);
00309 }
00310 throw;
00311 }
00312
00313 F big_endian() const {
00314 return this->network();
00315 }
00316
00317 F little_endian() const {
00318 switch ( byte_order )
00319 {
00320 case BYTEORDER_HOST:
00321 return host_to_le(value);
00322 case BYTEORDER_NETWORK:
00323 case BYTEORDER_BIG_ENDIAN:
00324 return net_to_le(value);
00325 case BYTEORDER_LITTLE_ENDIAN:
00326 return value;
00327 }
00328 throw;
00329 }
00330
00331 F value;
00332
00333 protected:
00334 void convert_value_from_type_to_host()
00335 {
00336 switch ( byte_order )
00337 {
00338 case BYTEORDER_HOST:
00339 return;
00340 case BYTEORDER_NETWORK:
00341 case BYTEORDER_BIG_ENDIAN:
00342 value = net_to_host(value);
00343 case BYTEORDER_LITTLE_ENDIAN:
00344 value = le_to_host(value);
00345 }
00346 }
00347
00348 void convert_value_from_host_to_type()
00349 {
00350 switch ( byte_order )
00351 {
00352 case BYTEORDER_HOST:
00353 return;
00354 case BYTEORDER_NETWORK:
00355 case BYTEORDER_BIG_ENDIAN:
00356 value = host_to_net(value);
00357 case BYTEORDER_LITTLE_ENDIAN:
00358 value = host_to_le(value);
00359 }
00360 }
00361
00362 };
00363
00364 typedef Float<float> FloatSingle;
00365 typedef Float<double> FloatDouble;
00366 typedef Float<long double> FloatQuadruple;
00367
00368 template <typename T> FloatingPoint::operator T()
00369 {
00370 switch ( this->size() )
00371 {
00372 case 4:
00373 {
00374 FloatSingle* f;
00375 f = dynamic_cast<FloatSingle*>(this);
00376 return static_cast<T>(f->host());
00377 }
00378 case 8:
00379 {
00380 FloatDouble* f;
00381 f = dynamic_cast<FloatDouble*>(this);
00382 return static_cast<T>(f->host());
00383 }
00384 case 16:
00385 {
00386 FloatQuadruple* f;
00387 f = dynamic_cast<FloatQuadruple*>(this);
00388 return static_cast<T>(f->host());
00389 }
00390 }
00391 throw std::logic_error("bit::FloatingPoint bad cast");
00392 }
00393
00394 template <typename T> FloatingPoint& FloatingPoint::operator = ( T i )
00395 {
00396 switch ( this->size() )
00397 {
00398 case 4:
00399 {
00400 FloatSingle* f;
00401 f = dynamic_cast<FloatSingle*>(this);
00402 *f = (float)(i);
00403 }
00404 break;
00405 case 8:
00406 {
00407 FloatDouble* f;
00408 f = dynamic_cast<FloatDouble*>(this);
00409 *f = (double)(i);
00410 }
00411 break;
00412 case 16:
00413 {
00414 FloatQuadruple* f;
00415 f = dynamic_cast<FloatQuadruple*>(this);
00416 *f = (long double)(i);
00417 }
00418 break;
00419 }
00420 return *this;
00421 }
00422
00423 }
00424
00425 #endif