Jump to content

template class with sc_fixed


samng

Recommended Posts

Hi

 

sc_fixed type looks ahead to the type of the destination variable to pick the right action for quatisation and overflow handling:

 

sc_fixed<6,6> a = 13;

sc_fixed<5,5,SC_RND> b  = a>>1;

 

a become 7.

 

But using sc_fixed in a template class like:

 

template <class T, int N> class Vector {

     T m_array[N];

 

     Vector operator>> (const unisgned int m) const {

          Vector tmp;

          for (int i=0; i<N; i++)

             tmp.m_array = m_array>>m;

     }

};

 

.....

 

Vector <sc_fixed<6,6>,1 > a;

Vector <sc_fixed<5,5,SC_RND>,1 > b = a >> 1;

 

a[0] is now 6 not 7, because the return type of operator >> is still Vector<sc_fixed<6,6>,1 >.

 

Is there anyway to write the template class/operator that can see the type of b so that sc_fixed rounding behaviour can preserved?

 

Thanks

Sam

 

 

 

Link to comment
Share on other sites

Sam,

 

sc_fixed type looks ahead to the type of the destination variable to pick the right action for quatisation and overflow handling:

 

That's not fully correct.  In C++, you can't (directly) consider the return-type of a function (e.g: for overloading) to adapt the behaviour.  You need to resort to intermediate values instead.  In case of sc_fix(ed)/sc_fxnum, this intermediate value is sc_fxval, a variable-precision fixed-point value.  Objects of this type always carry the required amount of bits during run-time and the assignment to another finite-precision type (sc_fxnum et.al.) handles the quantisation and overflow.

 

Is there anyway to write the template class/operator that can see the type of b so that sc_fixed rounding behaviour can preserved?

 

AFAICS, you want to build a container class template for arithmetic types that provides element-wise operators.  In order to deal with such intermediate values, there are several options depending on the level of generality you need to achieve and the constraints on the C++ language features, you can rely on.  Disclaimer: The following snippets are fully untested.

 

Simplest solution: Return a Vector<sc_fxval> instead (and provide an appropriate assignment operator/conversion constructor):

     Vector<sc_fxval,N> operator>> (unsigned m) const {
          Vector<sc_fxval,N> tmp;
          for (int i=0; i<N; i++)
             tmp.m_array[i] = m_array[i]>>m;
          return tmp;
     }

Of course, this will limit the use of this shift operator in your Vector template to classes, where the result of the  shift operator on the elements can be reasonably converted to sc_fxval.

 

As a second option, you can use C++11's  decltype and new function declaration syntax:

 

     auto operator>> (unsigned m) const -> Vector< decltype(T() >> m), N > {
          typedef decltype( T() >> m ) return_type;
          Vector<return_type,N> tmp;
          for (int i=0; i<N; i++)
             tmp.m_array[i] = m_array[i]>>m;
          return tmp;
     }

This should work correctly for arbitrary shift operators and return an array of shift results.

Since your compiler may not support these shiny new features of C++11, you can use a traits class with (partial) specialisation:

 

template< typename T > struct vector_element_traits;

// partial specialisation for sc_fixed
template< int WordLength, int IntegerWordLength, sc_o_mode Overflow, sc_q_mode Quantization >
struct vector_element_traits< sc_fixed<WordLength, IntegerWordLength, Overflow, Quantization > >
{
  typedef sc_fxval right_shift_result;
};

// ...

Vector<typename vector_element_traits<T>::right_shift_result,N> operator>> (unsigned m) const {
    Vector<typename vector_element_traits<T>::right_shift_result,N> > tmp;
    for (int i=0; i<N; i++)
        tmp.m_array[i] = m_array[i]>>m;
    return tmp;
}

 

Last but not least, you can defer the evaluation of the element-wise operator by using expression templates to the implementation of the assignment operator of the vector.  But this may be a bit too advanced for tonight. ;-)

 

Greetings from Oldenburg,
  Philipp

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...