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 #include "systemc/datatypes/fx/scfx_rep.h"
00039
00040 #include "systemc/datatypes/fx/scfx_ieee.h"
00041 #include "systemc/datatypes/fx/scfx_pow10.h"
00042 #include "systemc/datatypes/fx/scfx_utils.h"
00043
00044 #include "systemc/datatypes/bit/sc_bv_base.h"
00045
00046 #include <ctype.h>
00047 #include <math.h>
00048
00049
00050 namespace sc_dt
00051 {
00052
00053
00054
00055
00056
00057 static scfx_pow10 pow10_fx;
00058
00059 static const int mantissa0_size = SCFX_IEEE_DOUBLE_M_SIZE - bits_in_int;
00060
00061 static inline
00062 int
00063 n_word( int x )
00064 {
00065 return ( x + bits_in_word - 1 ) / bits_in_word;
00066 }
00067
00068
00069
00070
00071
00072
00073 scfx_rep::scfx_rep()
00074 : m_mant( min_mant ), m_r_flag( false )
00075 {
00076 set_zero();
00077 }
00078
00079 scfx_rep::scfx_rep( int a )
00080 : m_mant( min_mant ), m_r_flag( false )
00081 {
00082 if( a != 0 )
00083 {
00084 m_mant.clear();
00085 m_wp = m_msw = m_lsw = 2;
00086 m_state = normal;
00087 if( a > 0 )
00088 {
00089 m_mant[2] = a;
00090 m_sign = 1;
00091 }
00092 else
00093 {
00094 m_mant[2] = -a;
00095 m_sign = -1;
00096 }
00097 }
00098 else
00099 set_zero();
00100 }
00101
00102 scfx_rep::scfx_rep( unsigned int a )
00103 : m_mant( min_mant ), m_r_flag( false )
00104 {
00105 if( a != 0 )
00106 {
00107 m_mant.clear();
00108 m_wp = m_msw = m_lsw = 2;
00109 m_state = normal;
00110 m_mant[2] = a;
00111 m_sign = 1;
00112 }
00113 else
00114 set_zero();
00115 }
00116
00117 scfx_rep::scfx_rep( long a )
00118 : m_mant( min_mant ), m_r_flag( false )
00119 {
00120 if( a != 0 )
00121 {
00122 m_mant.clear();
00123 m_wp = m_msw = m_lsw = 2;
00124 m_state = normal;
00125 if( a > 0 )
00126 {
00127 m_mant[2] = a;
00128 m_sign = 1;
00129 }
00130 else
00131 {
00132 m_mant[2] = -a;
00133 m_sign = -1;
00134 }
00135 }
00136 else
00137 set_zero();
00138 }
00139
00140 scfx_rep::scfx_rep( unsigned long a )
00141 : m_mant( min_mant ), m_r_flag( false )
00142 {
00143 if( a != 0 )
00144 {
00145 m_mant.clear();
00146 m_wp = m_msw = m_lsw = 2;
00147 m_state = normal;
00148 m_mant[2] = a;
00149 m_sign = 1;
00150 }
00151 else
00152 set_zero();
00153 }
00154
00155 scfx_rep::scfx_rep( double a )
00156 : m_mant( min_mant ), m_wp( 0 ), m_state( normal ), m_msw( 0 ), m_lsw( 0 ),
00157 m_r_flag( false )
00158 {
00159 m_mant.clear();
00160
00161 scfx_ieee_double id( a );
00162
00163 m_sign = id.negative() ? -1 : 1;
00164
00165 if( id.is_nan() )
00166 m_state = not_a_number;
00167 else if( id.is_inf() )
00168 m_state = infinity;
00169 else if( id.is_subnormal() )
00170 {
00171 m_mant[0] = id.mantissa1();
00172 m_mant[1] = id.mantissa0();
00173 normalize( id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE );
00174 }
00175 else if( id.is_normal() )
00176 {
00177 m_mant[0] = id.mantissa1();
00178 m_mant[1] = id.mantissa0() | ( 1 << mantissa0_size );
00179 normalize( id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE );
00180 }
00181 }
00182
00183 scfx_rep::scfx_rep( int64 a )
00184 : m_mant( min_mant ), m_r_flag( false )
00185 {
00186 if( a != 0 )
00187 {
00188 m_mant.clear();
00189 m_wp = 1;
00190 m_state = normal;
00191 if( a > 0 )
00192 {
00193 m_mant[1] = static_cast<word>( a );
00194 m_mant[2] = static_cast<word>( a >> bits_in_word );
00195 m_sign = 1;
00196 }
00197 else
00198 {
00199 m_mant[1] = static_cast<word>( -a );
00200 m_mant[2] = static_cast<word>( (-a) >> bits_in_word );
00201 m_sign = -1;
00202 }
00203 find_sw();
00204 }
00205 else
00206 set_zero();
00207 }
00208
00209 scfx_rep::scfx_rep( uint64 a )
00210 : m_mant( min_mant ), m_r_flag( false )
00211 {
00212 if( a != 0 )
00213 {
00214 m_mant.clear();
00215 m_wp = 1;
00216 m_state = normal;
00217 m_mant[1] = static_cast<word>( a );
00218 m_mant[2] = static_cast<word>( a >> bits_in_word );
00219 m_sign = 1;
00220 find_sw();
00221 }
00222 else
00223 set_zero();
00224 }
00225
00226 scfx_rep::scfx_rep( const sc_signed& a )
00227 : m_mant( min_mant ), m_r_flag( false )
00228 {
00229 if( a.iszero() )
00230 set_zero();
00231 else
00232 {
00233 int words = n_word( a.length() );
00234 if( words > size() )
00235 resize_to( words );
00236 m_mant.clear();
00237 m_wp = 0;
00238 m_state = normal;
00239 if( a.sign() )
00240 {
00241 sc_signed a2 = -a;
00242 for( int i = 0; i < a2.length(); ++ i )
00243 {
00244 if( a2[i] )
00245 {
00246 scfx_index x = calc_indices( i );
00247 m_mant[x.wi()] |= 1 << x.bi();
00248 }
00249 }
00250 m_sign = -1;
00251 }
00252 else
00253 {
00254 for( int i = 0; i < a.length(); ++ i )
00255 {
00256 if( a[i] )
00257 {
00258 scfx_index x = calc_indices( i );
00259 m_mant[x.wi()] |= 1 << x.bi();
00260 }
00261 }
00262 m_sign = 1;
00263 }
00264 find_sw();
00265 }
00266 }
00267
00268 scfx_rep::scfx_rep( const sc_unsigned& a )
00269 : m_mant( min_mant ), m_r_flag( false )
00270 {
00271 if( a.iszero() )
00272 set_zero();
00273 else
00274 {
00275 int words = n_word( a.length() );
00276 if( words > size() )
00277 resize_to( words );
00278 m_mant.clear();
00279 m_wp = 0;
00280 m_state = normal;
00281 for( int i = 0; i < a.length(); ++ i )
00282 {
00283 if( a[i] )
00284 {
00285 scfx_index x = calc_indices( i );
00286 m_mant[x.wi()] |= 1 << x.bi();
00287 }
00288 }
00289 m_sign = 1;
00290 find_sw();
00291 }
00292 }
00293
00294
00295
00296
00297 scfx_rep::scfx_rep( const scfx_rep& a )
00298 : m_mant( a.m_mant ), m_wp( a.m_wp ), m_sign( a.m_sign ), m_state( a.m_state ),
00299 m_msw( a.m_msw ), m_lsw( a.m_lsw ), m_r_flag( false )
00300 {}
00301
00302
00303
00304
00305
00306
00307
00308
00309 union scfx_rep_node
00310 {
00311 char data[sizeof( scfx_rep )];
00312 scfx_rep_node* next;
00313 };
00314
00315
00316 static scfx_rep_node* list = 0;
00317
00318
00319 void*
00320 scfx_rep::operator new( size_t size )
00321 {
00322 const int ALLOC_SIZE = 1024;
00323
00324 if( size != sizeof( scfx_rep ) )
00325 return ::operator new( size );
00326
00327 if( ! list )
00328 {
00329 list = new scfx_rep_node[ALLOC_SIZE];
00330 for( int i = 0; i < ALLOC_SIZE - 1; i ++ )
00331 list[i].next = list + i + 1;
00332 list[ALLOC_SIZE - 1].next = 0;
00333 }
00334
00335 scfx_rep* ptr = reinterpret_cast<scfx_rep*>( list->data );
00336 list = list->next;
00337
00338 return ptr;
00339 }
00340
00341
00342 void scfx_rep::operator delete( void* ptr, size_t size )
00343 {
00344 if( size != sizeof( scfx_rep ) )
00345 {
00346 ::operator delete( ptr );
00347 return;
00348 }
00349
00350 scfx_rep_node* node = static_cast<scfx_rep_node*>( ptr );
00351 node->next = list;
00352 list = node;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362 #define SCFX_FAIL_IF_(cnd) \
00363 { \
00364 if( ( cnd ) ) \
00365 { \
00366 m_state = not_a_number; \
00367 m_mant.clear(); \
00368 return; \
00369 } \
00370 }
00371
00372
00373 void
00374 scfx_rep::from_string( const char* s, int cte_wl )
00375 {
00376 SCFX_FAIL_IF_( s == 0 || *s == 0 );
00377
00378 scfx_string s2;
00379 s2 += s;
00380 s2 += '\0';
00381
00382 bool sign_char;
00383 m_sign = scfx_parse_sign( s, sign_char );
00384
00385 sc_numrep numrep = scfx_parse_prefix( s );
00386
00387 int base = 0;
00388
00389 switch( numrep )
00390 {
00391 case SC_DEC:
00392 {
00393 base = 10;
00394 if( scfx_is_nan( s ) )
00395 {
00396 m_state = not_a_number;
00397 m_mant.clear();
00398 return;
00399 }
00400 if( scfx_is_inf( s ) )
00401 {
00402 m_state = infinity;
00403 m_mant.clear();
00404 return;
00405 }
00406 break;
00407 }
00408 case SC_BIN:
00409 case SC_BIN_US:
00410 {
00411 SCFX_FAIL_IF_( sign_char );
00412 base = 2;
00413 break;
00414 }
00415
00416 case SC_BIN_SM:
00417 {
00418 base = 2;
00419 break;
00420 }
00421 case SC_OCT:
00422 case SC_OCT_US:
00423 {
00424 SCFX_FAIL_IF_( sign_char );
00425 base = 8;
00426 break;
00427 }
00428 case SC_OCT_SM:
00429 {
00430 base = 8;
00431 break;
00432 }
00433 case SC_HEX:
00434 case SC_HEX_US:
00435 {
00436 SCFX_FAIL_IF_( sign_char );
00437 base = 16;
00438 break;
00439 }
00440 case SC_HEX_SM:
00441 {
00442 base = 16;
00443 break;
00444 }
00445 case SC_CSD:
00446 {
00447 SCFX_FAIL_IF_( sign_char );
00448 base = 2;
00449 scfx_csd2tc( s2 );
00450 s = (const char*) s2 + 4;
00451 numrep = SC_BIN;
00452 break;
00453 }
00454 default:;
00455 }
00456
00457
00458
00459
00460
00461 const char *end = s;
00462 bool based_point = false;
00463 int int_digits = 0;
00464 int frac_digits = 0;
00465
00466 while( *end )
00467 {
00468 if( scfx_exp_start( end ) )
00469 break;
00470
00471 if( *end == '.' )
00472 {
00473 SCFX_FAIL_IF_( based_point );
00474 based_point = true;
00475 }
00476 else
00477 {
00478 SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) );
00479 if( based_point )
00480 frac_digits ++;
00481 else
00482 int_digits ++;
00483 }
00484
00485 ++ end;
00486 }
00487
00488 SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 );
00489
00490
00491
00492 int exponent = 0;
00493
00494 if( *end )
00495 {
00496 for( const char *e = end + 2; *e; ++ e )
00497 SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) );
00498 exponent = atoi( end + 1 );
00499 }
00500
00501
00502
00503
00504
00505 bool mant_is_neg = false;
00506
00507 switch( numrep )
00508 {
00509 case SC_BIN:
00510 case SC_OCT:
00511 case SC_HEX:
00512 {
00513 const char* p = s;
00514 if( *p == '.' )
00515 ++ p;
00516
00517 mant_is_neg = ( scfx_to_digit( *p, numrep ) >= ( base >> 1 ) );
00518
00519 break;
00520 }
00521 default:
00522 ;
00523 }
00524
00525
00526
00527
00528
00529 switch( base )
00530 {
00531 case 2:
00532 {
00533 int bit_offset = exponent % bits_in_word;
00534 int word_offset = exponent / bits_in_word;
00535
00536 int_digits += bit_offset;
00537 frac_digits -= bit_offset;
00538
00539 int words = n_word( int_digits ) + n_word( frac_digits );
00540 if( words > size() )
00541 resize_to( words );
00542 m_mant.clear();
00543
00544 int j = n_word( frac_digits ) * bits_in_word + int_digits - 1;
00545
00546 for( ; s < end; s ++ )
00547 {
00548 switch( *s )
00549 {
00550 case '1':
00551 set_bin( j );
00552 case '0':
00553 j --;
00554 case '.':
00555 break;
00556 default:
00557 SCFX_FAIL_IF_( true );
00558 }
00559 }
00560
00561 m_wp = n_word( frac_digits ) - word_offset;
00562 break;
00563 }
00564 case 8:
00565 {
00566 exponent *= 3;
00567 int_digits *= 3;
00568 frac_digits *= 3;
00569
00570 int bit_offset = exponent % bits_in_word;
00571 int word_offset = exponent / bits_in_word;
00572
00573 int_digits += bit_offset;
00574 frac_digits -= bit_offset;
00575
00576 int words = n_word( int_digits ) + n_word( frac_digits );
00577 if( words > size() )
00578 resize_to( words );
00579 m_mant.clear();
00580
00581 int j = n_word( frac_digits ) * bits_in_word + int_digits - 3;
00582
00583 for( ; s < end; s ++ )
00584 {
00585 switch( *s )
00586 {
00587 case '7': case '6': case '5': case '4':
00588 case '3': case '2': case '1':
00589 set_oct( j, *s - '0' );
00590 case '0':
00591 j -= 3;
00592 case '.':
00593 break;
00594 default:
00595 SCFX_FAIL_IF_( true );
00596 }
00597 }
00598
00599 m_wp = n_word( frac_digits ) - word_offset;
00600 break;
00601 }
00602 case 10:
00603 {
00604 unsigned long carry, temp;
00605 int length = int_digits + frac_digits;
00606 resize_to( sc_max( min_mant, n_word( 4 * length ) ) );
00607
00608 m_mant.clear();
00609 m_msw = m_lsw = 0;
00610
00611 for( ; s < end; s ++ )
00612 {
00613 switch( *s )
00614 {
00615 case '9': case '8': case '7': case '6': case '5':
00616 case '4': case '3': case '2': case '1': case '0':
00617 multiply_by_ten();
00618 carry = *s - '0';
00619 for ( int i = 0; carry && i < m_mant.size(); i++ )
00620 {
00621 temp = m_mant[i];
00622 temp += carry;
00623 carry = temp < m_mant[i];
00624 m_mant[i] = temp;
00625 }
00626 case '.':
00627 break;
00628 default:
00629 SCFX_FAIL_IF_( true );
00630 }
00631 }
00632
00633 m_wp = 0;
00634 find_sw();
00635
00636 int denominator = frac_digits - exponent;
00637
00638 if( denominator )
00639 {
00640 scfx_rep frac_num = pow10_fx( denominator );
00641 scfx_rep* temp_num =
00642 div_scfx_rep( const_cast<const scfx_rep&>( *this ),
00643 frac_num, cte_wl );
00644 *this = *temp_num;
00645 delete temp_num;
00646 }
00647
00648 break;
00649 }
00650 case 16:
00651 {
00652 exponent *= 4;
00653 int_digits *= 4;
00654 frac_digits *= 4;
00655
00656 int bit_offset = exponent % bits_in_word;
00657 int word_offset = exponent / bits_in_word;
00658
00659 int_digits += bit_offset;
00660 frac_digits -= bit_offset;
00661
00662 int words = n_word( int_digits ) + n_word( frac_digits );
00663 if( words > size() )
00664 resize_to( words );
00665 m_mant.clear();
00666
00667 int j = n_word( frac_digits ) * bits_in_word + int_digits - 4;
00668
00669 for( ; s < end; s ++ )
00670 {
00671 switch( *s )
00672 {
00673 case 'f': case 'e': case 'd': case 'c': case 'b': case 'a':
00674 set_hex( j, *s - 'a' + 10 );
00675 j -= 4;
00676 break;
00677 case 'F': case 'E': case 'D': case 'C': case 'B': case 'A':
00678 set_hex( j, *s - 'A' + 10 );
00679 j -= 4;
00680 break;
00681 case '9': case '8': case '7': case '6': case '5':
00682 case '4': case '3': case '2': case '1':
00683 set_hex( j, *s - '0' );
00684 case '0':
00685 j -= 4;
00686 case '.':
00687 break;
00688 default:
00689 SCFX_FAIL_IF_( true );
00690 }
00691 }
00692
00693 m_wp = n_word( frac_digits ) - word_offset;
00694 break;
00695 }
00696 }
00697
00698 m_state = normal;
00699 find_sw();
00700
00701
00702
00703
00704
00705 if( mant_is_neg )
00706 {
00707 m_mant[m_msw] |= -1 << scfx_find_msb( m_mant[m_msw] );
00708 for( int i = m_msw + 1; i < m_mant.size(); ++ i )
00709 m_mant[i] = static_cast<word>( -1 );
00710 complement( m_mant, m_mant, m_mant.size() );
00711 inc( m_mant );
00712 m_sign *= -1;
00713 find_sw();
00714 }
00715 }
00716
00717
00718 #undef SCFX_FAIL_IF_
00719
00720
00721
00722
00723
00724
00725
00726
00727 double
00728 scfx_rep::to_double() const
00729 {
00730 scfx_ieee_double id;
00731
00732
00733
00734 if( is_nan() )
00735 {
00736 id.set_nan();
00737 return id;
00738 }
00739
00740 if( is_inf() )
00741 {
00742 id.set_inf();
00743 id.negative( m_sign < 0 );
00744 return id;
00745 }
00746
00747 if( is_zero() )
00748 {
00749 id = 0.;
00750 id.negative( m_sign < 0 );
00751 return id;
00752 }
00753
00754 int msb = scfx_find_msb( m_mant[m_msw] );
00755
00756 int exp = (m_msw - m_wp) * bits_in_word + msb;
00757
00758 if( exp > SCFX_IEEE_DOUBLE_E_MAX )
00759 {
00760 id.set_inf();
00761 id.negative( m_sign < 0 );
00762 return id;
00763 }
00764
00765 if( exp < SCFX_IEEE_DOUBLE_E_MIN
00766 - static_cast<int>( SCFX_IEEE_DOUBLE_M_SIZE ) )
00767 {
00768 id = 0.;
00769 return id;
00770 }
00771
00772 int shift = mantissa0_size - msb;
00773
00774 unsigned int m0;
00775 unsigned int m1 = 0;
00776 unsigned int guard = 0;
00777
00778 if( shift == 0 )
00779 {
00780 m0 = m_mant[m_msw] & ~( 1 << mantissa0_size );
00781 if( m_msw > m_lsw )
00782 {
00783 m1 = m_mant[m_msw - 1];
00784 if( m_msw - 1 > m_lsw )
00785 guard = m_mant[m_msw - 2] >> ( bits_in_word - 1 );
00786 }
00787 }
00788 else if( shift < 0 )
00789 {
00790 m0 = ( m_mant[m_msw] >> -shift ) & ~( 1 << mantissa0_size );
00791 m1 = m_mant[m_msw] << ( bits_in_word + shift );
00792 if( m_msw > m_lsw )
00793 {
00794 m1 |= m_mant[m_msw - 1] >> -shift;
00795 guard = ( m_mant[m_msw - 1] >> ( -shift - 1 ) ) & 1;
00796 }
00797 }
00798 else
00799 {
00800 m0 = ( m_mant[m_msw] << shift ) & ~( 1 << mantissa0_size );
00801 if( m_msw > m_lsw )
00802 {
00803 m0 |= m_mant[m_msw - 1] >> ( bits_in_word - shift );
00804 m1 = m_mant[m_msw - 1] << shift;
00805 if( m_msw - 1 > m_lsw )
00806 {
00807 m1 |= m_mant[m_msw - 2] >> ( bits_in_word - shift );
00808 guard = ( m_mant[m_msw - 2] >> (bits_in_word - shift - 1) )
00809 & 1;
00810 }
00811 }
00812 }
00813
00814 if( exp < SCFX_IEEE_DOUBLE_E_MIN )
00815 {
00816 m0 |= ( 1 << mantissa0_size );
00817
00818 int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp;
00819
00820 if( subnormal_shift < bits_in_word )
00821 {
00822 m1 = m1 >> subnormal_shift
00823 | m0 << ( bits_in_word - subnormal_shift );
00824 m0 = m0 >> subnormal_shift;
00825 }
00826 else
00827 {
00828 m1 = m0 >> ( subnormal_shift - bits_in_word );
00829 m0 = 0;
00830 }
00831
00832 guard = 0;
00833
00834 exp = SCFX_IEEE_DOUBLE_E_MIN - 1;
00835 }
00836
00837 id.mantissa0( m0 );
00838 id.mantissa1( m1 );
00839 id.exponent( exp );
00840 id.negative( m_sign < 0 );
00841
00842 double result = id;
00843
00844 if( guard != 0 )
00845 result += m_sign * scfx_pow2( exp - SCFX_IEEE_DOUBLE_M_SIZE );
00846
00847 return result;
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857 void
00858 print_dec( scfx_string& s, const scfx_rep& num, int w_prefix, sc_fmt fmt )
00859 {
00860 if( num.is_neg() )
00861 s += '-';
00862
00863 if( w_prefix == 1 ) {
00864 scfx_print_prefix( s, SC_DEC );
00865 }
00866
00867 if( num.is_zero() )
00868 {
00869 s += '0';
00870 return;
00871 }
00872
00873
00874
00875 scfx_rep int_part = num;
00876 scfx_rep frac_part = num;
00877
00878 int i;
00879
00880 for( i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i ++ )
00881 int_part.m_mant[i] = 0;
00882 int_part.find_sw();
00883 if( int_part.m_wp < int_part.m_lsw )
00884 int_part.resize_to( int_part.size() - int_part.m_wp, -1 );
00885
00886 for( i = frac_part.m_msw;
00887 i >= frac_part.m_lsw && i >= frac_part.m_wp;
00888 i -- )
00889 frac_part.m_mant[i] = 0;
00890 frac_part.find_sw();
00891 if( frac_part.m_msw == frac_part.size() - 1 )
00892 frac_part.resize_to( frac_part.size() + 1, 1 );
00893
00894
00895
00896 int int_digits = 0;
00897 int int_zeros = 0;
00898
00899 if( ! int_part.is_zero() )
00900 {
00901 double int_wl = ( int_part.m_msw - int_part.m_wp ) * bits_in_word
00902 + scfx_find_msb( int_part.m_mant[int_part.m_msw] ) + 1;
00903 int_digits = (int) ceil( int_wl * log10( 2. ) );
00904
00905 int len = s.length();
00906 s.append( int_digits );
00907
00908 bool zero_digits = ( frac_part.is_zero() && fmt != SC_F );
00909
00910 for( i = int_digits + len - 1; i >= len; i-- )
00911 {
00912 unsigned int remainder = int_part.divide_by_ten();
00913 s[i] = static_cast<char>( '0' + remainder );
00914
00915 if( zero_digits )
00916 {
00917 if( remainder == 0 )
00918 int_zeros ++;
00919 else
00920 zero_digits = false;
00921 }
00922 }
00923
00924
00925 s.discard( int_zeros );
00926
00927 if( s[len] == '0' )
00928 {
00929
00930 s.remove( len );
00931 -- int_digits;
00932 }
00933 }
00934
00935
00936
00937 int frac_digits = 0;
00938 int frac_zeros = 0;
00939
00940 if( ! frac_part.is_zero() )
00941 {
00942 s += '.';
00943
00944 bool zero_digits = ( int_digits == 0 && fmt != SC_F );
00945
00946 double frac_wl = ( frac_part.m_wp - frac_part.m_msw ) * bits_in_word
00947 - scfx_find_msb( frac_part.m_mant[frac_part.m_msw] )
00948 - 1;
00949 frac_zeros = (int) floor( frac_wl * log10( 2. ) );
00950
00951 scfx_rep temp;
00952 sc_dt::multiply( temp, frac_part, pow10_fx( frac_zeros ) );
00953 frac_part = temp;
00954 if( frac_part.m_msw == frac_part.size() - 1 )
00955 frac_part.resize_to( frac_part.size() + 1, 1 );
00956
00957 frac_digits = frac_zeros;
00958 if( ! zero_digits )
00959 {
00960 for( i = 0; i < frac_zeros; i ++ )
00961 s += '0';
00962 frac_zeros = 0;
00963 }
00964
00965 while( ! frac_part.is_zero() )
00966 {
00967 frac_part.multiply_by_ten();
00968 int n = frac_part.m_mant[frac_part.m_msw + 1];
00969
00970 if( zero_digits )
00971 {
00972 if( n == 0 )
00973 frac_zeros ++;
00974 else
00975 zero_digits = false;
00976 }
00977
00978 if( ! zero_digits )
00979 s += static_cast<char>( '0' + n );
00980
00981 frac_part.m_mant[frac_part.m_msw + 1] = 0;
00982 frac_digits ++;
00983 }
00984 }
00985
00986
00987
00988 if( fmt != SC_F )
00989 {
00990 if( frac_digits == 0 )
00991 scfx_print_exp( s, int_zeros );
00992 else if( int_digits == 0 )
00993 scfx_print_exp( s, - frac_zeros );
00994 }
00995 }
00996
00997 void
00998 print_other( scfx_string& s, const scfx_rep& a, sc_numrep numrep, int w_prefix,
00999 sc_fmt fmt, const scfx_params* params )
01000 {
01001 scfx_rep b = a;
01002
01003 sc_numrep numrep2 = numrep;
01004
01005 bool numrep_is_sm = ( numrep == SC_BIN_SM ||
01006 numrep == SC_OCT_SM ||
01007 numrep == SC_HEX_SM );
01008
01009 if( numrep_is_sm )
01010 {
01011 if( b.is_neg() )
01012 {
01013 s += '-';
01014 b = *neg_scfx_rep( a );
01015 }
01016 switch( numrep )
01017 {
01018 case SC_BIN_SM:
01019 numrep2 = SC_BIN_US;
01020 break;
01021 case SC_OCT_SM:
01022 numrep2 = SC_OCT_US;
01023 break;
01024 case SC_HEX_SM:
01025 numrep2 = SC_HEX_US;
01026 break;
01027 default:
01028 ;
01029 }
01030 }
01031
01032 if( w_prefix != 0 ) {
01033 scfx_print_prefix( s, numrep );
01034 }
01035
01036 numrep = numrep2;
01037
01038 int msb, lsb;
01039
01040 if( params != 0 )
01041 {
01042 msb = params->iwl() - 1;
01043 lsb = params->iwl() - params->wl();
01044
01045 if( params->enc() == SC_TC_ &&
01046 ( numrep == SC_BIN_US ||
01047 numrep == SC_OCT_US ||
01048 numrep == SC_HEX_US ) &&
01049 ! numrep_is_sm &&
01050 params->wl() > 1 )
01051 -- msb;
01052 else if( params->enc() == SC_US_ &&
01053 ( numrep == SC_BIN ||
01054 numrep == SC_OCT ||
01055 numrep == SC_HEX ||
01056 numrep == SC_CSD ) )
01057 ++ msb;
01058 }
01059 else
01060 {
01061 if( b.is_zero() )
01062 {
01063 msb = 0;
01064 lsb = 0;
01065 }
01066 else
01067 {
01068 msb = ( b.m_msw - b.m_wp ) * bits_in_word
01069 + scfx_find_msb( b.m_mant[ b.m_msw ] ) + 1;
01070 while( b.get_bit( msb ) == b.get_bit( msb - 1 ) )
01071 -- msb;
01072
01073 if( numrep == SC_BIN_US ||
01074 numrep == SC_OCT_US ||
01075 numrep == SC_HEX_US )
01076 -- msb;
01077
01078 lsb = ( b.m_lsw - b.m_wp ) * bits_in_word
01079 + scfx_find_lsb( b.m_mant[ b.m_lsw ] );
01080 }
01081 }
01082
01083 int step;
01084
01085 switch( numrep )
01086 {
01087 case SC_BIN:
01088 case SC_BIN_US:
01089 case SC_CSD:
01090 step = 1;
01091 break;
01092 case SC_OCT:
01093 case SC_OCT_US:
01094 step = 3;
01095 break;
01096 case SC_HEX:
01097 case SC_HEX_US:
01098 step = 4;
01099 break;
01100 default:
01101 step = 0;
01102 }
01103
01104 msb = (int) ceil( double( msb + 1 ) / step ) * step - 1;
01105
01106 lsb = (int) floor( double( lsb ) / step ) * step;
01107
01108 if( msb < 0 )
01109 {
01110 s += '.';
01111 if( fmt == SC_F )
01112 {
01113 int sign = ( b.is_neg() ) ? ( 1 << step ) - 1 : 0;
01114 for( int i = ( msb + 1 ) / step; i < 0; i ++ )
01115 {
01116 if( sign < 10 )
01117 s += static_cast<char>( sign + '0' );
01118 else
01119 s += static_cast<char>( sign + 'a' - 10 );
01120 }
01121 }
01122 }
01123
01124 int i = msb;
01125 while( i >= lsb )
01126 {
01127 int value = 0;
01128 for( int j = step - 1; j >= 0; -- j )
01129 {
01130 value += static_cast<int>( b.get_bit( i ) ) << j;
01131 -- i;
01132 }
01133 if( value < 10 )
01134 s += static_cast<char>( value + '0' );
01135 else
01136 s += static_cast<char>( value + 'a' - 10 );
01137 if( i == -1 )
01138 s += '.';
01139 }
01140
01141 if( lsb > 0 && fmt == SC_F )
01142 {
01143 for( int i = lsb / step; i > 0; i -- )
01144 s += '0';
01145 }
01146
01147 if( s[s.length() - 1] == '.' )
01148 s.discard( 1 );
01149
01150 if( fmt != SC_F )
01151 {
01152 if( msb < 0 )
01153 scfx_print_exp( s, ( msb + 1 ) / step );
01154 else if( lsb > 0 )
01155 scfx_print_exp( s, lsb / step );
01156 }
01157
01158 if( numrep == SC_CSD )
01159 scfx_tc2csd( s, w_prefix );
01160 }
01161
01162 const char*
01163 scfx_rep::to_string( sc_numrep numrep, int w_prefix,
01164 sc_fmt fmt, const scfx_params* params ) const
01165 {
01166 static scfx_string s;
01167
01168 s.clear();
01169
01170 if( is_nan() )
01171 scfx_print_nan( s );
01172 else if( is_inf() )
01173 scfx_print_inf( s, is_neg() );
01174 else if( is_neg() && ! is_zero() &&
01175 ( numrep == SC_BIN_US ||
01176 numrep == SC_OCT_US ||
01177 numrep == SC_HEX_US ) )
01178 s += "negative";
01179 else if( numrep == SC_DEC )
01180 sc_dt::print_dec( s, *this, w_prefix, fmt );
01181 else
01182 sc_dt::print_other( s, *this, numrep, w_prefix, fmt, params );
01183
01184 return s;
01185 }
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 static inline
01197 int
01198 add_mants( int size, scfx_mant& result,
01199 const scfx_mant& a, const scfx_mant& b )
01200 {
01201 unsigned int carry = 0;
01202
01203 int index = 0;
01204
01205 do
01206 {
01207 word x = a[index];
01208 word y = b[index];
01209
01210 y += carry;
01211 carry = y < carry;
01212 y += x;
01213 carry += y < x;
01214 result[index] = y;
01215 }
01216 while( ++ index < size );
01217
01218 return ( carry ? 1 : 0 );
01219 }
01220
01221
01222 static inline
01223 int
01224 sub_mants( int size, scfx_mant& result,
01225 const scfx_mant& a, const scfx_mant& b )
01226 {
01227 unsigned carry = 0;
01228
01229 int index = 0;
01230
01231 do
01232 {
01233 word x = a[index];
01234 word y = b[index];
01235
01236 y += carry;
01237 carry = y < carry;
01238 y = x - y;
01239 carry += y > x;
01240 result[index] = y;
01241 }
01242 while( ++ index < size );
01243
01244 return ( carry ? 1 : 0 );
01245 }
01246
01247
01248 scfx_rep*
01249 add_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
01250 {
01251 scfx_rep& result = *new scfx_rep;
01252
01253
01254
01255
01256
01257 if( lhs.is_nan() || rhs.is_nan()
01258 || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign ) )
01259 {
01260 result.set_nan();
01261 return &result;
01262 }
01263
01264 if( lhs.is_inf() )
01265 {
01266 result.set_inf( lhs.m_sign );
01267 return &result;
01268 }
01269
01270 if( rhs.is_inf() )
01271 {
01272 result.set_inf( rhs.m_sign );
01273 return &result;
01274 }
01275
01276
01277
01278
01279
01280 scfx_mant_ref lhs_mant;
01281 scfx_mant_ref rhs_mant;
01282
01283 int len_mant = lhs.size();
01284 int new_wp = lhs.m_wp;
01285
01286 align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
01287
01288
01289
01290
01291
01292 result.resize_to( len_mant );
01293 result.m_wp = new_wp;
01294
01295
01296
01297
01298
01299 if( lhs.m_sign == rhs.m_sign )
01300 {
01301 add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01302 result.m_sign = lhs.m_sign;
01303 }
01304 else
01305 {
01306 int cmp = compare_abs( lhs, rhs );
01307
01308 if( cmp == 1 )
01309 {
01310 sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01311 result.m_sign = lhs.m_sign;
01312 }
01313 else if ( cmp == -1 )
01314 {
01315 sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
01316 result.m_sign = rhs.m_sign;
01317 }
01318 else
01319 {
01320 result.m_mant.clear();
01321 result.m_sign = 1;
01322 }
01323 }
01324
01325 result.find_sw();
01326 result.round( max_wl );
01327
01328 return &result;
01329 }
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 static inline
01341 int
01342 sub_with_index( scfx_mant& a, int a_msw, int a_lsw,
01343 const scfx_mant& b, int b_msw, int b_lsw )
01344 {
01345 unsigned carry = 0;
01346
01347 int size = b_msw - b_lsw;
01348 int a_index = a_msw - size;
01349 int b_index = b_msw - size;
01350
01351 do
01352 {
01353 word x = a[a_index];
01354 word y = b[b_index];
01355
01356 y += carry;
01357 carry = y < carry;
01358 y = x - y;
01359 carry += y > x;
01360 a[a_index] = y;
01361
01362 a_index ++;
01363 b_index ++;
01364 }
01365 while( size -- );
01366
01367 if( carry )
01368 {
01369
01370 a[a_msw + 1] = 0;
01371 }
01372
01373 return ( carry ? 1 : 0 );
01374 }
01375
01376
01377 scfx_rep*
01378 sub_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
01379 {
01380 scfx_rep& result = *new scfx_rep;
01381
01382
01383
01384
01385
01386 if( lhs.is_nan() || rhs.is_nan()
01387 || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign ) )
01388 {
01389 result.set_nan();
01390 return &result;
01391 }
01392
01393 if( lhs.is_inf() )
01394 {
01395 result.set_inf( lhs.m_sign );
01396 return &result;
01397 }
01398
01399 if( rhs.is_inf() )
01400 {
01401 result.set_inf( -1 * rhs.m_sign );
01402 return &result;
01403 }
01404
01405
01406
01407
01408
01409 scfx_mant_ref lhs_mant;
01410 scfx_mant_ref rhs_mant;
01411
01412 int len_mant = lhs.size();
01413 int new_wp = lhs.m_wp;
01414
01415 align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
01416
01417
01418
01419
01420
01421 result.resize_to( len_mant );
01422 result.m_wp = new_wp;
01423
01424
01425
01426
01427
01428 if( lhs.m_sign != rhs.m_sign )
01429 {
01430 add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01431 result.m_sign = lhs.m_sign;
01432 }
01433 else
01434 {
01435 int cmp = compare_abs( lhs, rhs );
01436
01437 if( cmp == 1 )
01438 {
01439 sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01440 result.m_sign = lhs.m_sign;
01441 }
01442 else if ( cmp == -1 )
01443 {
01444 sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
01445 result.m_sign = -rhs.m_sign;
01446 } else {
01447 result.m_mant.clear();
01448 result.m_sign = 1;
01449 }
01450 }
01451
01452 result.find_sw();
01453 result.round( max_wl );
01454
01455 return &result;
01456 }
01457
01458
01459
01460
01461
01462
01463 union long_short
01464 {
01465 word l;
01466 struct
01467 {
01468 #if defined( SCFX_BIG_ENDIAN )
01469 half_word u;
01470 half_word l;
01471 #elif defined( SCFX_LITTLE_ENDIAN )
01472 half_word l;
01473 half_word u;
01474 #endif
01475 } s;
01476 };
01477
01478
01479 #if defined( SCFX_BIG_ENDIAN )
01480 static const int half_word_incr = -1;
01481 #elif defined( SCFX_LITTLE_ENDIAN )
01482 static const int half_word_incr = 1;
01483 #endif
01484
01485
01486 void
01487 multiply( scfx_rep& result, const scfx_rep& lhs, const scfx_rep& rhs,
01488 int max_wl )
01489 {
01490
01491
01492
01493
01494 if( lhs.is_nan() || rhs.is_nan()
01495 || lhs.is_inf() && rhs.is_zero()
01496 || lhs.is_zero() && rhs.is_inf() )
01497 {
01498 result.set_nan();
01499 return;
01500 }
01501
01502 if( lhs.is_inf() || rhs.is_inf() )
01503 {
01504 result.set_inf( lhs.m_sign * rhs.m_sign );
01505 return;
01506 }
01507
01508 if( lhs.is_zero() || rhs.is_zero() ) {
01509 result.set_zero( lhs.m_sign * rhs.m_sign );
01510 return;
01511 }
01512
01513
01514
01515
01516
01517 int len_lhs = lhs.m_msw - lhs.m_lsw + 1;
01518 int len_rhs = rhs.m_msw - rhs.m_lsw + 1;
01519
01520 int new_size = sc_max( min_mant, len_lhs + len_rhs );
01521 int new_wp = ( lhs.m_wp - lhs.m_lsw ) + ( rhs.m_wp - rhs.m_lsw );
01522 int new_sign = lhs.m_sign * rhs.m_sign;
01523
01524 result.resize_to( new_size );
01525 result.m_mant.clear();
01526 result.m_wp = new_wp;
01527 result.m_sign = new_sign;
01528 result.m_state = scfx_rep::normal;
01529
01530 half_word *s1 = lhs.m_mant.half_addr( lhs.m_lsw );
01531 half_word *s2 = rhs.m_mant.half_addr( rhs.m_lsw );
01532
01533 half_word *t = result.m_mant.half_addr();
01534
01535 len_lhs <<= 1;
01536 len_rhs <<= 1;
01537
01538 int i1, i2;
01539
01540 for( i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr )
01541 {
01542 register long_short ls;
01543 ls.l = 0;
01544
01545 half_word v1 = s1[i1];
01546
01547 for( i2 = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr )
01548 {
01549 ls.l += v1 * s2[i2];
01550 ls.s.l = ls.s.u + ( ( t[i2] += ls.s.l ) < ls.s.l );
01551 ls.s.u = 0;
01552 }
01553
01554 t[i2] = ls.s.l;
01555 t += half_word_incr;
01556 }
01557
01558 result.find_sw();
01559 result.round( max_wl );
01560 }
01561
01562
01563
01564
01565
01566
01567 scfx_rep*
01568 div_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int div_wl )
01569 {
01570 scfx_rep& result = *new scfx_rep;
01571
01572
01573
01574
01575
01576 if( lhs.is_nan() || rhs.is_nan() || lhs.is_inf() && rhs.is_inf() ||
01577 lhs.is_zero() && rhs.is_zero() )
01578 {
01579 result.set_nan();
01580 return &result;
01581 }
01582
01583 if( lhs.is_inf() || rhs.is_zero() )
01584 {
01585 result.set_inf( lhs.m_sign * rhs.m_sign );
01586 return &result;
01587 }
01588
01589 if( lhs.is_zero() || rhs.is_inf() )
01590 {
01591 result.set_zero( lhs.m_sign * rhs.m_sign );
01592 return &result;
01593 }
01594
01595
01596
01597
01598
01599
01600 div_wl ++;
01601
01602 result.resize_to( sc_max( n_word( div_wl ) + 1, min_mant ) );
01603 result.m_mant.clear();
01604 result.m_sign = lhs.m_sign * rhs.m_sign;
01605
01606 int msb_lhs = scfx_find_msb( lhs.m_mant[lhs.m_msw] )
01607 + ( lhs.m_msw - lhs.m_wp ) * bits_in_word;
01608 int msb_rhs = scfx_find_msb( rhs.m_mant[rhs.m_msw] )
01609 + ( rhs.m_msw - rhs.m_wp ) * bits_in_word;
01610
01611 int msb_res = msb_lhs - msb_rhs;
01612 int to_shift = -msb_res % bits_in_word;
01613 int result_index;
01614
01615 int c = ( msb_res % bits_in_word >= 0 ) ? 1 : 0;
01616
01617 result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word;
01618 result.m_wp = (result.size() - c) - msb_res / bits_in_word;
01619
01620 scfx_rep remainder = lhs;
01621
01622
01623 remainder.lshift( to_shift );
01624
01625
01626 if( remainder.m_msw == remainder.size() - 1 )
01627 remainder.resize_to( remainder.size() + 1, 1 );
01628
01629
01630 int msw_diff = rhs.m_msw - remainder.m_msw;
01631 if (msw_diff > 0)
01632 remainder.resize_to( remainder.size() + msw_diff, -1 );
01633
01634 int counter;
01635
01636 for( counter = div_wl; counter && ! remainder.is_zero(); counter -- )
01637 {
01638 if( compare_msw_ff( rhs, remainder ) <= 0 )
01639 {
01640 result.set_bin( result_index );
01641 sub_with_index( remainder.m_mant, remainder.m_msw, remainder.m_lsw,
01642 rhs.m_mant, rhs.m_msw, rhs.m_lsw );
01643 }
01644 result_index --;
01645 remainder.shift_left( 1 );
01646 remainder.m_lsw = remainder.find_lsw();
01647 }
01648
01649
01650 if( counter == 0 )
01651 {
01652 int index = result_index + 1 - result.m_wp * bits_in_word;
01653
01654 scfx_index x = result.calc_indices( index );
01655 scfx_index x1 = result.calc_indices( index + 1 );
01656
01657 if( result.o_bit_at( x ) && result.o_bit_at( x1 ) )
01658 result.q_incr( x );
01659
01660 result.m_r_flag = true;
01661 }
01662
01663 result.find_sw();
01664
01665 return &result;
01666 }
01667
01668
01669
01670
01671
01672
01673 void
01674 scfx_rep::lshift( int n )
01675 {
01676 if( n == 0 )
01677 return;
01678
01679 if( n < 0 )
01680 {
01681 rshift( -n );
01682 return;
01683 }
01684
01685 if( is_normal() )
01686 {
01687 int shift_bits = n % bits_in_word;
01688 int shift_words = n / bits_in_word;
01689
01690
01691 if( m_msw == size() - 1 &&
01692 scfx_find_msb( m_mant[m_msw] ) >= bits_in_word - shift_bits )
01693 resize_to( size() + 1, 1 );
01694
01695
01696 m_wp -= shift_words;
01697 shift_left( shift_bits );
01698 find_sw();
01699 }
01700 }
01701
01702
01703
01704
01705
01706
01707 void
01708 scfx_rep::rshift( int n )
01709 {
01710 if( n == 0 )
01711 return;
01712
01713 if( n < 0 )
01714 {
01715 lshift( -n );
01716 return;
01717 }
01718
01719 if( is_normal() )
01720 {
01721 int shift_bits = n % bits_in_word;
01722 int shift_words = n / bits_in_word;
01723
01724
01725 if( m_lsw == 0 && scfx_find_lsb( m_mant[m_lsw] ) < shift_bits )
01726 resize_to( size() + 1, -1 );
01727
01728
01729 m_wp += shift_words;
01730 shift_right( shift_bits );
01731 find_sw();
01732 }
01733 }
01734
01735
01736
01737
01738
01739
01740
01741
01742 int
01743 compare_abs( const scfx_rep& a, const scfx_rep& b )
01744 {
01745
01746
01747 word a_word = a.m_mant[a.m_msw];
01748 word b_word = b.m_mant[b.m_msw];
01749
01750 if( a_word == 0 || b_word == 0 )
01751 {
01752 if( a_word != 0 )
01753 return 1;
01754 if( b_word != 0 )
01755 return -1;
01756 return 0;
01757 }
01758
01759
01760
01761 int a_msw = a.m_msw - a.m_wp;
01762 int b_msw = b.m_msw - b.m_wp;
01763
01764 if( a_msw > b_msw )
01765 return 1;
01766
01767 if( a_msw < b_msw )
01768 return -1;
01769
01770
01771
01772 int a_i = a.m_msw;
01773 int b_i = b.m_msw;
01774
01775 while( a_i >= a.m_lsw && b_i >= b.m_lsw )
01776 {
01777 a_word = a.m_mant[a_i];
01778 b_word = b.m_mant[b_i];
01779 if( a_word > b_word )
01780 return 1;
01781 if( a_word < b_word )
01782 return -1;
01783 -- a_i;
01784 -- b_i;
01785 }
01786
01787 bool a_zero = true;
01788 while( a_i >= a.m_lsw )
01789 {
01790 a_zero = a_zero && ( a.m_mant[a_i] == 0 );
01791 -- a_i;
01792 }
01793
01794 bool b_zero = true;
01795 while( b_i >= b.m_lsw )
01796 {
01797 b_zero = b_zero && ( b.m_mant[b_i] == 0 );
01798 -- b_i;
01799 }
01800
01801
01802
01803 if( ! a_zero && b_zero )
01804 return 1;
01805
01806 if( a_zero && ! b_zero )
01807 return -1;
01808
01809 return 0;
01810 }
01811
01812
01813
01814
01815
01816
01817
01818
01819 int
01820 cmp_scfx_rep( const scfx_rep& a, const scfx_rep& b )
01821 {
01822
01823
01824 if( a.is_nan() || b.is_nan() )
01825 {
01826 #if 0
01827 if( a.is_nan() && b.is_nan() )
01828 {
01829 return 0;
01830 }
01831 #endif
01832 return 2;
01833 }
01834
01835 if( a.is_inf() || b.is_inf() )
01836 {
01837 if( a.is_inf() )
01838 {
01839 if( ! a.is_neg() )
01840 {
01841 if( b.is_inf() && ! b.is_neg() )
01842 {
01843 return 0;
01844 }
01845 else
01846 {
01847 return 1;
01848 }
01849 }
01850 else
01851 {
01852 if( b.is_inf() && b.is_neg() )
01853 {
01854 return 0;
01855 }
01856 else
01857 {
01858 return -1;
01859 }
01860 }
01861 }
01862 if( b.is_inf() )
01863 {
01864 if( ! b.is_neg() )
01865 {
01866 return -1;
01867 }
01868 else
01869 {
01870 return 1;
01871 }
01872 }
01873 }
01874
01875 if( a.is_zero() && b.is_zero() )
01876 {
01877 return 0;
01878 }
01879
01880
01881
01882 if( a.m_sign != b.m_sign )
01883 {
01884 return a.m_sign;
01885 }
01886
01887 return ( a.m_sign * compare_abs( a, b ) );
01888 }
01889
01890
01891
01892
01893
01894
01895
01896
01897 void
01898 scfx_rep::quantization( const scfx_params& params, bool& q_flag )
01899 {
01900 scfx_index x = calc_indices( params.iwl() - params.wl() );
01901
01902 if( x.wi() < 0 )
01903 return;
01904
01905 if( x.wi() >= size() )
01906 resize_to( x.wi() + 1, 1 );
01907
01908 bool qb = q_bit( x );
01909 bool qz = q_zero( x );
01910
01911 q_flag = ( qb || ! qz );
01912
01913 if( q_flag )
01914 {
01915 switch( params.q_mode() )
01916 {
01917 case SC_TRN:
01918 {
01919 if( is_neg() )
01920 q_incr( x );
01921 break;
01922 }
01923 case SC_RND:
01924 {
01925 if( ! is_neg() )
01926 {
01927 if( qb )
01928 q_incr( x );
01929 }
01930 else
01931 {
01932 if( qb && ! qz )
01933 q_incr( x );
01934 }
01935 break;
01936 }
01937 case SC_TRN_ZERO:
01938 {
01939 break;
01940 }
01941 case SC_RND_INF:
01942 {
01943 if( qb )
01944 q_incr( x );
01945 break;
01946 }
01947 case SC_RND_CONV:
01948 {
01949 if( qb && ! qz || qb && qz && q_odd( x ) )
01950 q_incr( x );
01951 break;
01952 }
01953 case SC_RND_ZERO:
01954 {
01955 if( qb && ! qz )
01956 q_incr( x );
01957 break;
01958 }
01959 case SC_RND_MIN_INF:
01960 {
01961 if( ! is_neg() )
01962 {
01963 if( qb && ! qz )
01964 q_incr( x );
01965 }
01966 else
01967 {
01968 if( qb )
01969 q_incr( x );
01970 }
01971 break;
01972 }
01973 default:
01974 ;
01975 }
01976 q_clear( x );
01977
01978 find_sw();
01979 }
01980 }
01981
01982
01983
01984
01985
01986
01987
01988
01989 void
01990 scfx_rep::overflow( const scfx_params& params, bool& o_flag )
01991 {
01992 scfx_index x = calc_indices( params.iwl() - 1 );
01993
01994 if( x.wi() >= size() )
01995 resize_to( x.wi() + 1, 1 );
01996
01997 if( x.wi() < 0 )
01998 {
01999 resize_to( size() - x.wi(), -1 );
02000 x.wi( 0 );
02001 }
02002
02003 bool zero_left = o_zero_left( x );
02004 bool bit_at = o_bit_at( x );
02005 bool zero_right = o_zero_right( x );
02006
02007 bool under = false;
02008 bool over = false;
02009
02010 sc_enc enc = params.enc();
02011
02012 if( enc == SC_TC_ )
02013 {
02014 if( is_neg() )
02015 {
02016 if( params.o_mode() == SC_SAT_SYM )
02017 under = ( ! zero_left || bit_at );
02018 else
02019 under = ( ! zero_left || zero_left && bit_at && ! zero_right );
02020 }
02021 else
02022 over = ( ! zero_left || bit_at );
02023 }
02024 else
02025 {
02026 if( is_neg() )
02027 under = ( ! is_zero() );
02028 else
02029 over = ( ! zero_left );
02030 }
02031
02032 o_flag = ( under || over );
02033
02034 if( o_flag )
02035 {
02036 scfx_index x2 = calc_indices( params.iwl() - params.wl() );
02037
02038 if( x2.wi() < 0 )
02039 {
02040 resize_to( size() - x2.wi(), -1 );
02041 x.wi( x.wi() - x2.wi() );
02042 x2.wi( 0 );
02043 }
02044
02045 switch( params.o_mode() )
02046 {
02047 case SC_WRAP:
02048 {
02049 int n_bits = params.n_bits();
02050
02051 if( n_bits == 0 )
02052 {
02053
02054 toggle_tc();
02055 o_extend( x, enc );
02056 toggle_tc();
02057 }
02058 else if( n_bits < params.wl() )
02059 {
02060 scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits );
02061
02062
02063
02064 toggle_tc();
02065 o_set( x, x3, enc, under );
02066 o_extend( x, enc );
02067 toggle_tc();
02068 }
02069 else
02070 {
02071
02072