⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scfx_rep.cpp

📁 system C源码 一种替代verilog的语言
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    m_state = normal;    find_sw();    //    // two's complement of mantissa if it is negative    //    if( mant_is_neg )    {	m_mant[m_msw] |=  -1 << scfx_find_msb( m_mant[m_msw] );	for( int i = m_msw + 1; i < m_mant.size(); ++ i )	    m_mant[i] = static_cast<word>( -1 );	complement( m_mant, m_mant, m_mant.size() );	inc( m_mant );	m_sign *= -1;	find_sw();    }}#undef SCFX_FAIL_IF_// ----------------------------------------------------------------------------//  METHOD : to_double////  Convert from scfx_rep to double.// ----------------------------------------------------------------------------doublescfx_rep::to_double() const {    scfx_ieee_double id;    // handle special cases    if( is_nan() )    {        id.set_nan();	return id;    }    if( is_inf() )    {        id.set_inf();	id.negative( m_sign < 0 );	return id;    }    if( is_zero() )    {	id = 0.;	id.negative( m_sign < 0 );	return id;    }    int msb = scfx_find_msb( m_mant[m_msw] );    int exp = (m_msw - m_wp) * bits_in_word + msb;    if( exp > SCFX_IEEE_DOUBLE_E_MAX )    {	id.set_inf();	id.negative( m_sign < 0 );	return id;    }    if( exp < SCFX_IEEE_DOUBLE_E_MIN	- static_cast<int>( SCFX_IEEE_DOUBLE_M_SIZE ) )    {	id = 0.;	return id;    }     int shift = mantissa0_size - msb;    unsigned int m0;    unsigned int m1 = 0;    unsigned int guard = 0;    if( shift == 0 )    {        m0 = m_mant[m_msw] & ~( 1 << mantissa0_size );	if( m_msw > m_lsw )	{	    m1 = m_mant[m_msw - 1];	    if( m_msw - 1 > m_lsw )	        guard = m_mant[m_msw - 2] >> ( bits_in_word - 1 );	}    }    else if( shift < 0 )    {	m0 = ( m_mant[m_msw] >> -shift ) & ~( 1 << mantissa0_size );	m1 = m_mant[m_msw] << ( bits_in_word + shift );	if( m_msw > m_lsw )	{	    m1 |= m_mant[m_msw - 1] >> -shift;	    guard = ( m_mant[m_msw - 1] >> ( -shift - 1 ) ) & 1;	}    }    else    {	m0 = ( m_mant[m_msw] << shift ) & ~( 1 << mantissa0_size );	if( m_msw > m_lsw )	{	    m0 |= m_mant[m_msw - 1] >> ( bits_in_word - shift );	    m1 = m_mant[m_msw - 1] << shift;	    if( m_msw - 1 > m_lsw )	    {	        m1 |= m_mant[m_msw - 2] >> ( bits_in_word - shift );		guard = ( m_mant[m_msw - 2] >> (bits_in_word - shift - 1) )                      & 1;	    }      	}    }    if( exp < SCFX_IEEE_DOUBLE_E_MIN )    {	m0 |= ( 1 << mantissa0_size );	int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp;	if( subnormal_shift < bits_in_word )	{	    m1 = m1 >> subnormal_shift	       | m0 << ( bits_in_word - subnormal_shift );	    m0 = m0 >> subnormal_shift;	}	else	{	    m1 = m0 >> ( subnormal_shift - bits_in_word );	    m0 = 0;	}	guard = 0;	exp = SCFX_IEEE_DOUBLE_E_MIN - 1;    }    id.mantissa0( m0 );    id.mantissa1( m1 );    id.exponent( exp );    id.negative( m_sign < 0 );    double result = id;    if( guard != 0 )        result += m_sign * scfx_pow2( exp - SCFX_IEEE_DOUBLE_M_SIZE );    return result;}// ----------------------------------------------------------------------------//  METHOD : to_string////  Convert from scfx_rep to character string.// ----------------------------------------------------------------------------voidprint_dec( scfx_string& s, const scfx_rep& num, int w_prefix, sc_fmt fmt ){    if( num.is_neg() )	s += '-';    if( w_prefix == 1 ) {	scfx_print_prefix( s, SC_DEC );    }    if( num.is_zero() )    {	s += '0';	return;    }    // split 'num' into its integer and fractional part    scfx_rep int_part  = num;    scfx_rep frac_part = num;    int i;        for( i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i ++ )	int_part.m_mant[i] = 0;    int_part.find_sw();    if( int_part.m_wp < int_part.m_lsw )	int_part.resize_to( int_part.size() - int_part.m_wp, -1 );        for( i = frac_part.m_msw;	 i >= frac_part.m_lsw && i >= frac_part.m_wp;	 i -- )	frac_part.m_mant[i] = 0;    frac_part.find_sw();    if( frac_part.m_msw == frac_part.size() - 1 )	frac_part.resize_to( frac_part.size() + 1, 1 );    // print integer part    int int_digits = 0;    int int_zeros  = 0;        if( ! int_part.is_zero() )    {	double int_wl = ( int_part.m_msw - int_part.m_wp ) * bits_in_word	              + scfx_find_msb( int_part.m_mant[int_part.m_msw] ) + 1;	int_digits = (int) ceil( int_wl * log10( 2. ) );	int len = s.length();	s.append( int_digits );	bool zero_digits = ( frac_part.is_zero() && fmt != SC_F );	for( i = int_digits + len - 1; i >= len; i-- )	{	    unsigned int remainder = int_part.divide_by_ten();	    s[i] = static_cast<char>( '0' + remainder );	    	    if( zero_digits )	    {		if( remainder == 0 )		    int_zeros ++;		else		    zero_digits = false;	    }	}	// discard trailing zeros from int_part	s.discard( int_zeros );	if( s[len] == '0' )	{	    // int_digits was overestimated by one	    s.remove( len );	    -- int_digits;	}    }    // print fractional part    int frac_digits = 0;    int frac_zeros  = 0;    if( ! frac_part.is_zero() )    {	s += '.';	bool zero_digits = ( int_digits == 0 && fmt != SC_F );	double frac_wl = ( frac_part.m_wp - frac_part.m_msw ) * bits_in_word	               - scfx_find_msb( frac_part.m_mant[frac_part.m_msw] )                       - 1;	frac_zeros = (int) floor( frac_wl * log10( 2. ) );	scfx_rep temp;	sc_dt::multiply( temp, frac_part, pow10_fx( frac_zeros ) );	frac_part = temp;	if( frac_part.m_msw == frac_part.size() - 1 )	    frac_part.resize_to( frac_part.size() + 1, 1 );		frac_digits = frac_zeros;	if( ! zero_digits )	{	    for( i = 0; i < frac_zeros; i ++ )		s += '0';	    frac_zeros = 0;	}	while( ! frac_part.is_zero() )	{	    frac_part.multiply_by_ten();	    int n = frac_part.m_mant[frac_part.m_msw + 1];		    if( zero_digits )	    {		if( n == 0 )		    frac_zeros ++;		else		    zero_digits = false;	    }		    if( ! zero_digits )		s += static_cast<char>( '0' + n );	    frac_part.m_mant[frac_part.m_msw + 1] = 0;	    frac_digits ++;	}    }    // print exponent        if( fmt != SC_F )    {        if( frac_digits == 0 )	    scfx_print_exp( s, int_zeros );	else if( int_digits == 0 )	    scfx_print_exp( s, - frac_zeros );    }}voidprint_other( scfx_string& s, const scfx_rep& a, sc_numrep numrep, int w_prefix,	     sc_fmt fmt, const scfx_params* params ){    scfx_rep b = a;    sc_numrep numrep2 = numrep;    bool numrep_is_sm = ( numrep == SC_BIN_SM ||			  numrep == SC_OCT_SM ||			  numrep == SC_HEX_SM );    if( numrep_is_sm )    {	if( b.is_neg() )	{	    s += '-';	    b = *neg_scfx_rep( a );	}	switch( numrep )	{	    case SC_BIN_SM:		numrep2 = SC_BIN_US;		break;	    case SC_OCT_SM:		numrep2 = SC_OCT_US;		break;	    case SC_HEX_SM:		numrep2 = SC_HEX_US;		break;	    default:		;	}    }        if( w_prefix != 0 ) {	scfx_print_prefix( s, numrep );    }    numrep = numrep2;    int msb, lsb;    if( params != 0 )    {	msb = params->iwl() - 1;	lsb = params->iwl() - params->wl();	if( params->enc() == SC_TC_ &&	    ( numrep == SC_BIN_US ||	      numrep == SC_OCT_US ||	      numrep == SC_HEX_US ) &&	    ! numrep_is_sm &&	    params->wl() > 1 )	    -- msb;	else if( params->enc() == SC_US_ &&	    ( numrep == SC_BIN ||	      numrep == SC_OCT ||	      numrep == SC_HEX ||	      numrep == SC_CSD ) )	    ++ msb;    }    else    {	if( b.is_zero() )	{	    msb = 0;	    lsb = 0;	}	else	{	    msb = ( b.m_msw - b.m_wp ) * bits_in_word		+ scfx_find_msb( b.m_mant[ b.m_msw ] ) + 1;	    while( b.get_bit( msb ) == b.get_bit( msb - 1 ) )		-- msb;	    if( numrep == SC_BIN_US ||		numrep == SC_OCT_US ||		numrep == SC_HEX_US )		-- msb;	    lsb = ( b.m_lsw - b.m_wp ) * bits_in_word		+ scfx_find_lsb( b.m_mant[ b.m_lsw ] );	}    }    int step;    switch( numrep )    {	case SC_BIN:	case SC_BIN_US:	case SC_CSD:	    step = 1;	   break;	case SC_OCT:	case SC_OCT_US:	    step = 3;	    break;	case SC_HEX:	case SC_HEX_US:	    step = 4;	    break;	default:	    step = 0;    }    msb = (int) ceil( double( msb + 1 ) / step ) * step - 1;    lsb = (int) floor( double( lsb ) / step ) * step;    if( msb < 0 )    {	s += '.';	if( fmt == SC_F )	{	    int sign = ( b.is_neg() ) ? ( 1 << step ) - 1 : 0;	    for( int i = ( msb + 1 ) / step; i < 0; i ++ )	    {		if( sign < 10 )		    s += static_cast<char>( sign + '0' );		else		    s += static_cast<char>( sign + 'a' - 10 );	    }	}    }    int i = msb;    while( i >= lsb )    {        int value = 0;        for( int j = step - 1; j >= 0; -- j )	{            value += static_cast<int>( b.get_bit( i ) ) << j;            -- i;        }        if( value < 10 )            s += static_cast<char>( value + '0' );	else            s += static_cast<char>( value + 'a' - 10 );	if( i == -1 )	    s += '.';    }    if( lsb > 0 && fmt == SC_F )    {	for( int i = lsb / step; i > 0; i -- )	    s += '0';    }    if( s[s.length() - 1] == '.' )	s.discard( 1 );    if( fmt != SC_F )    {	if( msb < 0 )	    scfx_print_exp( s, ( msb + 1 ) / step );	else if( lsb > 0 )	    scfx_print_exp( s, lsb / step );    }    if( numrep == SC_CSD )	scfx_tc2csd( s, w_prefix );}const char*scfx_rep::to_string( sc_numrep numrep, int w_prefix,		     sc_fmt fmt, const scfx_params* params ) const{    static scfx_string s;    s.clear();    if( is_nan() )        scfx_print_nan( s );    else if( is_inf() )        scfx_print_inf( s, is_neg() );    else if( is_neg() && ! is_zero() &&	     ( numrep == SC_BIN_US ||	       numrep == SC_OCT_US ||	       numrep == SC_HEX_US ) )        s += "negative";    else if( numrep == SC_DEC || numrep == SC_NOBASE )        sc_dt::print_dec( s, *this, w_prefix, fmt );    else        sc_dt::print_other( s, *this, numrep, w_prefix, fmt, params );    return s;}// ----------------------------------------------------------------------------//  ADD////  add two mantissas of the same size//  result has the same size//  returns carry of operation// ----------------------------------------------------------------------------static inlineintadd_mants( int size, scfx_mant& result,	   const scfx_mant& a, const scfx_mant& b ){    unsigned int carry = 0;    int index = 0;    do    {        word x = a[index];	word y = b[index];	y += carry;	carry = y < carry;	y += x;	carry += y < x;	result[index] = y;    }    while( ++ index < size );    return ( carry ? 1 : 0 );}static inlineintsub_mants( int size, scfx_mant& result,	   const scfx_mant& a, const scfx_mant& b ){    unsigned carry = 0;    int index = 0;    do    {	word x = a[index];	word y = b[index];	y += carry;	carry = y < carry;	y = x - y;	carry += y > x;	result[index] = y;    }    while( ++ index < size );    return ( carry ? 1 : 0 );}scfx_rep*add_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl ){    scfx_rep& result = *new scfx_rep;    //    // check for special cases    //    if( lhs.is_nan() || rhs.is_nan()    ||  ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign ) )    {	result.set_nan();	return &result;    }    if( lhs.is_inf() )    {	result.set_inf( lhs.m_sign );	return &result;    }    if( rhs.is_inf() )    {	result.set_inf( rhs.m_sign );	return &result;    }    //    // align operands if needed    //    scfx_mant_ref lhs_mant;    scfx_mant_ref rhs_mant;    int len_mant = lhs.size();    int new_wp = lhs.m_wp;    align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );    //    // size the result mantissa    //    result.resize_to( len_mant );    result.m_wp = new_wp;    //    // do it    //    if( lhs.m_sign == rhs.m_sign )    {	add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );	result.m_sign = lhs.m_sign;    }    else    {	int cmp = compare_abs( lhs, rhs );	if( cmp == 1 )	{	    sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );	    result.m_sign = lhs.m_sign;	}	else if ( cmp == -1 )	{	    sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );	    result.m_sign = rhs.m_sign;	}	else	{	    result.m_mant.clear();	    result.m_sign = 1;	}    }    result.find_sw();    result.round( max_wl );    return &result;}// ----------------------------------------------------------------------------//  SUB////  sub two word's of the same size//  result has the same size//  returns carry of operation// ----------------------------------------------------------------------------static inlineintsub_with_index(       scfx_mant& a, int a_msw, int a_lsw,		const scfx_mant& b, int b_msw, int b_lsw ){    unsigned carry = 0;    int size    = b_msw - b_lsw;    int a_index = a_msw - size;    int b_index = b_msw - size;    do    {	word x = a[a_index];	word y = b[b_index];	y += carry;	carry = y < carry;	y = x - y;	carry += y > x;	a[a_index] = y;	a_index ++;	b_index ++;    }    while( size -- );    if( carry )    {        // special case: a[a_msw + 1 ] == 1        a[a_msw + 1] = 0;    }    return ( carry ? 1 : 0 );}scfx_rep*sub_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl ){    scfx_rep& result = *new scfx_rep;    //    // check for special cases    //    if( lhs.is_nan() || rhs.is_nan()    ||  ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign ) )    {	result.set_nan();	return &result;    }    if( lhs.is_inf() )    {	result.set_inf( lhs.m_sign );	return &result;    }    if( rhs.is_inf() )    {	result.set_inf( -1 * rhs.m_sign );	return &result;    }    //    // align operands if needed    //    scfx_mant_ref lhs_mant;    scfx_mant_ref rhs_mant;    int len_mant = lhs.size();    int new_wp = lhs.m_wp;    align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );    //    // size the result mantissa    //    result.resize_to( len_mant );    result.m_wp = new_wp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -