00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #ifndef fb_freq_INCLUDED
00094 #define fb_freq_INCLUDED
00095
00096 #include "defs.h"
00097 #ifndef ERRORS_INCLUDED
00098 #include "errors.h"
00099 #endif
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 enum FB_FREQ_TYPE {
00113 FB_FREQ_TYPE_EXACT = 1,
00114 FB_FREQ_TYPE_GUESS = 0,
00115 FB_FREQ_TYPE_UNKNOWN = -1,
00116 FB_FREQ_TYPE_UNINIT = -2,
00117 FB_FREQ_TYPE_ERROR = -3
00118 };
00119
00120 #define FB_FREQ_TYPE_COMBINE( type1, type2 ) \
00121 ( (type1) > (type2) ? (type2) : (type1) )
00122 #define FB_FREQ_TYPE_BETTER( type1, type2 ) ( (type1) > (type2) )
00123
00124 #define FB_FREQ_TYPE_IS_EXACT( type ) ( (type) > 0 )
00125 #define FB_FREQ_TYPE_IS_GUESS( type ) ( (type) == 0 )
00126 #define FB_FREQ_TYPE_IS_KNOWN( type ) ( (type) >= 0 )
00127 #define FB_FREQ_TYPE_NOT_KNOWN( type ) ( (type) < 0 )
00128 #define FB_FREQ_TYPE_INITIALIZED( type ) ( (type) >= FB_FREQ_TYPE_UNKNOWN )
00129
00130 #define FB_FREQ_TYPE_IS_VALID( type ) \
00131 ( (type) >= FB_FREQ_TYPE_ERROR && (type) <= FB_FREQ_TYPE_EXACT )
00132
00133
00134
00135
00136
00137
00138
00139
00140 #if defined(TARG_SL) && defined(__SL__)
00141 #define FREQ_OFFSET 3
00142 #define FREQ_SET_OFFSET(value) (value + FREQ_OFFSET)
00143 #define FREQ_RESET_OFFSET(value) (value - FREQ_OFFSET)
00144 typedef UINT32 FREQ_VALUE_TYPE;
00145 #else
00146 const float FB_FREQ_EPSILON = 0.0001;
00147 typedef float FREQ_VALUE_TYPE;
00148 #endif
00149
00150 class FB_FREQ {
00151 public:
00152
00153 FB_FREQ_TYPE _type;
00154
00155 FREQ_VALUE_TYPE _value;
00156
00157
00158
00159
00160
00161
00162
00163
00164 #if defined(TARG_SL) && defined(__SL__)
00165 FB_FREQ( FB_FREQ_TYPE type, FREQ_VALUE_TYPE value )
00166 : _type( type ), _value( FREQ_SET_OFFSET(value) ) { }
00167 #else
00168 FB_FREQ( FB_FREQ_TYPE type, FREQ_VALUE_TYPE value )
00169 : _type( type ), _value( value ) { }
00170 #endif
00171
00172
00173 public:
00174
00175
00176 #if defined(TARG_SL) && defined(__SL__)
00177 FB_FREQ()
00178 : _type( FB_FREQ_TYPE_UNINIT ),
00179 _value( FREQ_SET_OFFSET((FREQ_VALUE_TYPE) FB_FREQ_TYPE_UNINIT) ) {}
00180
00181 FB_FREQ( FREQ_VALUE_TYPE value, bool exact )
00182 : _type( exact ? FB_FREQ_TYPE_EXACT : FB_FREQ_TYPE_GUESS ),
00183 _value( FREQ_SET_OFFSET(value))
00184 { Is_True( value >= 0, ( "FB_FREQ: negative value %ld", value ) ); }
00185 FB_FREQ( INT32 value )
00186 : _type( FB_FREQ_TYPE_EXACT ),
00187 _value( FREQ_SET_OFFSET((FREQ_VALUE_TYPE) value))
00188 { Is_True( value >= 0, ( "FB_FREQ: negative value %ld", value ) ); }
00189 FB_FREQ( FREQ_VALUE_TYPE value )
00190 : _type( FB_FREQ_TYPE_EXACT ),
00191 _value(FREQ_SET_OFFSET(value))
00192 { Is_True( value >= 0, ( "FB_FREQ: negative value %ld", value ) ); }
00193
00194 FB_FREQ( FB_FREQ_TYPE type )
00195 : _type( type ),
00196 _value( type >= 0 ? FREQ_SET_OFFSET(0) : FREQ_SET_OFFSET((FREQ_VALUE_TYPE) type) ) {
00197 Is_True( FB_FREQ_TYPE_IS_VALID( type ),
00198 ( "FB_FREQ: invalid type %d", type ) );
00199 }
00200 #else
00201
00202 FB_FREQ()
00203 : _type( FB_FREQ_TYPE_UNINIT ),
00204 _value( (FREQ_VALUE_TYPE) FB_FREQ_TYPE_UNINIT ) {}
00205
00206 FB_FREQ( float value, bool exact )
00207 : _type( exact ? FB_FREQ_TYPE_EXACT : FB_FREQ_TYPE_GUESS ),
00208 _value( value )
00209 { Is_True( value >= 0.0, ( "FB_FREQ: negative value %f", value ) ); }
00210
00211 FB_FREQ( INT32 value )
00212 : _type( FB_FREQ_TYPE_EXACT ),
00213 _value( (FREQ_VALUE_TYPE) value )
00214 { Is_True( value >= 0, ( "FB_FREQ: negative value %lld", value ) ); }
00215
00216 #ifdef KEY
00217 FB_FREQ( double value )
00218 : _type( FB_FREQ_TYPE_EXACT ),
00219 _value( (FREQ_VALUE_TYPE) value )
00220 { Is_True( value >= 0.0, ( "FB_FREQ: negative value %lld", value ) ); }
00221
00222 FB_FREQ( float value )
00223 : _type( FB_FREQ_TYPE_EXACT ),
00224 _value( value )
00225 { Is_True( value >= 0.0, ( "FB_FREQ: negative value %lld", value ) ); }
00226 #endif
00227
00228 FB_FREQ( INT64 value )
00229 : _type( FB_FREQ_TYPE_EXACT ),
00230 _value( (FREQ_VALUE_TYPE) value )
00231 { Is_True( value >= 0, ( "FB_FREQ: negative value %lld", value ) ); }
00232
00233 FB_FREQ( FB_FREQ_TYPE type )
00234 : _type( type ),
00235 _value( type >= 0 ? 0.0 : (FREQ_VALUE_TYPE) type ) {
00236 Is_True( FB_FREQ_TYPE_IS_VALID( type ),
00237 ( "FB_FREQ: invalid type %d", type ) );
00238 }
00239 #endif
00240
00241
00242 FREQ_VALUE_TYPE Value() const { return _value; }
00243 FREQ_VALUE_TYPE& Get_Value() { return _value; }
00244 void Set_Value(FREQ_VALUE_TYPE val) { _value=val; }
00245
00246 #if defined(TARG_SL) && defined(__SL__)
00247
00248 friend FB_FREQ operator+ ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00249 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type );
00250 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) )
00251 return FB_FREQ( type );
00252 return FB_FREQ( type, FREQ_RESET_OFFSET(freq1._value) +FREQ_RESET_OFFSET( freq2._value));
00253 }
00254
00255 FB_FREQ operator+= ( const FB_FREQ freq ) {
00256 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type );
00257 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) )
00258 _value = FREQ_SET_OFFSET((FREQ_VALUE_TYPE) _type);
00259 else
00260 _value += FREQ_RESET_OFFSET(freq._value) ;
00261 return *this;
00262 }
00263
00264 void Print( FILE *fp ) const {
00265 switch ( _type ) {
00266 case FB_FREQ_TYPE_EXACT:
00267 fprintf( fp, "%d!", _value );
00268 break;
00269 case FB_FREQ_TYPE_GUESS:
00270 fprintf( fp, "%d?", _value );
00271 break;
00272 case FB_FREQ_TYPE_UNKNOWN:
00273 fprintf( fp, "unknown" );
00274 break;
00275 case FB_FREQ_TYPE_UNINIT:
00276 fprintf( fp, "uninitialized" );
00277 break;
00278 case FB_FREQ_TYPE_ERROR:
00279 fprintf( fp, "error" );
00280 break;
00281 default:
00282 Is_True( FALSE, ("FB_FREQ: Unexpected type %d", _type ));
00283 break;
00284 }
00285 }
00286
00287 void Print_simple (FILE * fp) const {
00288 fprintf(fp, "_type = %d | _value = %f \n", _type, _value);
00289 }
00290
00291 #else
00292
00293
00294
00295 bool Known() const { return FB_FREQ_TYPE_IS_KNOWN( _type ); }
00296 bool Guess() const { return FB_FREQ_TYPE_IS_GUESS( _type ); }
00297 bool Exact() const { return FB_FREQ_TYPE_IS_EXACT( _type ); }
00298 bool Uninitialized() const { return ( _type == FB_FREQ_TYPE_UNINIT ); }
00299 bool Initialized() const { return FB_FREQ_TYPE_INITIALIZED( _type ); }
00300 bool Error() const { return ( _type == FB_FREQ_TYPE_ERROR ); }
00301 bool Zero() const { return ( _value < FB_FREQ_EPSILON &&
00302 _value > - FB_FREQ_EPSILON ); }
00303
00304 bool Better( const FB_FREQ freq ) const {
00305 return FB_FREQ_TYPE_BETTER( _type, freq._type );
00306 }
00307
00308
00309
00310 FB_FREQ operator+= ( const FB_FREQ freq ) {
00311 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type );
00312 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) )
00313 _value = (FREQ_VALUE_TYPE) _type;
00314 else
00315 _value += freq._value;
00316 return *this;
00317 }
00318
00319 FB_FREQ operator-= ( const FB_FREQ freq ) {
00320 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type );
00321 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) )
00322 _value = (FREQ_VALUE_TYPE) _type;
00323 else {
00324 _value -= freq._value;
00325 if ( _value < 0 )
00326 if ( - _value < FB_FREQ_EPSILON
00327 || - _value < FB_FREQ_EPSILON * freq._value )
00328 _value = 0;
00329 else {
00330 DevWarn( "FB_FREQ: subtraction of larger from smaller value" );
00331 _type = FB_FREQ_TYPE_ERROR;
00332 _value = (FREQ_VALUE_TYPE) _type;
00333 }
00334 }
00335 return *this;
00336 }
00337
00338 FB_FREQ operator*= ( const FB_FREQ freq ) {
00339 if ( Zero() && Exact() )
00340 ;
00341 else if ( freq.Zero() && freq.Exact() ) {
00342 _type = FB_FREQ_TYPE_EXACT;
00343 _value = 0.0;
00344 } else {
00345 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type );
00346 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) )
00347 _value = (FREQ_VALUE_TYPE) _type;
00348 else
00349 _value *= freq._value;
00350 }
00351 return *this;
00352 }
00353
00354
00355 FB_FREQ operator*= ( const FREQ_VALUE_TYPE scale ) {
00356 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) );
00357 return ( *this *= FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) );
00358 }
00359
00360
00361
00362 FB_FREQ operator/= ( const FB_FREQ freq ) {
00363 if ( Zero() && Exact() )
00364 ;
00365 else if ( freq.Zero() ) {
00366 DevWarn("FB_FREQ: division by zero");
00367 _type = FB_FREQ_TYPE_ERROR;
00368 _value = (FREQ_VALUE_TYPE) _type;
00369 } else {
00370 _type = FB_FREQ_TYPE_COMBINE( _type, freq._type );
00371 if ( FB_FREQ_TYPE_NOT_KNOWN( _type ) )
00372 _value = (FREQ_VALUE_TYPE) _type;
00373 else {
00374 if ( _value != freq._value )
00375 _type = FB_FREQ_TYPE_COMBINE( _type, FB_FREQ_TYPE_GUESS );
00376 _value /= freq._value;
00377 }
00378 }
00379 return *this;
00380 }
00381
00382
00383 FB_FREQ operator/= ( const FREQ_VALUE_TYPE scale ) {
00384 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) );
00385 return ( *this /= FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) );
00386 }
00387
00388
00389
00390 friend FB_FREQ operator+ ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00391 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type );
00392 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) )
00393 return FB_FREQ( type );
00394 return FB_FREQ( type, freq1._value + freq2._value );
00395 }
00396
00397 friend FB_FREQ operator- ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00398 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type );
00399 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) )
00400 return FB_FREQ( type );
00401 FREQ_VALUE_TYPE value = freq1._value - freq2._value;
00402 if ( value >= 0 )
00403 return FB_FREQ( type, value );
00404 if ( - value < FB_FREQ_EPSILON
00405 || - value < freq2._value * FB_FREQ_EPSILON )
00406 return FB_FREQ( type, 0 );
00407 DevWarn( "FB_FREQ: subtraction of larger from smaller value" );
00408 return FB_FREQ( FB_FREQ_TYPE_ERROR );
00409 }
00410
00411 friend FB_FREQ operator* ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00412 if ( ( freq1.Zero() && freq1.Exact() ) ||
00413 ( freq2.Zero() && freq2.Exact() ) )
00414 return FB_FREQ( FB_FREQ_TYPE_EXACT, 0.0 );
00415 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type );
00416 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) )
00417 return FB_FREQ( type );
00418 return FB_FREQ( type, freq1._value * freq2._value );
00419 }
00420
00421
00422 friend FB_FREQ operator* ( const FB_FREQ freq, const FREQ_VALUE_TYPE scale ) {
00423 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) );
00424 return ( freq * FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) );
00425 }
00426
00427
00428
00429 friend FB_FREQ operator/ ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00430 if ( freq1.Zero() && freq1.Exact() )
00431 return FB_FREQ( FB_FREQ_TYPE_EXACT, 0.0 );
00432 if ( freq2.Zero() ) {
00433 DevWarn("FB_FREQ: division by zero");
00434 return FB_FREQ( FB_FREQ_TYPE_ERROR );
00435 }
00436 FB_FREQ_TYPE type = FB_FREQ_TYPE_COMBINE( freq1._type, freq2._type );
00437 if ( FB_FREQ_TYPE_NOT_KNOWN( type ) )
00438 return FB_FREQ( type );
00439 if ( freq1._value != freq2._value )
00440 type = FB_FREQ_TYPE_COMBINE( type, FB_FREQ_TYPE_GUESS );
00441 FREQ_VALUE_TYPE value = freq1._value / freq2._value;
00442 return FB_FREQ( type, value );
00443 }
00444
00445
00446 friend FB_FREQ operator/ ( const FB_FREQ freq, FREQ_VALUE_TYPE scale ) {
00447 Is_True ( scale >= 0.0, ( "FB_FREQ: negative scale %f", scale ) );
00448 return ( freq / FB_FREQ( FB_FREQ_TYPE_GUESS, scale ) );
00449 }
00450
00451 friend bool operator== ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00452 if ( freq1._value > freq2._value )
00453 return ( freq1._value < FB_FREQ_EPSILON
00454 || freq1._value * ( 1 - FB_FREQ_EPSILON ) < freq2._value );
00455 else if ( freq1._value < freq2._value )
00456 return ( freq2._value < FB_FREQ_EPSILON
00457 || freq2._value * ( 1 - FB_FREQ_EPSILON ) < freq1._value );
00458 else return true;
00459 }
00460
00461 friend bool operator!= ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00462 if ( freq1._value > freq2._value )
00463 return ( freq1._value >= FB_FREQ_EPSILON
00464 && freq1._value * ( 1 - FB_FREQ_EPSILON ) >= freq2._value );
00465 else if ( freq1._value < freq2._value )
00466 return ( freq2._value >= FB_FREQ_EPSILON
00467 && freq2._value * ( 1 - FB_FREQ_EPSILON ) >= freq1._value );
00468 else return false;
00469 }
00470
00471 friend bool operator> ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00472 return ( freq1._value > freq2._value );
00473 }
00474
00475 friend bool operator< ( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00476 return ( freq1._value < freq2._value );
00477 }
00478
00479 #ifdef KEY // fix problem with g++ 3.2
00480 friend bool operator>=( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00481 return ( freq1._value >= freq2._value );
00482 }
00483
00484 friend bool operator<=( const FB_FREQ freq1, const FB_FREQ freq2 ) {
00485 return ( freq1._value <= freq2._value );
00486 }
00487 #endif
00488
00489
00490
00491 void Print( FILE *fp ) const {
00492 switch ( _type ) {
00493 case FB_FREQ_TYPE_EXACT:
00494 fprintf( fp, "%g!", _value );
00495 break;
00496 case FB_FREQ_TYPE_GUESS:
00497 fprintf( fp, "%g?", _value );
00498 break;
00499 case FB_FREQ_TYPE_UNKNOWN:
00500 fprintf( fp, "unknown" );
00501 break;
00502 case FB_FREQ_TYPE_UNINIT:
00503 fprintf( fp, "uninitialized" );
00504 break;
00505 case FB_FREQ_TYPE_ERROR:
00506 fprintf( fp, "error" );
00507 break;
00508 default:
00509 Is_True( FALSE, ("FB_FREQ: Unexpected type %d", _type ));
00510 break;
00511 }
00512 }
00513
00514 void Print_simple (FILE * fp) const {
00515 fprintf(fp, "_type = %d | _value = %f \n", _type, _value);
00516 }
00517
00518 INT Sprintf( char *buffer ) const {
00519 INT length = 0;
00520 switch ( _type ) {
00521 case FB_FREQ_TYPE_EXACT:
00522 length = sprintf( buffer, "%g!", _value );
00523 break;
00524 case FB_FREQ_TYPE_GUESS:
00525 length = sprintf( buffer, "%g?", _value );
00526 break;
00527 case FB_FREQ_TYPE_UNKNOWN:
00528 length = sprintf( buffer, "unknown" );
00529 break;
00530 case FB_FREQ_TYPE_UNINIT:
00531 length = sprintf( buffer, "uninitialized" );
00532 break;
00533 case FB_FREQ_TYPE_ERROR:
00534 length = sprintf( buffer, "error" );
00535 break;
00536 default:
00537 Is_True( FALSE, ("FB_FREQ: Unexpected type %d", _type ));
00538 break;
00539 }
00540 return length;
00541 }
00542 #endif
00543 };
00544
00545
00546
00547
00548 const FB_FREQ FB_FREQ_ZERO( 0, true );
00549 const FB_FREQ FB_FREQ_UNKNOWN( FB_FREQ_TYPE_UNKNOWN );
00550 const FB_FREQ FB_FREQ_UNINIT( FB_FREQ_TYPE_UNINIT );
00551 const FB_FREQ FB_FREQ_ERROR( FB_FREQ_TYPE_ERROR );
00552
00553
00554
00555 #endif //#ifndef fb_freq_INCLUDED