📄 sc_fxnum.cpp
字号:
high = full_circle - resolution; } double val = c; sc_fxval_fast c2 = c; bool under = ( val < low ); bool over = ( val > high ); o_flag = ( under || over ); if( o_flag ) { switch( params.o_mode() ) { case SC_WRAP: // wrap-around { int n_bits = params.n_bits(); if( n_bits == 0 ) { // wrap-around all 'wl' bits val -= floor( val / full_circle ) * full_circle; if( val > high ) val -= full_circle; } else if( n_bits < params.wl() ) { double X = scfx_pow2( iwl - n_bits ); // wrap-around least significant 'wl - n_bits' bits val -= floor( val / X ) * X; if( val > ( X - resolution ) ) val -= X; // saturate most significant 'n_bits' bits if( under ) val += low; else { if( params.enc() == SC_TC_ ) val += full_circle / 2.0 - X; else val += full_circle - X; } } else { // saturate all 'wl' bits if( under ) val = low; else val = high; } break; } case SC_SAT: // saturation case SC_SAT_SYM: // symmetrical saturation { if( under ) val = low; else val = high; break; } case SC_SAT_ZERO: // saturation to zero { val = 0.0; break; } case SC_WRAP_SM: // sign magnitude wrap-around { SC_ERROR_IF_( params.enc() == SC_US_, sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ ); int n_bits = params.n_bits(); if( n_bits == 0 ) { // invert conditionally if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) ) val = -val - resolution; // wrap-around all 'wl' bits val -= floor( val / full_circle ) * full_circle; if( val > high ) val -= full_circle; } else if( n_bits == 1 ) { // invert conditionally if( c2.is_neg() != c2.get_bit( iwl - 1 ) ) val = -val - resolution; // wrap-around all 'wl' bits val -= floor( val / full_circle ) * full_circle; if( val > high ) val -= full_circle; } else if( n_bits < params.wl() ) { // invert conditionally if( c2.is_neg() == c2.get_bit( iwl - n_bits ) ) val = -val - resolution; double X = scfx_pow2( iwl - n_bits ); // wrap-around least significant 'wl - n_bits' bits val -= floor( val / X ) * X; if( val > ( X - resolution ) ) val -= X; // saturate most significant 'n_bits' bits if( under ) val += low; else val += full_circle / 2.0 - X; } else { // saturate all 'wl' bits if( under ) val = low; else val = high; } break; } default: ; } c = val; }}voidsc_fxnum_fast::cast(){ scfx_ieee_double id( m_val ); SC_ERROR_IF_( id.is_nan() || id.is_inf(), sc_core::SC_ID_INVALID_FX_VALUE_); if( m_params.cast_switch() == SC_ON ) { m_q_flag = false; m_o_flag = false; // check for special cases if( id.is_zero() ) { if( id.negative() != 0 ) m_val = -m_val; return; } // perform casting sc_dt::quantization( m_val, m_params, m_q_flag ); sc_dt::overflow( m_val, m_params, m_o_flag ); // check for special case: -0 id = m_val; if( id.is_zero() && id.negative() != 0 ) { m_val = -m_val; } // check for special case: NaN of Inf if( id.is_nan() || id.is_inf() ) { m_val = 0.0; } }}// defined in sc_fxval.cpp;externconst char*to_string( const scfx_ieee_double&, sc_numrep, int, sc_fmt, const scfx_params* = 0 );// explicit conversion to character stringconst std::stringsc_fxnum_fast::to_string() const{ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );}const std::stringsc_fxnum_fast::to_string( sc_numrep numrep ) const{ return std::string( sc_dt::to_string( m_val, numrep, -1, SC_F, &m_params ) );}const std::stringsc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix ) const{ return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), SC_F, &m_params ) );}const std::stringsc_fxnum_fast::to_string( sc_fmt fmt ) const{ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt, &m_params ) );}const std::stringsc_fxnum_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const{ return std::string( sc_dt::to_string( m_val, numrep, -1, fmt, &m_params ) );}const std::stringsc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const{ return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), fmt, &m_params ) );}const std::stringsc_fxnum_fast::to_dec() const{ return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );}const std::stringsc_fxnum_fast::to_bin() const{ return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_F, &m_params ) );}const std::stringsc_fxnum_fast::to_oct() const{ return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_F, &m_params ) );}const std::stringsc_fxnum_fast::to_hex() const{ return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_F, &m_params ) );}// print or dump contentvoidsc_fxnum_fast::print( ::std::ostream& os ) const{ os << sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params );}voidsc_fxnum_fast::scan( ::std::istream& is ){ std::string s; is >> s; *this = s.c_str();}voidsc_fxnum_fast::dump( ::std::ostream& os ) const{ os << "sc_fxnum_fast" << ::std::endl; os << "(" << ::std::endl; os << "val = " << m_val << ::std::endl; os << "params = "; m_params.dump( os ); os << "q_flag = " << m_q_flag << ::std::endl; os << "o_flag = " << m_o_flag << ::std::endl; // TO BE COMPLETED // os << "observer = "; // if( m_observer != 0 ) // m_observer->dump( os ); // else // os << "0" << ::std::endl; os << ")" << ::std::endl;}// internal use only;boolsc_fxnum_fast::get_bit( int i ) const{ scfx_ieee_double id( m_val ); if( id.is_zero() || id.is_nan() || id.is_inf() ) return false; // convert to two's complement unsigned int m0 = id.mantissa0(); unsigned int m1 = id.mantissa1(); if( id.is_normal() ) m0 += 1U << 20; if( id.negative() != 0 ) { m0 = ~ m0; m1 = ~ m1; unsigned int tmp = m1; m1 += 1U; if( m1 <= tmp ) m0 += 1U; } // get the right bit int j = i - id.exponent(); if( ( j += 20 ) >= 32 ) return ( ( m0 & 1U << 31 ) != 0 ); else if( j >= 0 ) return ( ( m0 & 1U << j ) != 0 ); else if( ( j += 32 ) >= 0 ) return ( ( m1 & 1U << j ) != 0 ); else return false;}boolsc_fxnum_fast::set_bit( int i, bool high ){ scfx_ieee_double id( m_val ); if( id.is_nan() || id.is_inf() ) return false; if( high ) { if( get_bit( i ) ) return true; if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) m_val -= scfx_pow2( i ); else m_val += scfx_pow2( i ); } else { if( ! get_bit( i ) ) return true; if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) m_val += scfx_pow2( i ); else m_val -= scfx_pow2( i ); } return true;}boolsc_fxnum_fast::get_slice( int i, int j, sc_bv_base& bv ) const{ scfx_ieee_double id( m_val ); if( id.is_nan() || id.is_inf() ) return false; // convert to two's complement unsigned int m0 = id.mantissa0(); unsigned int m1 = id.mantissa1(); if( id.is_normal() ) m0 += 1U << 20; if( id.negative() != 0 ) { m0 = ~ m0; m1 = ~ m1; unsigned int tmp = m1; m1 += 1U; if( m1 <= tmp ) m0 += 1U; } // get the bits int l = j; for( int k = 0; k < bv.length(); ++ k ) { bool b = false; int n = l - id.exponent(); if( ( n += 20 ) >= 32 ) b = ( ( m0 & 1U << 31 ) != 0 ); else if( n >= 0 ) b = ( ( m0 & 1U << n ) != 0 ); else if( ( n += 32 ) >= 0 ) b = ( ( m1 & 1U << n ) != 0 ); bv[k] = b; if( i >= j ) ++ l; else -- l; } return true;}boolsc_fxnum_fast::set_slice( int i, int j, const sc_bv_base& bv ){ scfx_ieee_double id( m_val ); if( id.is_nan() || id.is_inf() ) return false; // set the bits int l = j; for( int k = 0; k < bv.length(); ++ k ) { if( bv[k].to_bool() ) { if( ! get_bit( l ) ) { if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) m_val -= scfx_pow2( l ); else m_val += scfx_pow2( l ); } } else { if( get_bit( l ) ) { if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) m_val += scfx_pow2( l ); else m_val -= scfx_pow2( l ); } } if( i >= j ) ++ l; else -- l; } return true;}sc_fxnum_fast_observer*sc_fxnum_fast::lock_observer() const{ SC_ASSERT_( m_observer != 0, "lock observer failed" ); sc_fxnum_fast_observer* tmp = m_observer; m_observer = 0; return tmp;}voidsc_fxnum_fast::unlock_observer( sc_fxnum_fast_observer* observer_ ) const{ SC_ASSERT_( observer_ != 0, "unlock observer failed" ); m_observer = observer_;}} // namespace sc_dt// Taf!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -