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 #include "sysc/utils/sc_machine.h"
00048 #include "sysc/datatypes/fx/scfx_rep.h"
00049
00050 #include "sysc/datatypes/fx/scfx_ieee.h"
00051 #include "sysc/datatypes/fx/scfx_pow10.h"
00052 #include "sysc/datatypes/fx/scfx_utils.h"
00053
00054 #include "sysc/datatypes/bit/sc_bv_base.h"
00055
00056 #include <ctype.h>
00057 #include <math.h>
00058
00059
00060 namespace sc_dt
00061 {
00062
00063
00064
00065
00066
00067 static scfx_pow10 pow10_fx;
00068
00069 static const int mantissa0_size = SCFX_IEEE_DOUBLE_M_SIZE - bits_in_int;
00070
00071 static inline
00072 int
00073 n_word( int x )
00074 {
00075 return ( x + bits_in_word - 1 ) / bits_in_word;
00076 }
00077
00078
00079
00080
00081
00082
00083 scfx_rep::scfx_rep()
00084 : m_mant( min_mant ), m_r_flag( false )
00085 {
00086 set_zero();
00087 }
00088
00089 scfx_rep::scfx_rep( int a )
00090 : m_mant( min_mant ), m_r_flag( false )
00091 {
00092 if( a != 0 )
00093 {
00094 m_mant.clear();
00095 m_wp = m_msw = m_lsw = 2;
00096 m_state = normal;
00097 if( a > 0 )
00098 {
00099 m_mant[2] = a;
00100 m_sign = 1;
00101 }
00102 else
00103 {
00104 m_mant[2] = -a;
00105 m_sign = -1;
00106 }
00107 }
00108 else
00109 set_zero();
00110 }
00111
00112 scfx_rep::scfx_rep( unsigned int a )
00113 : m_mant( min_mant ), m_r_flag( false )
00114 {
00115 if( a != 0 )
00116 {
00117 m_mant.clear();
00118 m_wp = m_msw = m_lsw = 2;
00119 m_state = normal;
00120 m_mant[2] = a;
00121 m_sign = 1;
00122 }
00123 else
00124 set_zero();
00125 }
00126
00127 scfx_rep::scfx_rep( long a )
00128 : m_mant( min_mant ), m_r_flag( false )
00129 {
00130 if( a != 0 )
00131 {
00132 m_mant.clear();
00133 m_state = normal;
00134 if ( a > 0 )
00135 {
00136 m_sign = 1;
00137 }
00138 else
00139 {
00140 a = -a;
00141 m_sign = -1;
00142 }
00143 # if defined(SC_LONG_64)
00144 m_wp = 1;
00145 m_mant[1] = static_cast<word>( a );
00146 m_mant[2] = static_cast<word>( a >> bits_in_word );
00147 find_sw();
00148 # else
00149 m_wp = 2;
00150 m_msw = 2;
00151 m_lsw = 2;
00152 m_mant[2] = a;
00153 # endif
00154
00155 }
00156 else
00157 set_zero();
00158 }
00159
00160 scfx_rep::scfx_rep( unsigned long a )
00161 : m_mant( min_mant ), m_r_flag( false )
00162 {
00163 if( a != 0 )
00164 {
00165 m_mant.clear();
00166 m_wp = m_msw = m_lsw = 2;
00167 m_state = normal;
00168 # if defined(SC_LONG_64)
00169 m_wp = 1;
00170 m_mant[1] = static_cast<word>( a );
00171 m_mant[2] = static_cast<word>( a >> bits_in_word );
00172 find_sw();
00173 # else
00174 m_wp = 2;
00175 m_msw = 2;
00176 m_lsw = 2;
00177 m_mant[2] = a;
00178 # endif
00179 m_sign = 1;
00180 }
00181 else
00182 set_zero();
00183 }
00184
00185 scfx_rep::scfx_rep( double a )
00186 : m_mant( min_mant ), m_wp( 0 ), m_state( normal ), m_msw( 0 ), m_lsw( 0 ),
00187 m_r_flag( false )
00188 {
00189 m_mant.clear();
00190
00191 scfx_ieee_double id( a );
00192
00193 m_sign = id.negative() ? -1 : 1;
00194
00195 if( id.is_nan() )
00196 m_state = not_a_number;
00197 else if( id.is_inf() )
00198 m_state = infinity;
00199 else if( id.is_subnormal() )
00200 {
00201 m_mant[0] = id.mantissa1();
00202 m_mant[1] = id.mantissa0();
00203 normalize( id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE );
00204 }
00205 else if( id.is_normal() )
00206 {
00207 m_mant[0] = id.mantissa1();
00208 m_mant[1] = id.mantissa0() | ( 1 << mantissa0_size );
00209 normalize( id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE );
00210 }
00211 }
00212
00213 scfx_rep::scfx_rep( int64 a )
00214 : m_mant( min_mant ), m_r_flag( false )
00215 {
00216 if( a != 0 )
00217 {
00218 m_mant.clear();
00219 m_wp = 1;
00220 m_state = normal;
00221 if( a > 0 )
00222 {
00223 m_mant[1] = static_cast<word>( a );
00224 m_mant[2] = static_cast<word>( a >> bits_in_word );
00225 m_sign = 1;
00226 }
00227 else
00228 {
00229 m_mant[1] = static_cast<word>( -a );
00230 m_mant[2] = static_cast<word>( (-a) >> bits_in_word );
00231 m_sign = -1;
00232 }
00233 find_sw();
00234 }
00235 else
00236 set_zero();
00237 }
00238
00239 scfx_rep::scfx_rep( uint64 a )
00240 : m_mant( min_mant ), m_r_flag( false )
00241 {
00242 if( a != 0 )
00243 {
00244 m_mant.clear();
00245 m_wp = 1;
00246 m_state = normal;
00247 m_mant[1] = static_cast<word>( a );
00248 m_mant[2] = static_cast<word>( a >> bits_in_word );
00249 m_sign = 1;
00250 find_sw();
00251 }
00252 else
00253 set_zero();
00254 }
00255
00256 scfx_rep::scfx_rep( const sc_signed& a )
00257 : m_mant( min_mant ), m_r_flag( false )
00258 {
00259 if( a.iszero() )
00260 set_zero();
00261 else
00262 {
00263 int words = n_word( a.length() );
00264 if( words > size() )
00265 resize_to( words );
00266 m_mant.clear();
00267 m_wp = 0;
00268 m_state = normal;
00269 if( a.sign() )
00270 {
00271 sc_signed a2 = -a;
00272 for( int i = 0; i < a2.length(); ++ i )
00273 {
00274 if( a2[i] )
00275 {
00276 scfx_index x = calc_indices( i );
00277 m_mant[x.wi()] |= 1 << x.bi();
00278 }
00279 }
00280 m_sign = -1;
00281 }
00282 else
00283 {
00284 for( int i = 0; i < a.length(); ++ i )
00285 {
00286 if( a[i] )
00287 {
00288 scfx_index x = calc_indices( i );
00289 m_mant[x.wi()] |= 1 << x.bi();
00290 }
00291 }
00292 m_sign = 1;
00293 }
00294 find_sw();
00295 }
00296 }
00297
00298 scfx_rep::scfx_rep( const sc_unsigned& a )
00299 : m_mant( min_mant ), m_r_flag( false )
00300 {
00301 if( a.iszero() )
00302 set_zero();
00303 else
00304 {
00305 int words = n_word( a.length() );
00306 if( words > size() )
00307 resize_to( words );
00308 m_mant.clear();
00309 m_wp = 0;
00310 m_state = normal;
00311 for( int i = 0; i < a.length(); ++ i )
00312 {
00313 if( a[i] )
00314 {
00315 scfx_index x = calc_indices( i );
00316 m_mant[x.wi()] |= 1 << x.bi();
00317 }
00318 }
00319 m_sign = 1;
00320 find_sw();
00321 }
00322 }
00323
00324
00325
00326
00327 scfx_rep::scfx_rep( const scfx_rep& a )
00328 : m_mant( a.m_mant ), m_wp( a.m_wp ), m_sign( a.m_sign ), m_state( a.m_state ),
00329 m_msw( a.m_msw ), m_lsw( a.m_lsw ), m_r_flag( false )
00330 {}
00331
00332
00333
00334
00335
00336
00337
00338
00339 union scfx_rep_node
00340 {
00341 char data[sizeof( scfx_rep )];
00342 scfx_rep_node* next;
00343 };
00344
00345
00346 static scfx_rep_node* list = 0;
00347
00348
00349 void*
00350 scfx_rep::operator new( std::size_t size )
00351 {
00352 const int ALLOC_SIZE = 1024;
00353
00354 if( size != sizeof( scfx_rep ) )
00355 return ::operator new( size );
00356
00357 if( ! list )
00358 {
00359 list = new scfx_rep_node[ALLOC_SIZE];
00360 for( int i = 0; i < ALLOC_SIZE - 1; i ++ )
00361 list[i].next = list + i + 1;
00362 list[ALLOC_SIZE - 1].next = 0;
00363 }
00364
00365 scfx_rep* ptr = reinterpret_cast<scfx_rep*>( list->data );
00366 list = list->next;
00367
00368 return ptr;
00369 }
00370
00371
00372 void scfx_rep::operator delete( void* ptr, std::size_t size )
00373 {
00374 if( size != sizeof( scfx_rep ) )
00375 {
00376 ::operator delete( ptr );
00377 return;
00378 }
00379
00380 scfx_rep_node* node = static_cast<scfx_rep_node*>( ptr );
00381 node->next = list;
00382 list = node;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392 #define SCFX_FAIL_IF_(cnd) \
00393 { \
00394 if( ( cnd ) ) \
00395 { \
00396 m_state = not_a_number; \
00397 m_mant.clear(); \
00398 return; \
00399 } \
00400 }
00401
00402
00403 void
00404 scfx_rep::from_string( const char* s, int cte_wl )
00405 {
00406 SCFX_FAIL_IF_( s == 0 || *s == 0 );
00407
00408 scfx_string s2;
00409 s2 += s;
00410 s2 += '\0';
00411
00412 bool sign_char;
00413 m_sign = scfx_parse_sign( s, sign_char );
00414
00415 sc_numrep numrep = scfx_parse_prefix( s );
00416
00417 int base = 0;
00418
00419 switch( numrep )
00420 {
00421 case SC_DEC:
00422 {
00423 base = 10;
00424 if( scfx_is_nan( s ) )
00425 {
00426 m_state = not_a_number;
00427 m_mant.clear();
00428 return;
00429 }
00430 if( scfx_is_inf( s ) )
00431 {
00432 m_state = infinity;
00433 m_mant.clear();
00434 return;
00435 }
00436 break;
00437 }
00438 case SC_BIN:
00439 case SC_BIN_US:
00440 {
00441 SCFX_FAIL_IF_( sign_char );
00442 base = 2;
00443 break;
00444 }
00445
00446 case SC_BIN_SM:
00447 {
00448 base = 2;
00449 break;
00450 }
00451 case SC_OCT:
00452 case SC_OCT_US:
00453 {
00454 SCFX_FAIL_IF_( sign_char );
00455 base = 8;
00456 break;
00457 }
00458 case SC_OCT_SM:
00459 {
00460 base = 8;
00461 break;
00462 }
00463 case SC_HEX:
00464 case SC_HEX_US:
00465 {
00466 SCFX_FAIL_IF_( sign_char );
00467 base = 16;
00468 break;
00469 }
00470 case SC_HEX_SM:
00471 {
00472 base = 16;
00473 break;
00474 }
00475 case SC_CSD:
00476 {
00477 SCFX_FAIL_IF_( sign_char );
00478 base = 2;
00479 scfx_csd2tc( s2 );
00480 s = (const char*) s2 + 4;
00481 numrep = SC_BIN;
00482 break;
00483 }
00484 default:;
00485 }
00486
00487
00488
00489
00490
00491 const char *end = s;
00492 bool based_point = false;
00493 int int_digits = 0;
00494 int frac_digits = 0;
00495
00496 while( *end )
00497 {
00498 if( scfx_exp_start( end ) )
00499 break;
00500
00501 if( *end == '.' )
00502 {
00503 SCFX_FAIL_IF_( based_point );
00504 based_point = true;
00505 }
00506 else
00507 {
00508 SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) );
00509 if( based_point )
00510 frac_digits ++;
00511 else
00512 int_digits ++;
00513 }
00514
00515 ++ end;
00516 }
00517
00518 SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 );
00519
00520
00521
00522 int exponent = 0;
00523
00524 if( *end )
00525 {
00526 for( const char *e = end + 2; *e; ++ e )
00527 SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) );
00528 exponent = atoi( end + 1 );
00529 }
00530
00531
00532
00533
00534
00535 bool mant_is_neg = false;
00536
00537 switch( numrep )
00538 {
00539 case SC_BIN:
00540 case SC_OCT:
00541 case SC_HEX:
00542 {
00543 const char* p = s;
00544 if( *p == '.' )
00545 ++ p;
00546
00547 mant_is_neg = ( scfx_to_digit( *p, numrep ) >= ( base >> 1 ) );
00548
00549 break;
00550 }
00551 default:
00552 ;
00553 }
00554
00555
00556
00557
00558
00559 switch( base )
00560 {
00561 case 2:
00562 {
00563 int bit_offset = exponent % bits_in_word;
00564 int word_offset = exponent / bits_in_word;
00565
00566 int_digits += bit_offset;
00567 frac_digits -= bit_offset;
00568
00569 int words = n_word( int_digits ) + n_word( frac_digits );
00570 if( words > size() )
00571 resize_to( words );
00572 m_mant.clear();
00573
00574 int j = n_word( frac_digits ) * bits_in_word + int_digits - 1;
00575
00576 for( ; s < end; s ++ )
00577 {
00578 switch( *s )
00579 {
00580 case '1':
00581 set_bin( j );
00582 case '0':
00583 j --;
00584 case '.':
00585 break;
00586 default:
00587 SCFX_FAIL_IF_( true );
00588 }
00589 }
00590
00591 m_wp = n_word( frac_digits ) - word_offset;
00592 break;
00593 }
00594 case 8:
00595 {
00596 exponent *= 3;
00597 int_digits *= 3;
00598 frac_digits *= 3;
00599
00600 int bit_offset = exponent % bits_in_word;
00601 int word_offset = exponent / bits_in_word;
00602
00603 int_digits += bit_offset;
00604 frac_digits -= bit_offset;
00605
00606 int words = n_word( int_digits ) + n_word( frac_digits );
00607 if( words > size() )
00608 resize_to( words );
00609 m_mant.clear();
00610
00611 int j = n_word( frac_digits ) * bits_in_word + int_digits - 3;
00612
00613 for( ; s < end; s ++ )
00614 {
00615 switch( *s )
00616 {
00617 case '7': case '6': case '5': case '4':
00618 case '3': case '2': case '1':
00619 set_oct( j, *s - '0' );
00620 case '0':
00621 j -= 3;
00622 case '.':
00623 break;
00624 default:
00625 SCFX_FAIL_IF_( true );
00626 }
00627 }
00628
00629 m_wp = n_word( frac_digits ) - word_offset;
00630 break;
00631 }
00632 case 10:
00633 {
00634 word carry, temp;
00635 int length = int_digits + frac_digits;
00636 resize_to( sc_max( min_mant, n_word( 4 * length ) ) );
00637
00638 m_mant.clear();
00639 m_msw = m_lsw = 0;
00640
00641 for( ; s < end; s ++ )
00642 {
00643 switch( *s )
00644 {
00645 case '9': case '8': case '7': case '6': case '5':
00646 case '4': case '3': case '2': case '1': case '0':
00647 multiply_by_ten();
00648 carry = *s - '0';
00649 for ( int i = 0; carry && i < m_mant.size(); i++ )
00650 {
00651 temp = m_mant[i];
00652 temp += carry;
00653 carry = temp < m_mant[i];
00654 m_mant[i] = temp;
00655 }
00656 case '.':
00657 break;
00658 default:
00659 SCFX_FAIL_IF_( true );
00660 }
00661 }
00662
00663 m_wp = 0;
00664 find_sw();
00665
00666 int denominator = frac_digits - exponent;
00667
00668 if( denominator )
00669 {
00670 scfx_rep frac_num = pow10_fx( denominator );
00671 scfx_rep* temp_num =
00672 div_scfx_rep( const_cast<const scfx_rep&>( *this ),
00673 frac_num, cte_wl );
00674 *this = *temp_num;
00675 delete temp_num;
00676 }
00677
00678 break;
00679 }
00680 case 16:
00681 {
00682 exponent *= 4;
00683 int_digits *= 4;
00684 frac_digits *= 4;
00685
00686 int bit_offset = exponent % bits_in_word;
00687 int word_offset = exponent / bits_in_word;
00688
00689 int_digits += bit_offset;
00690 frac_digits -= bit_offset;
00691
00692 int words = n_word( int_digits ) + n_word( frac_digits );
00693 if( words > size() )
00694 resize_to( words );
00695 m_mant.clear();
00696
00697 int j = n_word( frac_digits ) * bits_in_word + int_digits - 4;
00698
00699 for( ; s < end; s ++ )
00700 {
00701 switch( *s )
00702 {
00703 case 'f': case 'e': case 'd': case 'c': case 'b': case 'a':
00704 set_hex( j, *s - 'a' + 10 );
00705 j -= 4;
00706 break;
00707 case 'F': case 'E': case 'D': case 'C': case 'B': case 'A':
00708 set_hex( j, *s - 'A' + 10 );
00709 j -= 4;
00710 break;
00711 case '9': case '8': case '7': case '6': case '5':
00712 case '4': case '3': case '2': case '1':
00713 set_hex( j, *s - '0' );
00714 case '0':
00715 j -= 4;
00716 case '.':
00717 break;
00718 default:
00719 SCFX_FAIL_IF_( true );
00720 }
00721 }
00722
00723 m_wp = n_word( frac_digits ) - word_offset;
00724 break;
00725 }
00726 }
00727
00728 m_state = normal;
00729 find_sw();
00730
00731
00732
00733
00734
00735 if( mant_is_neg )
00736 {
00737 m_mant[m_msw] |= -1 << scfx_find_msb( m_mant[m_msw] );
00738 for( int i = m_msw + 1; i < m_mant.size(); ++ i )
00739 m_mant[i] = static_cast<word>( -1 );
00740 complement( m_mant, m_mant, m_mant.size() );
00741 inc( m_mant );
00742 m_sign *= -1;
00743 find_sw();
00744 }
00745 }
00746
00747
00748 #undef SCFX_FAIL_IF_
00749
00750
00751
00752
00753
00754
00755
00756
00757 double
00758 scfx_rep::to_double() const
00759 {
00760 scfx_ieee_double id;
00761
00762
00763
00764 if( is_nan() )
00765 {
00766 id.set_nan();
00767 return id;
00768 }
00769
00770 if( is_inf() )
00771 {
00772 id.set_inf();
00773 id.negative( m_sign < 0 );
00774 return id;
00775 }
00776
00777 if( is_zero() )
00778 {
00779 id = 0.;
00780 id.negative( m_sign < 0 );
00781 return id;
00782 }
00783
00784 int msb = scfx_find_msb( m_mant[m_msw] );
00785
00786 int exp = (m_msw - m_wp) * bits_in_word + msb;
00787
00788 if( exp > SCFX_IEEE_DOUBLE_E_MAX )
00789 {
00790 id.set_inf();
00791 id.negative( m_sign < 0 );
00792 return id;
00793 }
00794
00795 if( exp < SCFX_IEEE_DOUBLE_E_MIN
00796 - static_cast<int>( SCFX_IEEE_DOUBLE_M_SIZE ) )
00797 {
00798 id = 0.;
00799 return id;
00800 }
00801
00802 int shift = mantissa0_size - msb;
00803
00804 unsigned int m0;
00805 unsigned int m1 = 0;
00806 unsigned int guard = 0;
00807
00808 if( shift == 0 )
00809 {
00810 m0 = m_mant[m_msw] & ~( 1 << mantissa0_size );
00811 if( m_msw > m_lsw )
00812 {
00813 m1 = m_mant[m_msw - 1];
00814 if( m_msw - 1 > m_lsw )
00815 guard = m_mant[m_msw - 2] >> ( bits_in_word - 1 );
00816 }
00817 }
00818 else if( shift < 0 )
00819 {
00820 m0 = ( m_mant[m_msw] >> -shift ) & ~( 1 << mantissa0_size );
00821 m1 = m_mant[m_msw] << ( bits_in_word + shift );
00822 if( m_msw > m_lsw )
00823 {
00824 m1 |= m_mant[m_msw - 1] >> -shift;
00825 guard = ( m_mant[m_msw - 1] >> ( -shift - 1 ) ) & 1;
00826 }
00827 }
00828 else
00829 {
00830 m0 = ( m_mant[m_msw] << shift ) & ~( 1 << mantissa0_size );
00831 if( m_msw > m_lsw )
00832 {
00833 m0 |= m_mant[m_msw - 1] >> ( bits_in_word - shift );
00834 m1 = m_mant[m_msw - 1] << shift;
00835 if( m_msw - 1 > m_lsw )
00836 {
00837 m1 |= m_mant[m_msw - 2] >> ( bits_in_word - shift );
00838 guard = ( m_mant[m_msw - 2] >> (bits_in_word - shift - 1) )
00839 & 1;
00840 }
00841 }
00842 }
00843
00844 if( exp < SCFX_IEEE_DOUBLE_E_MIN )
00845 {
00846 m0 |= ( 1 << mantissa0_size );
00847
00848 int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp;
00849
00850 if( subnormal_shift < bits_in_word )
00851 {
00852 m1 = m1 >> subnormal_shift
00853 | m0 << ( bits_in_word - subnormal_shift );
00854 m0 = m0 >> subnormal_shift;
00855 }
00856 else
00857 {
00858 m1 = m0 >> ( subnormal_shift - bits_in_word );
00859 m0 = 0;
00860 }
00861
00862 guard = 0;
00863
00864 exp = SCFX_IEEE_DOUBLE_E_MIN - 1;
00865 }
00866
00867 id.mantissa0( m0 );
00868 id.mantissa1( m1 );
00869 id.exponent( exp );
00870 id.negative( m_sign < 0 );
00871
00872 double result = id;
00873
00874 if( guard != 0 )
00875 result += m_sign * scfx_pow2( exp - SCFX_IEEE_DOUBLE_M_SIZE );
00876
00877 return result;
00878 }
00879
00880
00881
00882
00883
00884
00885
00886
00887 void
00888 print_dec( scfx_string& s, const scfx_rep& num, int w_prefix, sc_fmt fmt )
00889 {
00890 if( num.is_neg() )
00891 s += '-';
00892
00893 if( w_prefix == 1 ) {
00894 scfx_print_prefix( s, SC_DEC );
00895 }
00896
00897 if( num.is_zero() )
00898 {
00899 s += '0';
00900 return;
00901 }
00902
00903
00904
00905 scfx_rep int_part = num;
00906 scfx_rep frac_part = num;
00907
00908 int i;
00909
00910 for( i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i ++ )
00911 int_part.m_mant[i] = 0;
00912 int_part.find_sw();
00913 if( int_part.m_wp < int_part.m_lsw )
00914 int_part.resize_to( int_part.size() - int_part.m_wp, -1 );
00915
00916 for( i = frac_part.m_msw;
00917 i >= frac_part.m_lsw && i >= frac_part.m_wp;
00918 i -- )
00919 frac_part.m_mant[i] = 0;
00920 frac_part.find_sw();
00921 if( frac_part.m_msw == frac_part.size() - 1 )
00922 frac_part.resize_to( frac_part.size() + 1, 1 );
00923
00924
00925
00926 int int_digits = 0;
00927 int int_zeros = 0;
00928
00929 if( ! int_part.is_zero() )
00930 {
00931 double int_wl = ( int_part.m_msw - int_part.m_wp ) * bits_in_word
00932 + scfx_find_msb( int_part.m_mant[int_part.m_msw] ) + 1;
00933 int_digits = (int) ceil( int_wl * log10( 2. ) );
00934
00935 int len = s.length();
00936 s.append( int_digits );
00937
00938 bool zero_digits = ( frac_part.is_zero() && fmt != SC_F );
00939
00940 for( i = int_digits + len - 1; i >= len; i-- )
00941 {
00942 unsigned int remainder = int_part.divide_by_ten();
00943 s[i] = static_cast<char>( '0' + remainder );
00944
00945 if( zero_digits )
00946 {
00947 if( remainder == 0 )
00948 int_zeros ++;
00949 else
00950 zero_digits = false;
00951 }
00952 }
00953
00954
00955 s.discard( int_zeros );
00956
00957 if( s[len] == '0' )
00958 {
00959
00960 s.remove( len );
00961 -- int_digits;
00962 }
00963 }
00964
00965
00966
00967 int frac_digits = 0;
00968 int frac_zeros = 0;
00969
00970 if( ! frac_part.is_zero() )
00971 {
00972 s += '.';
00973
00974 bool zero_digits = ( int_digits == 0 && fmt != SC_F );
00975
00976 double frac_wl = ( frac_part.m_wp - frac_part.m_msw ) * bits_in_word
00977 - scfx_find_msb( frac_part.m_mant[frac_part.m_msw] )
00978 - 1;
00979 frac_zeros = (int) floor( frac_wl * log10( 2. ) );
00980
00981 scfx_rep temp;
00982 sc_dt::multiply( temp, frac_part, pow10_fx( frac_zeros ) );
00983 frac_part = temp;
00984 if( frac_part.m_msw == frac_part.size() - 1 )
00985 frac_part.resize_to( frac_part.size() + 1, 1 );
00986
00987 frac_digits = frac_zeros;
00988 if( ! zero_digits )
00989 {
00990 for( i = 0; i < frac_zeros; i ++ )
00991 s += '0';
00992 frac_zeros = 0;
00993 }
00994
00995 while( ! frac_part.is_zero() )
00996 {
00997 frac_part.multiply_by_ten();
00998 int n = frac_part.m_mant[frac_part.m_msw + 1];
00999
01000 if( zero_digits )
01001 {
01002 if( n == 0 )
01003 frac_zeros ++;
01004 else
01005 zero_digits = false;
01006 }
01007
01008 if( ! zero_digits )
01009 s += static_cast<char>( '0' + n );
01010
01011 frac_part.m_mant[frac_part.m_msw + 1] = 0;
01012 frac_digits ++;
01013 }
01014 }
01015
01016
01017
01018 if( fmt != SC_F )
01019 {
01020 if( frac_digits == 0 )
01021 scfx_print_exp( s, int_zeros );
01022 else if( int_digits == 0 )
01023 scfx_print_exp( s, - frac_zeros );
01024 }
01025 }
01026
01027 void
01028 print_other( scfx_string& s, const scfx_rep& a, sc_numrep numrep, int w_prefix,
01029 sc_fmt fmt, const scfx_params* params )
01030 {
01031 scfx_rep b = a;
01032
01033 sc_numrep numrep2 = numrep;
01034
01035 bool numrep_is_sm = ( numrep == SC_BIN_SM ||
01036 numrep == SC_OCT_SM ||
01037 numrep == SC_HEX_SM );
01038
01039 if( numrep_is_sm )
01040 {
01041 if( b.is_neg() )
01042 {
01043 s += '-';
01044 b = *neg_scfx_rep( a );
01045 }
01046 switch( numrep )
01047 {
01048 case SC_BIN_SM:
01049 numrep2 = SC_BIN_US;
01050 break;
01051 case SC_OCT_SM:
01052 numrep2 = SC_OCT_US;
01053 break;
01054 case SC_HEX_SM:
01055 numrep2 = SC_HEX_US;
01056 break;
01057 default:
01058 ;
01059 }
01060 }
01061
01062 if( w_prefix != 0 ) {
01063 scfx_print_prefix( s, numrep );
01064 }
01065
01066 numrep = numrep2;
01067
01068 int msb, lsb;
01069
01070 if( params != 0 )
01071 {
01072 msb = params->iwl() - 1;
01073 lsb = params->iwl() - params->wl();
01074
01075 if( params->enc() == SC_TC_ &&
01076 ( numrep == SC_BIN_US ||
01077 numrep == SC_OCT_US ||
01078 numrep == SC_HEX_US ) &&
01079 ! numrep_is_sm &&
01080 params->wl() > 1 )
01081 -- msb;
01082 else if( params->enc() == SC_US_ &&
01083 ( numrep == SC_BIN ||
01084 numrep == SC_OCT ||
01085 numrep == SC_HEX ||
01086 numrep == SC_CSD ) )
01087 ++ msb;
01088 }
01089 else
01090 {
01091 if( b.is_zero() )
01092 {
01093 msb = 0;
01094 lsb = 0;
01095 }
01096 else
01097 {
01098 msb = ( b.m_msw - b.m_wp ) * bits_in_word
01099 + scfx_find_msb( b.m_mant[ b.m_msw ] ) + 1;
01100 while( b.get_bit( msb ) == b.get_bit( msb - 1 ) )
01101 -- msb;
01102
01103 if( numrep == SC_BIN_US ||
01104 numrep == SC_OCT_US ||
01105 numrep == SC_HEX_US )
01106 -- msb;
01107
01108 lsb = ( b.m_lsw - b.m_wp ) * bits_in_word
01109 + scfx_find_lsb( b.m_mant[ b.m_lsw ] );
01110 }
01111 }
01112
01113 int step;
01114
01115 switch( numrep )
01116 {
01117 case SC_BIN:
01118 case SC_BIN_US:
01119 case SC_CSD:
01120 step = 1;
01121 break;
01122 case SC_OCT:
01123 case SC_OCT_US:
01124 step = 3;
01125 break;
01126 case SC_HEX:
01127 case SC_HEX_US:
01128 step = 4;
01129 break;
01130 default:
01131 step = 0;
01132 }
01133
01134 msb = (int) ceil( double( msb + 1 ) / step ) * step - 1;
01135
01136 lsb = (int) floor( double( lsb ) / step ) * step;
01137
01138 if( msb < 0 )
01139 {
01140 s += '.';
01141 if( fmt == SC_F )
01142 {
01143 int sign = ( b.is_neg() ) ? ( 1 << step ) - 1 : 0;
01144 for( int i = ( msb + 1 ) / step; i < 0; i ++ )
01145 {
01146 if( sign < 10 )
01147 s += static_cast<char>( sign + '0' );
01148 else
01149 s += static_cast<char>( sign + 'a' - 10 );
01150 }
01151 }
01152 }
01153
01154 int i = msb;
01155 while( i >= lsb )
01156 {
01157 int value = 0;
01158 for( int j = step - 1; j >= 0; -- j )
01159 {
01160 value += static_cast<int>( b.get_bit( i ) ) << j;
01161 -- i;
01162 }
01163 if( value < 10 )
01164 s += static_cast<char>( value + '0' );
01165 else
01166 s += static_cast<char>( value + 'a' - 10 );
01167 if( i == -1 )
01168 s += '.';
01169 }
01170
01171 if( lsb > 0 && fmt == SC_F )
01172 {
01173 for( int i = lsb / step; i > 0; i -- )
01174 s += '0';
01175 }
01176
01177 if( s[s.length() - 1] == '.' )
01178 s.discard( 1 );
01179
01180 if( fmt != SC_F )
01181 {
01182 if( msb < 0 )
01183 scfx_print_exp( s, ( msb + 1 ) / step );
01184 else if( lsb > 0 )
01185 scfx_print_exp( s, lsb / step );
01186 }
01187
01188 if( numrep == SC_CSD )
01189 scfx_tc2csd( s, w_prefix );
01190 }
01191
01192 const char*
01193 scfx_rep::to_string( sc_numrep numrep, int w_prefix,
01194 sc_fmt fmt, const scfx_params* params ) const
01195 {
01196 static scfx_string s;
01197
01198 s.clear();
01199
01200 if( is_nan() )
01201 scfx_print_nan( s );
01202 else if( is_inf() )
01203 scfx_print_inf( s, is_neg() );
01204 else if( is_neg() && ! is_zero() &&
01205 ( numrep == SC_BIN_US ||
01206 numrep == SC_OCT_US ||
01207 numrep == SC_HEX_US ) )
01208 s += "negative";
01209 else if( numrep == SC_DEC || numrep == SC_NOBASE )
01210 sc_dt::print_dec( s, *this, w_prefix, fmt );
01211 else
01212 sc_dt::print_other( s, *this, numrep, w_prefix, fmt, params );
01213
01214 return s;
01215 }
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 static inline
01227 int
01228 add_mants( int size, scfx_mant& result,
01229 const scfx_mant& a, const scfx_mant& b )
01230 {
01231 unsigned int carry = 0;
01232
01233 int index = 0;
01234
01235 do
01236 {
01237 word x = a[index];
01238 word y = b[index];
01239
01240 y += carry;
01241 carry = y < carry;
01242 y += x;
01243 carry += y < x;
01244 result[index] = y;
01245 }
01246 while( ++ index < size );
01247
01248 return ( carry ? 1 : 0 );
01249 }
01250
01251
01252 static inline
01253 int
01254 sub_mants( int size, scfx_mant& result,
01255 const scfx_mant& a, const scfx_mant& b )
01256 {
01257 unsigned carry = 0;
01258
01259 int index = 0;
01260
01261 do
01262 {
01263 word x = a[index];
01264 word y = b[index];
01265
01266 y += carry;
01267 carry = y < carry;
01268 y = x - y;
01269 carry += y > x;
01270 result[index] = y;
01271 }
01272 while( ++ index < size );
01273
01274 return ( carry ? 1 : 0 );
01275 }
01276
01277
01278 scfx_rep*
01279 add_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
01280 {
01281 scfx_rep& result = *new scfx_rep;
01282
01283
01284
01285
01286
01287 if( lhs.is_nan() || rhs.is_nan()
01288 || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign ) )
01289 {
01290 result.set_nan();
01291 return &result;
01292 }
01293
01294 if( lhs.is_inf() )
01295 {
01296 result.set_inf( lhs.m_sign );
01297 return &result;
01298 }
01299
01300 if( rhs.is_inf() )
01301 {
01302 result.set_inf( rhs.m_sign );
01303 return &result;
01304 }
01305
01306
01307
01308
01309
01310 scfx_mant_ref lhs_mant;
01311 scfx_mant_ref rhs_mant;
01312
01313 int len_mant = lhs.size();
01314 int new_wp = lhs.m_wp;
01315
01316 align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
01317
01318
01319
01320
01321
01322 result.resize_to( len_mant );
01323 result.m_wp = new_wp;
01324
01325
01326
01327
01328
01329 if( lhs.m_sign == rhs.m_sign )
01330 {
01331 add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01332 result.m_sign = lhs.m_sign;
01333 }
01334 else
01335 {
01336 int cmp = compare_abs( lhs, rhs );
01337
01338 if( cmp == 1 )
01339 {
01340 sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01341 result.m_sign = lhs.m_sign;
01342 }
01343 else if ( cmp == -1 )
01344 {
01345 sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
01346 result.m_sign = rhs.m_sign;
01347 }
01348 else
01349 {
01350 result.m_mant.clear();
01351 result.m_sign = 1;
01352 }
01353 }
01354
01355 result.find_sw();
01356 result.round( max_wl );
01357
01358 return &result;
01359 }
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370 static inline
01371 int
01372 sub_with_index( scfx_mant& a, int a_msw, int a_lsw,
01373 const scfx_mant& b, int b_msw, int b_lsw )
01374 {
01375 unsigned carry = 0;
01376
01377 int size = b_msw - b_lsw;
01378 int a_index = a_msw - size;
01379 int b_index = b_msw - size;
01380
01381 do
01382 {
01383 word x = a[a_index];
01384 word y = b[b_index];
01385
01386 y += carry;
01387 carry = y < carry;
01388 y = x - y;
01389 carry += y > x;
01390 a[a_index] = y;
01391
01392 a_index ++;
01393 b_index ++;
01394 }
01395 while( size -- );
01396
01397 if( carry )
01398 {
01399
01400 a[a_msw + 1] = 0;
01401 }
01402
01403 return ( carry ? 1 : 0 );
01404 }
01405
01406
01407 scfx_rep*
01408 sub_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
01409 {
01410 scfx_rep& result = *new scfx_rep;
01411
01412
01413
01414
01415
01416 if( lhs.is_nan() || rhs.is_nan()
01417 || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign ) )
01418 {
01419 result.set_nan();
01420 return &result;
01421 }
01422
01423 if( lhs.is_inf() )
01424 {
01425 result.set_inf( lhs.m_sign );
01426 return &result;
01427 }
01428
01429 if( rhs.is_inf() )
01430 {
01431 result.set_inf( -1 * rhs.m_sign );
01432 return &result;
01433 }
01434
01435
01436
01437
01438
01439 scfx_mant_ref lhs_mant;
01440 scfx_mant_ref rhs_mant;
01441
01442 int len_mant = lhs.size();
01443 int new_wp = lhs.m_wp;
01444
01445 align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
01446
01447
01448
01449
01450
01451 result.resize_to( len_mant );
01452 result.m_wp = new_wp;
01453
01454
01455
01456
01457
01458 if( lhs.m_sign != rhs.m_sign )
01459 {
01460 add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01461 result.m_sign = lhs.m_sign;
01462 }
01463 else
01464 {
01465 int cmp = compare_abs( lhs, rhs );
01466
01467 if( cmp == 1 )
01468 {
01469 sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
01470 result.m_sign = lhs.m_sign;
01471 }
01472 else if ( cmp == -1 )
01473 {
01474 sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
01475 result.m_sign = -rhs.m_sign;
01476 } else {
01477 result.m_mant.clear();
01478 result.m_sign = 1;
01479 }
01480 }
01481
01482 result.find_sw();
01483 result.round( max_wl );
01484
01485 return &result;
01486 }
01487
01488
01489
01490
01491
01492
01493 union word_short
01494 {
01495 word l;
01496 struct
01497 {
01498 #if defined( SC_BIG_ENDIAN )
01499 half_word u;
01500 half_word l;
01501 #elif defined( SC_LITTLE_ENDIAN )
01502 half_word l;
01503 half_word u;
01504 #endif
01505 } s;
01506 };
01507
01508
01509 #if defined( SC_BIG_ENDIAN )
01510 static const int half_word_incr = -1;
01511 #elif defined( SC_LITTLE_ENDIAN )
01512 static const int half_word_incr = 1;
01513 #endif
01514
01515
01516 void
01517 multiply( scfx_rep& result, const scfx_rep& lhs, const scfx_rep& rhs,
01518 int max_wl )
01519 {
01520
01521
01522
01523
01524 if( lhs.is_nan() || rhs.is_nan()
01525 || lhs.is_inf() && rhs.is_zero()
01526 || lhs.is_zero() && rhs.is_inf() )
01527 {
01528 result.set_nan();
01529 return;
01530 }
01531
01532 if( lhs.is_inf() || rhs.is_inf() )
01533 {
01534 result.set_inf( lhs.m_sign * rhs.m_sign );
01535 return;
01536 }
01537
01538 if( lhs.is_zero() || rhs.is_zero() ) {
01539 result.set_zero( lhs.m_sign * rhs.m_sign );
01540 return;
01541 }
01542
01543
01544
01545
01546
01547 int len_lhs = lhs.m_msw - lhs.m_lsw + 1;
01548 int len_rhs = rhs.m_msw - rhs.m_lsw + 1;
01549
01550 int new_size = sc_max( min_mant, len_lhs + len_rhs );
01551 int new_wp = ( lhs.m_wp - lhs.m_lsw ) + ( rhs.m_wp - rhs.m_lsw );
01552 int new_sign = lhs.m_sign * rhs.m_sign;
01553
01554 result.resize_to( new_size );
01555 result.m_mant.clear();
01556 result.m_wp = new_wp;
01557 result.m_sign = new_sign;
01558 result.m_state = scfx_rep::normal;
01559
01560 half_word *s1 = lhs.m_mant.half_addr( lhs.m_lsw );
01561 half_word *s2 = rhs.m_mant.half_addr( rhs.m_lsw );
01562
01563 half_word *t = result.m_mant.half_addr();
01564
01565 len_lhs <<= 1;
01566 len_rhs <<= 1;
01567
01568 int i1, i2;
01569
01570 for( i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr )
01571 {
01572 register word_short ls;
01573 ls.l = 0;
01574
01575 half_word v1 = s1[i1];
01576
01577 for( i2 = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr )
01578 {
01579 ls.l += v1 * s2[i2];
01580 ls.s.l = ls.s.u + ( ( t[i2] += ls.s.l ) < ls.s.l );
01581 ls.s.u = 0;
01582 }
01583
01584 t[i2] = ls.s.l;
01585 t += half_word_incr;
01586 }
01587
01588 result.find_sw();
01589 result.round( max_wl );
01590 }
01591
01592
01593
01594
01595
01596
01597 scfx_rep*
01598 div_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int div_wl )
01599 {
01600 scfx_rep& result = *new scfx_rep;
01601
01602
01603
01604
01605
01606 if( lhs.is_nan() || rhs.is_nan() || lhs.is_inf() && rhs.is_inf() ||
01607 lhs.is_zero() && rhs.is_zero() )
01608 {
01609 result.set_nan();
01610 return &result;
01611 }
01612
01613 if( lhs.is_inf() || rhs.is_zero() )
01614 {
01615 result.set_inf( lhs.m_sign * rhs.m_sign );
01616 return &result;
01617 }
01618
01619 if( lhs.is_zero() || rhs.is_inf() )
01620 {
01621 result.set_zero( lhs.m_sign * rhs.m_sign );
01622 return &result;
01623 }
01624
01625
01626
01627
01628
01629
01630 div_wl ++;
01631
01632 result.resize_to( sc_max( n_word( div_wl ) + 1, min_mant ) );
01633 result.m_mant.clear();
01634 result.m_sign = lhs.m_sign * rhs.m_sign;
01635
01636 int msb_lhs = scfx_find_msb( lhs.m_mant[lhs.m_msw] )
01637 + ( lhs.m_msw - lhs.m_wp ) * bits_in_word;
01638 int msb_rhs = scfx_find_msb( rhs.m_mant[rhs.m_msw] )
01639 + ( rhs.m_msw - rhs.m_wp ) * bits_in_word;
01640
01641 int msb_res = msb_lhs - msb_rhs;
01642 int to_shift = -msb_res % bits_in_word;
01643 int result_index;
01644
01645 int c = ( msb_res % bits_in_word >= 0 ) ? 1 : 0;
01646
01647 result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word;
01648 result.m_wp = (result.size() - c) - msb_res / bits_in_word;
01649
01650 scfx_rep remainder = lhs;
01651
01652
01653 remainder.lshift( to_shift );
01654
01655
01656 if( remainder.m_msw == remainder.size() - 1 )
01657 remainder.resize_to( remainder.size() + 1, 1 );
01658
01659
01660 int msw_diff = rhs.m_msw - remainder.m_msw;
01661 if (msw_diff > 0)
01662 remainder.resize_to( remainder.size() + msw_diff, -1 );
01663
01664 int counter;
01665
01666 for( counter = div_wl; counter && ! remainder.is_zero(); counter -- )
01667 {
01668 if( compare_msw_ff( rhs, remainder ) <= 0 )
01669 {
01670 result.set_bin( result_index );
01671 sub_with_index( remainder.m_mant, remainder.m_msw, remainder.m_lsw,
01672 rhs.m_mant, rhs.m_msw, rhs.m_lsw );
01673 }
01674 result_index --;
01675 remainder.shift_left( 1 );
01676 remainder.m_lsw = remainder.find_lsw();
01677 }
01678
01679
01680 if( counter == 0 )
01681 {
01682 int index = result_index + 1 - result.m_wp * bits_in_word;
01683
01684 scfx_index x = result.calc_indices( index );
01685 scfx_index x1 = result.calc_indices( index + 1 );
01686
01687 if( result.o_bit_at( x ) && result.o_bit_at( x1 ) )
01688 result.q_incr( x );
01689
01690 result.m_r_flag = true;
01691 }
01692
01693 result.find_sw();
01694
01695 return &result;
01696 }
01697
01698
01699
01700
01701
01702
01703 void
01704 scfx_rep::lshift( int n )
01705 {
01706 if( n == 0 )
01707 return;
01708
01709 if( n < 0 )
01710 {
01711 rshift( -n );
01712 return;
01713 }
01714
01715 if( is_normal() )
01716 {
01717 int shift_bits = n % bits_in_word;
01718 int shift_words = n / bits_in_word;
01719
01720
01721 if( m_msw == size() - 1 &&
01722 scfx_find_msb( m_mant[m_msw] ) >= bits_in_word - shift_bits )
01723 resize_to( size() + 1, 1 );
01724
01725
01726 m_wp -= shift_words;
01727 shift_left( shift_bits );
01728 find_sw();
01729 }
01730 }
01731
01732
01733
01734
01735
01736
01737 void
01738 scfx_rep::rshift( int n )
01739 {
01740 if( n == 0 )
01741 return;
01742
01743 if( n < 0 )
01744 {
01745 lshift( -n );
01746 return;
01747 }
01748
01749 if( is_normal() )
01750 {
01751 int shift_bits = n % bits_in_word;
01752 int shift_words = n / bits_in_word;
01753
01754
01755 if( m_lsw == 0 && scfx_find_lsb( m_mant[m_lsw] ) < shift_bits )
01756 resize_to( size() + 1, -1 );
01757
01758
01759 m_wp += shift_words;
01760 shift_right( shift_bits );
01761 find_sw();
01762 }
01763 }
01764
01765
01766
01767
01768
01769
01770
01771
01772 int
01773 compare_abs( const scfx_rep& a, const scfx_rep& b )
01774 {
01775
01776
01777 word a_word = a.m_mant[a.m_msw];
01778 word b_word = b.m_mant[b.m_msw];
01779
01780 if( a_word == 0 || b_word == 0 )
01781 {
01782 if( a_word != 0 )
01783 return 1;
01784 if( b_word != 0 )
01785 return -1;
01786 return 0;
01787 }
01788
01789
01790
01791 int a_msw = a.m_msw - a.m_wp;
01792 int b_msw = b.m_msw - b.m_wp;
01793
01794 if( a_msw > b_msw )
01795 return 1;
01796
01797 if( a_msw < b_msw )
01798 return -1;
01799
01800
01801
01802 int a_i = a.m_msw;
01803 int b_i = b.m_msw;
01804
01805 while( a_i >= a.m_lsw && b_i >= b.m_lsw )
01806 {
01807 a_word = a.m_mant[a_i];
01808 b_word = b.m_mant[b_i];
01809 if( a_word > b_word )
01810 return 1;
01811 if( a_word < b_word )
01812 return -1;
01813 -- a_i;
01814 -- b_i;
01815 }
01816
01817 bool a_zero = true;
01818 while( a_i >= a.m_lsw )
01819 {
01820 a_zero = a_zero && ( a.m_mant[a_i] == 0 );
01821 -- a_i;
01822 }
01823
01824 bool b_zero = true;
01825 while( b_i >= b.m_lsw )
01826 {
01827 b_zero = b_zero && ( b.m_mant[b_i] == 0 );
01828 -- b_i;
01829 }
01830
01831
01832
01833 if( ! a_zero && b_zero )
01834 return 1;
01835
01836 if( a_zero && ! b_zero )
01837 return -1;
01838
01839 return 0;
01840 }
01841
01842
01843
01844
01845
01846
01847
01848
01849 int
01850 cmp_scfx_rep( const scfx_rep& a, const scfx_rep& b )
01851 {
01852
01853
01854 if( a.is_nan() || b.is_nan() )
01855 {
01856 #if 0
01857 if( a.is_nan() && b.is_nan() )
01858 {
01859 return 0;
01860 }
01861 #endif
01862 return 2;
01863 }
01864
01865 if( a.is_inf() || b.is_inf() )
01866 {
01867 if( a.is_inf() )
01868 {
01869 if( ! a.is_neg() )
01870 {
01871 if( b.is_inf() && ! b.is_neg() )
01872 {
01873 return 0;
01874 }
01875 else
01876 {
01877 return 1;
01878 }
01879 }
01880 else
01881 {
01882 if( b.is_inf() && b.is_neg() )
01883 {
01884 return 0;
01885 }
01886 else
01887 {
01888 return -1;
01889 }
01890 }
01891 }
01892 if( b.is_inf() )
01893 {
01894 if( ! b.is_neg() )
01895 {
01896 return -1;
01897 }
01898 else
01899 {
01900 return 1;
01901 }
01902 }
01903 }
01904
01905 if( a.is_zero() && b.is_zero() )
01906 {
01907 return 0;
01908 }
01909
01910
01911
01912 if( a.m_sign != b.m_sign )
01913 {
01914 return a.m_sign;
01915 }
01916
01917 return ( a.m_sign * compare_abs( a, b ) );
01918 }
01919
01920
01921
01922
01923
01924
01925
01926
01927 void
01928 scfx_rep::quantization( const scfx_params& params, bool& q_flag )
01929 {
01930 scfx_index x = calc_indices( params.iwl() - params.wl() );
01931
01932 if( x.wi() < 0 )
01933 return;
01934
01935 if( x.wi() >= size() )
01936 resize_to( x.wi() + 1, 1 );
01937
01938 bool qb = q_bit( x );
01939 bool qz = q_zero( x );
01940
01941 q_flag = ( qb || ! qz );
01942
01943 if( q_flag )
01944 {
01945 switch( params.q_mode() )
01946 {
01947 case SC_TRN:
01948 {
01949 if( is_neg() )
01950 q_incr( x );
01951 break;
01952 }
01953 case SC_RND:
01954 {
01955 if( ! is_neg() )
01956 {
01957 if( qb )
01958 q_incr( x );
01959 }
01960 else
01961 {
01962 if( qb && ! qz )
01963 q_incr( x );
01964 }
01965 break;
01966 }
01967 case SC_TRN_ZERO:
01968 {
01969 break;
01970 }
01971 case SC_RND_INF:
01972 {
01973 if( qb )
01974 q_incr( x );
01975 break;
01976 }
01977 case SC_RND_CONV:
01978 {
01979 if( qb && ! qz || qb && qz && q_odd( x ) )
01980 q_incr( x );
01981 break;
01982 }
01983 case SC_RND_ZERO:
01984 {
01985 if( qb && ! qz )
01986 q_incr( x );
01987 break;
01988 }
01989 case SC_RND_MIN_INF:
01990 {
01991 if( ! is_neg() )
01992 {
01993 if( qb && ! qz )
01994 q_incr( x );
01995 }
01996 else
01997 {
01998 if( qb )
01999 q_incr( x );
02000 }
02001 break;
02002 }
02003 default:
02004 ;
02005 }
02006 q_clear( x );
02007
02008 find_sw();
02009 }
02010 }
02011
02012
02013
02014
02015
02016
02017
02018
02019 void
02020 scfx_rep::overflow( const scfx_params& params, bool& o_flag )
02021 {
02022 scfx_index x = calc_indices( params.iwl() - 1 );
02023
02024 if( x.wi() >= size() )
02025 resize_to( x.wi() + 1, 1 );
02026
02027 if( x.wi() < 0 )
02028 {
02029 resize_to( size() - x.wi(), -1 );
02030 x.wi( 0 );
02031 }
02032
02033 bool zero_left = o_zero_left( x );
02034 bool bit_at = o_bit_at( x );
02035 bool zero_right = o_zero_right( x );
02036
02037 bool under = false;
02038 bool over = false;
02039
02040 sc_enc enc = params.enc();
02041
02042 if( enc == SC_TC_ )
02043 {
02044 if( is_neg() )
02045 {
02046 if( params.o_mode() == SC_SAT_SYM )
02047 under = ( ! zero_left || bit_at );
02048 else
02049 under = ( ! zero_left || zero_left && bit_at && ! zero_right );
02050 }
02051 else
02052 over = ( ! zero_left || bit_at );
02053 }
02054 else
02055 {
02056 if( is_neg() )
02057 under = ( ! is_zero() );
02058 else
02059 over = ( ! zero_left );
02060 }
02061
02062 o_flag = ( under || over );
02063
02064 if( o_flag )
02065 {
02066 scfx_index x2 = calc_indices( params.iwl() - params.wl() );
02067
02068 if( x2.wi() < 0 )
02069 {
02070 resize_to( size() - x2.wi(), -1 );
02071 x.wi( x.wi() - x2.wi() );
02072 x2.wi( 0 );
02073 }
02074
02075 switch( params.o_mode() )
02076 {
02077 case SC_WRAP:
02078 {
02079 int n_bits = params.n_bits();
02080
02081 if( n_bits == 0 )
02082 {
02083
02084 toggle_tc();
02085 o_extend( x, enc );
02086 toggle_tc();
02087 }
02088 else if( n_bits < params.wl() )
02089 {
02090 scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits );
02091
02092
02093
02094 toggle_tc();
02095 o_set( x, x3, enc, under );
02096 o_extend( x, enc );
02097 toggle_tc();
02098 }
02099 else
02100 {
02101
02102 if( under )
02103 o_set_low( x, enc );
02104 else
02105 o_set_high( x, x2, enc );
02106 }
02107 break;
02108 }
02109 case SC_SAT:
02110 {
02111 if( under )
02112 o_set_low( x, enc );
02113 else
02114 o_set_high( x, x2, enc );
02115 break;
02116 }
02117 case SC_SAT_SYM:
02118 {
02119 if( under )
02120 {
02121 if( enc == SC_TC_ )
02122 o_set_high( x, x2, SC_TC_, -1 );
02123 else
02124 o_set_low( x, SC_US_ );
02125 }
02126 else
02127 o_set_high( x, x2, enc );
02128 break;
02129 }
02130 case SC_SAT_ZERO:
02131 {
02132 set_zero();
02133 break;
02134 }
02135 case SC_WRAP_SM:
02136 {
02137 SC_ERROR_IF_( enc == SC_US_,
02138 sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ );
02139
02140 int n_bits = params.n_bits();
02141
02142 if( n_bits == 0 )
02143 {
02144 scfx_index x4 = calc_indices( params.iwl() );
02145
02146 if( x4.wi() >= size() )
02147 resize_to( x4.wi() + 1, 1 );
02148
02149 toggle_tc();
02150 if( o_bit_at( x4 ) != o_bit_at( x ) )
02151 o_invert( x2 );
02152 o_extend( x, SC_TC_ );
02153 toggle_tc();
02154 }
02155 else if( n_bits == 1 )
02156 {
02157 toggle_tc();
02158 if( is_neg() != o_bit_at( x ) )
02159 o_invert( x2 );
02160 o_extend( x, SC_TC_ );
02161 toggle_tc();
02162 }
02163 else if( n_bits < params.wl() )
02164 {
02165 scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits );
02166 scfx_index x4 = calc_indices( params.iwl() - n_bits );
02167
02168
02169
02170 toggle_tc();
02171 if( is_neg() == o_bit_at( x4 ) )
02172 o_invert( x2 );
02173 o_set( x, x3, SC_TC_, under );
02174 o_extend( x, SC_TC_ );
02175 toggle_tc();
02176 }
02177 else
02178 {
02179 if( under )
02180 o_set_low( x, SC_TC_ );
02181 else
02182 o_set_high( x, x2, SC_TC_ );
02183 }
02184 break;
02185 }
02186 default:
02187 ;
02188 }
02189
02190 find_sw();
02191 }
02192 }
02193
02194
02195
02196
02197
02198
02199
02200
02201 void
02202 scfx_rep::cast( const scfx_params& params, bool& q_flag, bool& o_flag )
02203 {
02204 q_flag = false;
02205 o_flag = false;
02206
02207
02208
02209 if( is_zero() )
02210 {
02211 if( is_neg() )
02212 m_sign = 1;
02213 return;
02214 }
02215
02216
02217
02218 quantization( params, q_flag );
02219 overflow( params, o_flag );
02220
02221
02222
02223 if( is_zero() && is_neg() )
02224 m_sign = 1;
02225 }
02226
02227
02228
02229
02230
02231
02232 void
02233 align( const scfx_rep& lhs, const scfx_rep& rhs, int& new_wp,
02234 int& len_mant, scfx_mant_ref& lhs_mant, scfx_mant_ref& rhs_mant )
02235 {
02236 bool need_lhs = true;
02237 bool need_rhs = true;
02238
02239 if( lhs.m_wp != rhs.m_wp || lhs.size() != rhs.size() )
02240 {
02241 int lower_bound_lhs = lhs.m_lsw - lhs.m_wp;
02242 int upper_bound_lhs = lhs.m_msw - lhs.m_wp;
02243 int lower_bound_rhs = rhs.m_lsw - rhs.m_wp;
02244 int upper_bound_rhs = rhs.m_msw - rhs.m_wp;
02245
02246 int lower_bound = sc_min( lower_bound_lhs, lower_bound_rhs );
02247 int upper_bound = sc_max( upper_bound_lhs, upper_bound_rhs );
02248
02249 new_wp = -lower_bound;
02250 len_mant = sc_max( min_mant, upper_bound - lower_bound + 1 );
02251
02252 if( new_wp != lhs.m_wp || len_mant != lhs.size() )
02253 {
02254 lhs_mant = lhs.resize( len_mant, new_wp );
02255 need_lhs = false;
02256 }
02257
02258 if( new_wp != rhs.m_wp || len_mant != rhs.size() )
02259 {
02260 rhs_mant = rhs.resize( len_mant, new_wp );
02261 need_rhs = false;
02262 }
02263 }
02264
02265 if( need_lhs )
02266 {
02267 lhs_mant = lhs.m_mant;
02268 }
02269
02270 if( need_rhs )
02271 {
02272 rhs_mant = rhs.m_mant;
02273 }
02274 }
02275
02276
02277
02278
02279
02280
02281 int
02282 compare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs )
02283 {
02284
02285 if( rhs.m_msw < rhs.size() - 1 && rhs.m_mant[rhs.m_msw + 1 ] != 0 )
02286 {
02287 return -1;
02288 }
02289
02290 int lhs_size = lhs.m_msw - lhs.m_lsw + 1;
02291 int rhs_size = rhs.m_msw - rhs.m_lsw + 1;
02292
02293 int size = sc_min( lhs_size, rhs_size );
02294
02295 int lhs_index = lhs.m_msw;
02296 int rhs_index = rhs.m_msw;
02297
02298 int i;
02299
02300 for( i = 0;
02301 i < size && lhs.m_mant[lhs_index] == rhs.m_mant[rhs_index];
02302 i ++ )
02303 {
02304 lhs_index --;
02305 rhs_index --;
02306 }
02307
02308 if( i == size )
02309 {
02310 if( lhs_size == rhs_size )
02311 {
02312 return 0;
02313 }
02314
02315 if( lhs_size < rhs_size )
02316 {
02317 return -1;
02318 }
02319 else
02320 {
02321 return 1;
02322 }
02323 }
02324
02325 if( lhs.m_mant[lhs_index] < rhs.m_mant[rhs_index] )
02326 {
02327 return -1;
02328 } else {
02329 return 1;
02330 }
02331 }
02332
02333
02334
02335
02336
02337
02338 unsigned int
02339 scfx_rep::divide_by_ten()
02340 {
02341 #if defined( SC_BIG_ENDIAN )
02342 half_word* hw = (half_word*) &m_mant[m_msw];
02343 #elif defined( SC_LITTLE_ENDIAN )
02344 half_word* hw = ( (half_word*) &m_mant[m_msw] ) + 1;
02345 #endif
02346
02347 unsigned int remainder = 0;
02348
02349 word_short ls;
02350 ls.l = 0;
02351
02352 #if defined( SC_BIG_ENDIAN )
02353 for( int i = 0, end = ( m_msw - m_wp + 1 ) * 2; i < end; i ++ )
02354 #elif defined( SC_LITTLE_ENDIAN )
02355 for( int i = 0, end = -( m_msw - m_wp + 1 ) * 2; i > end; i -- )
02356 #endif
02357 {
02358 ls.s.u = static_cast<half_word>( remainder );
02359 ls.s.l = hw[i];
02360 remainder = ls.l % 10;
02361 ls.l /= 10;
02362 hw[i] = ls.s.l;
02363 }
02364
02365 return remainder;
02366 }
02367
02368
02369
02370
02371
02372
02373 void
02374 scfx_rep::multiply_by_ten()
02375 {
02376 int size = m_mant.size() + 1;
02377
02378 scfx_mant mant8( size );
02379 scfx_mant mant2( size );
02380
02381 size --;
02382
02383 mant8[size] = (m_mant[size - 1] >> (bits_in_word - 3));
02384 mant2[size] = (m_mant[size - 1] >> (bits_in_word - 1));
02385
02386 while( -- size )
02387 {
02388 mant8[size] = ( m_mant[size] << 3 ) |
02389 ( m_mant[size - 1] >> ( bits_in_word - 3 ) );
02390 mant2[size] = ( m_mant[size] << 1 ) |
02391 ( m_mant[size - 1] >> ( bits_in_word - 1 ) );
02392 }
02393
02394 mant8[0] = ( m_mant[0] << 3 );
02395 mant2[0] = ( m_mant[0] << 1 );
02396
02397 add_mants( m_mant.size(), m_mant, mant8, mant2 );
02398
02399 #if 0
02400 for( int i = size() - 1; i > 0; i -- )
02401 {
02402 m_mant[i] = ( m_mant[i] << 3 ) |
02403 ( m_mant[i-1] >> ( bits_in_word - 3 ) )
02404 + ( m_mant[i] << 1 ) |
02405 ( m_mant[i-1] >> ( bits_in_word - 1 ) );
02406 }
02407 m_mant[0] = ( m_mant[0] << 3 ) + ( m_mant[0] << 1 );
02408 #endif
02409 }
02410
02411
02412
02413
02414
02415
02416 void
02417 scfx_rep::normalize( int exponent )
02418 {
02419 int shift = exponent % bits_in_word;
02420 if( shift < 0 )
02421 {
02422 shift += bits_in_word;
02423 }
02424
02425 if( shift )
02426 {
02427 shift_left( shift );
02428 }
02429
02430 find_sw();
02431
02432 m_wp = (shift - exponent) / bits_in_word;
02433 }
02434
02435
02436
02437
02438
02439
02440 scfx_mant*
02441 scfx_rep::resize( int new_size, int new_wp ) const
02442 {
02443 scfx_mant *result = new scfx_mant( new_size );
02444
02445 result->clear();
02446
02447 int shift = new_wp - m_wp;
02448
02449 for( int j = m_lsw; j <= m_msw; j ++ )
02450 {
02451 (*result)[j+shift] = m_mant[j];
02452 }
02453
02454 return result;
02455 }
02456
02457
02458
02459
02460
02461
02462 void
02463 scfx_rep::set_bin( int i )
02464 {
02465 m_mant[i >> 5] |= 1 << ( i & 31 );
02466 }
02467
02468
02469
02470
02471
02472
02473 void
02474 scfx_rep::set_oct( int i, int n )
02475 {
02476 if( n & 1 )
02477 {
02478 m_mant[i >> 5] |= 1 << ( i & 31 );
02479 }
02480 i ++;
02481 if( n & 2 )
02482 {
02483 m_mant[i >> 5] |= 1 << ( i & 31 );
02484 }
02485 i ++;
02486 if( n & 4 )
02487 {
02488 m_mant[i >> 5] |= 1 << ( i & 31 );
02489 }
02490 }
02491
02492
02493
02494
02495
02496
02497 void
02498 scfx_rep::set_hex( int i, int n )
02499 {
02500 if( n & 1 )
02501 {
02502 m_mant[i >> 5] |= 1 << ( i & 31 );
02503 }
02504 i ++;
02505 if( n & 2 )
02506 {
02507 m_mant[i >> 5] |= 1 << ( i & 31 );
02508 }
02509 i ++;
02510 if( n & 4 )
02511 {
02512 m_mant[i >> 5] |= 1 << ( i & 31 );
02513 }
02514 i ++;
02515 if( n & 8 )
02516 {
02517 m_mant[i >> 5] |= 1 << ( i & 31 );
02518 }
02519 }
02520
02521
02522
02523
02524
02525
02526
02527
02528 void
02529 scfx_rep::shift_left( int n )
02530 {
02531 if( n != 0 )
02532 {
02533 int shift_left = n;
02534 int shift_right = bits_in_word - n;
02535
02536 SC_ASSERT_( !(m_mant[size()-1] >> shift_right),
02537 "shift_left overflow" );
02538
02539 for( int i = size() - 1; i > 0; i -- )
02540 {
02541 m_mant[i] = ( m_mant[i] << shift_left ) |
02542 ( m_mant[i-1] >> shift_right );
02543 }
02544 m_mant[0] <<= shift_left;
02545 }
02546 }
02547
02548
02549
02550
02551
02552
02553
02554
02555 void
02556 scfx_rep::shift_right( int n )
02557 {
02558 if( n != 0 )
02559 {
02560 int shift_left = bits_in_word - n;
02561 int shift_right = n;
02562
02563 SC_ASSERT_( !(m_mant[0] << shift_left), "shift_right overflow" );
02564
02565 for( int i = 0; i < size() - 1; i ++ )
02566 {
02567 m_mant[i] = ( m_mant[i] >> shift_right ) |
02568 ( m_mant[i+1] << shift_left );
02569 }
02570 m_mant[size()-1] >>= shift_right;
02571 }
02572 }
02573
02574
02575
02576
02577
02578
02579
02580
02581 bool
02582 scfx_rep::get_bit( int i ) const
02583 {
02584 if( ! is_normal() )
02585 return false;
02586
02587 scfx_index x = calc_indices( i );
02588
02589 if( x.wi() >= size() )
02590 return is_neg();
02591
02592 if( x.wi() < 0 )
02593 return false;
02594
02595 const_cast<scfx_rep*>( this )->toggle_tc();
02596
02597 bool result = ( m_mant[x.wi()] & ( 1 << x.bi() ) ) != 0;
02598
02599 const_cast<scfx_rep*>( this )->toggle_tc();
02600
02601 return result;
02602 }
02603
02604
02605
02606
02607
02608
02609
02610
02611 bool
02612 scfx_rep::set( int i, const scfx_params& params )
02613 {
02614 if( ! is_normal() )
02615 return false;
02616
02617 scfx_index x = calc_indices( i );
02618
02619 if( x.wi() >= size() )
02620 {
02621 if( is_neg() )
02622 return true;
02623 else
02624 resize_to( x.wi() + 1, 1 );
02625 }
02626 else if( x.wi() < 0 )
02627 {
02628 resize_to( size() - x.wi(), -1 );
02629 x.wi( 0 );
02630 }
02631
02632 toggle_tc();
02633
02634 m_mant[x.wi()] |= 1 << x.bi();
02635
02636 if( i == params.iwl() - 1 )
02637 o_extend( x, params.enc() );
02638
02639 toggle_tc();
02640
02641 find_sw();
02642
02643 return true;
02644 }
02645
02646
02647
02648
02649
02650
02651
02652
02653 bool
02654 scfx_rep::clear( int i, const scfx_params& params )
02655 {
02656 if( ! is_normal() )
02657 return false;
02658
02659 scfx_index x = calc_indices( i );
02660
02661 if( x.wi() >= size() )
02662 {
02663 if( ! is_neg() )
02664 return true;
02665 else
02666 resize_to( x.wi() + 1, 1 );
02667 }
02668 else if( x.wi() < 0 )
02669 return true;
02670
02671 toggle_tc();
02672
02673 m_mant[x.wi()] &= ~( 1 << x.bi() );
02674
02675 if( i == params.iwl() - 1 )
02676 o_extend( x, params.enc() );
02677
02678 toggle_tc();
02679
02680 find_sw();
02681
02682 return true;
02683 }
02684
02685
02686
02687
02688
02689
02690 bool
02691 scfx_rep::get_slice( int i, int j, const scfx_params&,
02692 sc_bv_base& bv ) const
02693 {
02694 if( is_nan() || is_inf() )
02695 return false;
02696
02697
02698
02699 int l = j;
02700 for( int k = 0; k < bv.length(); ++ k )
02701 {
02702 bv[k] = get_bit( l );
02703
02704 if( i >= j )
02705 ++ l;
02706 else
02707 -- l;
02708 }
02709
02710 return true;
02711 }
02712
02713 bool
02714 scfx_rep::set_slice( int i, int j, const scfx_params& params,
02715 const sc_bv_base& bv )
02716 {
02717 if( is_nan() || is_inf() )
02718 return false;
02719
02720
02721
02722 int l = j;
02723 for( int k = 0; k < bv.length(); ++ k )
02724 {
02725 if( bv[k].to_bool() )
02726 set( l, params );
02727 else
02728 clear( l, params );
02729
02730 if( i >= j )
02731 ++ l;
02732 else
02733 -- l;
02734 }
02735
02736 return true;
02737 }
02738
02739
02740
02741
02742
02743
02744 void
02745 scfx_rep::print( ::std::ostream& os ) const
02746 {
02747 os << to_string( SC_DEC, -1, SC_E );
02748 }
02749
02750
02751
02752
02753
02754
02755 void
02756 scfx_rep::dump( ::std::ostream& os ) const
02757 {
02758 os << "scfx_rep" << ::std::endl;
02759 os << "(" << ::std::endl;
02760
02761 os << "mant =" << ::std::endl;
02762 for( int i = size() - 1; i >= 0; i -- )
02763 {
02764 char buf[BUFSIZ];
02765 std::sprintf( buf, " %d: %10u (%8x)", i, (int) m_mant[i], (int) m_mant[i] );
02766 os << buf << ::std::endl;
02767 }
02768
02769 os << "wp = " << m_wp << ::std::endl;
02770 os << "sign = " << m_sign << ::std::endl;
02771
02772 os << "state = ";
02773 switch( m_state )
02774 {
02775 case normal:
02776 os << "normal";
02777 break;
02778 case infinity:
02779 os << "infinity";
02780 break;
02781 case not_a_number:
02782 os << "not_a_number";
02783 break;
02784 default:
02785 os << "unknown";
02786 }
02787 os << ::std::endl;
02788
02789 os << "msw = " << m_msw << ::std::endl;
02790 os << "lsw = " << m_lsw << ::std::endl;
02791
02792 os << ")" << ::std::endl;
02793 }
02794
02795
02796
02797
02798
02799
02800 void
02801 scfx_rep::get_type( int& wl, int& iwl, sc_enc& enc ) const
02802 {
02803 if( is_nan() || is_inf() )
02804 {
02805 wl = 0;
02806 iwl = 0;
02807 enc = SC_TC_;
02808 return;
02809 }
02810
02811 if( is_zero() )
02812 {
02813 wl = 1;
02814 iwl = 1;
02815 enc = SC_US_;
02816 return;
02817 }
02818
02819 int msb = ( m_msw - m_wp ) * bits_in_word
02820 + scfx_find_msb( m_mant[ m_msw ] ) + 1;
02821 while( get_bit( msb ) == get_bit( msb - 1 ) )
02822 {
02823 -- msb;
02824 }
02825
02826 int lsb = ( m_lsw - m_wp ) * bits_in_word
02827 + scfx_find_lsb( m_mant[ m_lsw ] );
02828
02829 if( is_neg() )
02830 {
02831 wl = msb - lsb + 1;
02832 iwl = msb + 1;
02833 enc = SC_TC_;
02834 }
02835 else
02836 {
02837 wl = msb - lsb;
02838 iwl = msb;
02839 enc = SC_US_;
02840 }
02841 }
02842
02843
02844
02845
02846
02847
02848
02849
02850 void
02851 scfx_rep::round( int wl )
02852 {
02853
02854
02855 if( is_nan() || is_inf() || is_zero() )
02856 return;
02857
02858
02859
02860 int wl_effective;
02861
02862 wl_effective = ( m_msw - m_lsw + 1 ) * bits_in_word;
02863 if( wl_effective <= wl )
02864 return;
02865
02866
02867
02868 int msb = scfx_find_msb( m_mant[m_msw] );
02869 int lsb = scfx_find_lsb( m_mant[m_lsw] );
02870
02871 wl_effective = ( m_msw * bits_in_word + msb ) -
02872 ( m_lsw * bits_in_word + lsb ) + 1;
02873 if( wl_effective <= wl )
02874 return;
02875
02876
02877
02878 int wi = m_msw - ( wl - 1 ) / bits_in_word;
02879 int bi = msb - ( wl - 1 ) % bits_in_word;
02880 if( bi < 0 )
02881 {
02882 -- wi;
02883 bi += bits_in_word;
02884 }
02885
02886 scfx_index x( wi, bi );
02887
02888 if( q_bit( x ) && ! q_zero( x ) ||
02889 q_bit( x ) && q_zero( x ) && q_odd( x ) )
02890 q_incr( x );
02891 q_clear( x );
02892
02893 find_sw();
02894
02895 m_r_flag = true;
02896 }
02897
02898 }
02899
02900
02901