sc_unsigned.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2005 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_unsigned.h -- Arbitrary precision unsigned arithmetic.
00021  
00022     This file includes the definitions of sc_unsigned_bitref,
00023     sc_unsigned_subref, and sc_unsigned classes. The first two classes
00024     are proxy classes to reference one bit and a range of bits of a
00025     sc_unsigned number, respectively.
00026 
00027     An sc_signed number has the sign-magnitude representation
00028     internally. However, its interface guarantees a 2's-complement
00029     representation. The sign-magnitude representation is chosen
00030     because of its efficiency: The sc_signed and sc_unsigned types are
00031     optimized for arithmetic rather than bitwise operations. For
00032     arithmetic operations, the sign-magnitude representation performs
00033     better.
00034 
00035     It is also important to note that an sc_unsigned number with n
00036     bits is equivalent to an sc_signed non-negative number with n + 1
00037     bits.
00038 
00039     The implementations of sc_signed and sc_unsigned classes are
00040     almost identical: Most of the member and friend functions are
00041     defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can
00042     be shared by both of these classes. These functions are chosed by
00043     defining a few macros before including them such as IF_SC_SIGNED
00044     and CLASS_TYPE. Our implementation choices are mostly dictated by
00045     performance considerations in that we tried to provide the most
00046     efficient sc_signed and sc_unsigned types without compromising
00047     their interface.
00048 
00049     For the behavior of operators, we have two semantics: the old and
00050     new. The most important difference between these two semantics is
00051     that the old semantics is closer to C/C++ semantics in that the
00052     result type of a binary operator on unsigned and signed arguments
00053     is unsigned; the new semantics, on the other hand, requires the
00054     result type be signed. The new semantics is required by the VSIA
00055     C/C++ data types standard. We have implemented the new semantics.
00056 
00057   Original Author: Ali Dasdan, Synopsys, Inc.
00058   
00059  *****************************************************************************/
00060 
00061 /*****************************************************************************
00062 
00063   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00064   changes you are making here.
00065 
00066       Name, Affiliation, Date:
00067   Description of Modification:
00068 
00069  *****************************************************************************/
00070 
00071 #ifndef SC_UNSIGNED_H
00072 #define SC_UNSIGNED_H
00073 
00074 
00075 #include "sysc/kernel/sc_object.h"
00076 #include "sysc/datatypes/misc/sc_value_base.h"
00077 #include "sysc/utils/sc_iostream.h"
00078 #include "sysc/utils/sc_temporary.h"
00079 #include "sysc/datatypes/int/sc_length_param.h"
00080 #include "sysc/datatypes/int/sc_nbdefs.h"
00081 #include "sysc/datatypes/int/sc_nbutils.h"
00082 #include "sysc/datatypes/int/sc_nbexterns.h"
00083 #include "sysc/utils/sc_temporary.h"
00084 
00085 
00086 namespace sc_dt
00087 {
00088 
00089 // classes defined in this module
00090 class sc_unsigned_bitref_r;
00091 class sc_unsigned_bitref;
00092 class sc_unsigned_subref_r;
00093 class sc_unsigned_subref;
00094 class sc_concatref; 
00095 class sc_unsigned;
00096 
00097 // forward class declarations
00098 class sc_bv_base;
00099 class sc_lv_base;
00100 class sc_int_base;
00101 class sc_uint_base;
00102 class sc_int_subref_r;
00103 class sc_uint_subref_r;
00104 class sc_signed;
00105 class sc_signed_subref_r;
00106 class sc_fxval;
00107 class sc_fxval_fast;
00108 class sc_fxnum;
00109 class sc_fxnum_fast;
00110 
00111 
00112 // ----------------------------------------------------------------------------
00113 //  CLASS : sc_unsigned_bitref_r
00114 //
00115 //  Proxy class for sc_unsigned bit selection (r-value only).
00116 // ----------------------------------------------------------------------------
00117 
00118 class sc_unsigned_bitref_r : public sc_value_base
00119 {
00120     friend class sc_unsigned;
00121 
00122 protected:
00123 
00124     // construction and initialization:
00125 
00126     sc_unsigned_bitref_r()
00127         {}
00128 
00129     void initialize( const sc_unsigned* obj_p, int index_ )
00130         {
00131             m_obj_p = CCAST<sc_unsigned*>( obj_p );
00132             m_index = index_;
00133         }
00134 
00135 public:
00136 
00137     // destructor
00138 
00139     virtual ~sc_unsigned_bitref_r()
00140         {}
00141 
00142     // copy constructor
00143 
00144     sc_unsigned_bitref_r( const sc_unsigned_bitref_r& a )
00145         : m_index( a.m_index ), m_obj_p( a.m_obj_p )
00146         {}
00147 
00148     // capacity
00149 
00150     int length() const
00151         { return 1; }
00152 
00153 
00154     // implicit conversion to bool
00155 
00156     operator uint64 () const;
00157     bool operator ! () const;
00158     bool operator ~ () const;
00159 
00160 
00161     // explicit conversions
00162 
00163     uint64 value() const
00164         { return operator uint64(); }
00165 
00166     bool to_bool() const
00167         { return operator uint64(); }
00168 
00169 
00170     // concatenation support
00171 
00172     virtual int concat_length(bool* xz_present_p) const
00173         { if ( xz_present_p ) *xz_present_p = false; return 1; }
00174     virtual uint64 concat_get_uint64() const 
00175         { return (uint64)operator uint64(); }
00176     virtual bool concat_get_ctrl( unsigned long* dst_p, int low_i ) const 
00177         {
00178             int  bit_mask = 1 << (low_i % BITS_PER_DIGIT);  
00179             int  word_i = low_i / BITS_PER_DIGIT;
00180             dst_p[word_i] &= ~bit_mask;
00181             return false;
00182         }
00183     virtual bool concat_get_data( unsigned long* dst_p, int low_i ) const 
00184         {
00185             int  bit_mask = 1 << (low_i % BITS_PER_DIGIT);  
00186             bool result;        // True if non-zero.
00187             int  word_i = low_i / BITS_PER_DIGIT;
00188             if ( operator uint64() )
00189             {
00190                 dst_p[word_i] |= bit_mask;
00191                 result = true;
00192             }
00193             else
00194             {
00195                 dst_p[word_i] &= ~bit_mask;
00196                 result = false;
00197             }
00198             return result;
00199         }
00200 
00201     // other methods
00202 
00203     void print( ::std::ostream& os = ::std::cout ) const
00204         { os << to_bool(); }
00205 
00206 protected:
00207 
00208     int          m_index;
00209     sc_unsigned* m_obj_p;
00210 
00211 private:
00212 
00213     // disabled
00214     const sc_unsigned_bitref_r& operator = ( const sc_unsigned_bitref_r& );
00215 };
00216 
00217 
00218 
00219 inline
00220 ::std::ostream&
00221 operator << ( ::std::ostream&, const sc_unsigned_bitref_r& );
00222 
00223 
00224 // ----------------------------------------------------------------------------
00225 //  CLASS : sc_unsigned_bitref
00226 //
00227 //  Proxy class for sc_unsigned bit selection (r-value and l-value).
00228 // ----------------------------------------------------------------------------
00229 
00230 class sc_unsigned_bitref
00231     : public sc_unsigned_bitref_r
00232 {
00233     friend class sc_unsigned;
00234     friend class sc_core::sc_vpool<sc_unsigned_bitref>;
00235 
00236 
00237 protected: // construction 
00238 
00239     sc_unsigned_bitref()
00240         {}
00241 
00242 public: 
00243 
00244     // copy constructor
00245 
00246     sc_unsigned_bitref( const sc_unsigned_bitref& a )
00247         : sc_unsigned_bitref_r( a )
00248         {}
00249 
00250 
00251     // assignment operators
00252 
00253     const sc_unsigned_bitref& operator = ( const sc_unsigned_bitref_r& );
00254     const sc_unsigned_bitref& operator = ( const sc_unsigned_bitref& );
00255     const sc_unsigned_bitref& operator = ( bool );
00256 
00257     const sc_unsigned_bitref& operator &= ( bool );
00258     const sc_unsigned_bitref& operator |= ( bool );
00259     const sc_unsigned_bitref& operator ^= ( bool );
00260 
00261     // concatenation methods
00262 
00263     virtual void concat_set(int64 src, int low_i);
00264     virtual void concat_set(const sc_signed& src, int low_i);
00265     virtual void concat_set(const sc_unsigned& src, int low_i);
00266     virtual void concat_set(uint64 src, int low_i);
00267 
00268 
00269     // other methods
00270 
00271     void scan( ::std::istream& is = ::std::cin );
00272 
00273 protected:
00274     static sc_core::sc_vpool<sc_unsigned_bitref> m_pool;
00275 };
00276 
00277 
00278 
00279 inline
00280 ::std::istream&
00281 operator >> ( ::std::istream&, sc_unsigned_bitref& );
00282 
00283 
00284 // ----------------------------------------------------------------------------
00285 //  CLASS : sc_unsigned_subref_r
00286 //
00287 //  Proxy class for sc_unsigned part selection (r-value only).
00288 // ----------------------------------------------------------------------------
00289 
00290 class sc_unsigned_subref_r : public sc_value_base
00291 {
00292     friend class sc_signed;
00293     friend class sc_unsigned;
00294     friend class sc_unsigned_signal;
00295 
00296 protected:
00297 
00298     // constructor
00299 
00300     sc_unsigned_subref_r()
00301         {}
00302 
00303     void initialize( const sc_unsigned* obj_p, int left_, int right_ )
00304         {
00305             m_obj_p = CCAST<sc_unsigned*>( obj_p );
00306             m_left = left_;
00307             m_right = right_;
00308         }
00309   
00310 public:
00311 
00312     // destructor
00313 
00314     virtual ~sc_unsigned_subref_r()
00315         {}
00316 
00317 
00318     // copy constructor
00319 
00320     sc_unsigned_subref_r( const sc_unsigned_subref_r& a )
00321         : m_left( a.m_left ), m_obj_p( a.m_obj_p ), m_right( a.m_right )
00322         {}
00323 
00324 
00325     // capacity
00326 
00327     int length() const
00328         { return m_left >= m_right ? (m_left-m_right+1) : (m_right-m_left+1 ); }
00329 
00330 
00331     // implicit conversion to sc_unsigned
00332 
00333     operator sc_unsigned () const;
00334 
00335 
00336     // explicit conversions
00337 
00338     int           to_int() const;
00339     unsigned int  to_uint() const;
00340     long          to_long() const;
00341     unsigned long to_ulong() const;
00342     int64         to_int64() const;
00343     uint64        to_uint64() const;
00344     double        to_double() const;
00345 
00346 
00347     // explicit conversion to character string
00348 
00349     const std::string to_string( sc_numrep numrep = SC_DEC ) const;
00350     const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
00351 
00352 
00353     // concatenation support
00354 
00355     virtual int concat_length(bool* xz_present_p) const
00356         { 
00357             if ( xz_present_p ) *xz_present_p = false; 
00358             return m_left - m_right + 1; 
00359         }
00360     virtual uint64 concat_get_uint64() const;
00361     virtual bool concat_get_ctrl( unsigned long* dst_p, int low_i ) const;
00362     virtual bool concat_get_data( unsigned long* dst_p, int low_i ) const;
00363 
00364     // reduce methods
00365 
00366     bool and_reduce() const;
00367     bool nand_reduce() const;
00368     bool or_reduce() const;
00369     bool nor_reduce() const;
00370     bool xor_reduce() const ;
00371     bool xnor_reduce() const;
00372 
00373     // other methods
00374 
00375     void print( ::std::ostream& os = ::std::cout ) const
00376         { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
00377 
00378 protected:
00379 
00380     int          m_left;   // Left-most bit in this part selection.
00381     sc_unsigned* m_obj_p;  // Target of this part selection. 
00382     int          m_right;  // Right-most bit in this part selection.
00383 
00384 private:
00385 
00386     // disabled
00387     const sc_unsigned_subref_r& operator = ( const sc_unsigned_subref_r& );
00388 };
00389 
00390 
00391 
00392 inline
00393 ::std::ostream&
00394 operator << ( ::std::ostream&, const sc_unsigned_subref_r& );
00395 
00396 
00397 // ----------------------------------------------------------------------------
00398 //  CLASS : sc_unsigned_subref
00399 //
00400 //  Proxy class for sc_unsigned part selection (r-value and l-value).
00401 // ----------------------------------------------------------------------------
00402 
00403 class sc_unsigned_subref
00404     : public sc_unsigned_subref_r
00405 {
00406     friend class sc_unsigned;
00407     friend class sc_core::sc_vpool<sc_unsigned_subref>;
00408 
00409 
00410     // constructor
00411 
00412 protected:
00413     sc_unsigned_subref()
00414         {}
00415   
00416 public:
00417 
00418     // copy constructor
00419 
00420     sc_unsigned_subref( const sc_unsigned_subref& a )
00421         : sc_unsigned_subref_r( a )
00422         {}
00423 
00424     // assignment operators
00425 
00426     const sc_unsigned_subref& operator = ( const sc_unsigned_subref_r& a );
00427     const sc_unsigned_subref& operator = ( const sc_unsigned_subref& a );
00428     const sc_unsigned_subref& operator = ( const sc_unsigned& a );
00429 
00430     template<class T>
00431     const sc_unsigned_subref& operator = ( const sc_generic_base<T>& a );
00432     const sc_unsigned_subref& operator = ( const sc_signed_subref_r& a );
00433     const sc_unsigned_subref& operator = ( const sc_signed& a );
00434 
00435     const sc_unsigned_subref& operator = ( const char* a );
00436     const sc_unsigned_subref& operator = ( unsigned long a );
00437     const sc_unsigned_subref& operator = ( long a );
00438 
00439     const sc_unsigned_subref& operator = ( unsigned int a )
00440         { return operator = ( (unsigned long) a ); }
00441 
00442     const sc_unsigned_subref& operator = ( int a )
00443         { return operator = ( (long) a ); }
00444 
00445     const sc_unsigned_subref& operator = ( uint64 a );
00446     const sc_unsigned_subref& operator = ( int64 a );
00447     const sc_unsigned_subref& operator = ( double a );  
00448     const sc_unsigned_subref& operator = ( const sc_int_base& a );
00449     const sc_unsigned_subref& operator = ( const sc_uint_base& a );
00450 
00451     // concatenation methods
00452 
00453     virtual void concat_set(int64 src, int low_i);
00454     virtual void concat_set(const sc_signed& src, int low_i);
00455     virtual void concat_set(const sc_unsigned& src, int low_i);
00456     virtual void concat_set(uint64 src, int low_i);
00457 
00458     // other methods
00459 
00460     void scan( ::std::istream& is = ::std::cin );
00461 
00462 protected:
00463     static sc_core::sc_vpool<sc_unsigned_subref> m_pool;
00464 };
00465 
00466 
00467 
00468 inline
00469 ::std::istream&
00470 operator >> ( ::std::istream&, sc_unsigned_subref& );
00471 
00472 
00473 // ----------------------------------------------------------------------------
00474 //  CLASS : sc_unsigned
00475 //
00476 //  Arbitrary precision unsigned number.
00477 // ----------------------------------------------------------------------------
00478 
00479 class sc_unsigned : public sc_value_base
00480 {
00481     friend class sc_concatref;
00482     friend class sc_unsigned_bitref_r;
00483     friend class sc_unsigned_bitref;
00484     friend class sc_unsigned_subref_r;
00485     friend class sc_unsigned_subref;
00486     friend class sc_signed;
00487     friend class sc_signed_subref;
00488     friend class sc_signed_subref_r;
00489 
00490   // Needed for types using sc_unsigned.
00491   typedef bool elemtype;
00492 
00493 public:
00494 
00495     // constructors
00496 
00497     explicit sc_unsigned( int nb = sc_length_param().len() );
00498     sc_unsigned( const sc_unsigned& v );
00499     sc_unsigned( const sc_signed&   v );
00500         template<class T>
00501     explicit sc_unsigned( const sc_generic_base<T>& v );
00502     explicit sc_unsigned( const sc_bv_base& v );
00503     explicit sc_unsigned( const sc_lv_base& v );
00504     explicit sc_unsigned( const sc_int_subref_r& v );
00505     explicit sc_unsigned( const sc_uint_subref_r& v );
00506     explicit sc_unsigned( const sc_signed_subref_r& v );
00507     explicit sc_unsigned( const sc_unsigned_subref_r& v );
00508 
00509 
00510 
00511     // assignment operators
00512 
00513     const sc_unsigned& operator = (const sc_unsigned&        v);
00514     const sc_unsigned& operator = (const sc_unsigned_subref_r& a );
00515 
00516     template<class T>
00517     const sc_unsigned& operator = ( const sc_generic_base<T>& a )
00518         { a->to_sc_unsigned(*this); return *this; }
00519 
00520     const sc_unsigned& operator = (const sc_signed&          v);
00521     const sc_unsigned& operator = (const sc_signed_subref_r& a );
00522 
00523     const sc_unsigned& operator = ( const char*               v);
00524     const sc_unsigned& operator = ( int64                     v);
00525     const sc_unsigned& operator = ( uint64                    v);
00526     const sc_unsigned& operator = ( long                      v);
00527     const sc_unsigned& operator = ( unsigned long             v);
00528 
00529     const sc_unsigned& operator = ( int                       v) 
00530         { return operator=((long) v); }
00531 
00532     const sc_unsigned& operator = ( unsigned int              v) 
00533         { return operator=((unsigned long) v); }
00534 
00535     const sc_unsigned& operator = ( double                    v);
00536     const sc_unsigned& operator = ( const sc_int_base&        v);
00537     const sc_unsigned& operator = ( const sc_uint_base&       v);
00538 
00539     const sc_unsigned& operator = ( const sc_bv_base& );
00540     const sc_unsigned& operator = ( const sc_lv_base& );
00541 
00542 #ifdef SC_INCLUDE_FX
00543     const sc_unsigned& operator = ( const sc_fxval& );
00544     const sc_unsigned& operator = ( const sc_fxval_fast& );
00545     const sc_unsigned& operator = ( const sc_fxnum& );
00546     const sc_unsigned& operator = ( const sc_fxnum_fast& );
00547 #endif
00548 
00549 
00550     // destructor
00551 
00552     virtual ~sc_unsigned()
00553         {
00554 #           ifndef SC_MAX_NBITS
00555                 delete [] digit;
00556 #           endif
00557         }
00558 
00559     // Concatenation support:
00560 
00561         unsigned long* get_raw() const { return digit; }
00562     virtual int concat_length(bool* xz_present_p) const
00563        { if ( xz_present_p ) *xz_present_p = false; return nbits-1; }
00564     virtual bool concat_get_ctrl( unsigned long* dst_p, int low_i ) const;
00565     virtual bool concat_get_data( unsigned long* dst_p, int low_i ) const;
00566     virtual uint64 concat_get_uint64() const;
00567     virtual void concat_set(int64 src, int low_i);
00568     virtual void concat_set(const sc_signed& src, int low_i);
00569     virtual void concat_set(const sc_unsigned& src, int low_i);
00570     virtual void concat_set(uint64 src, int low_i);
00571 
00572     // Increment operators.
00573 
00574     sc_unsigned& operator ++ ();
00575     const sc_unsigned operator ++ (int);
00576 
00577     // Decrement operators.
00578 
00579     sc_unsigned& operator -- ();
00580     const sc_unsigned operator -- (int);
00581 
00582 
00583     // bit selection
00584 
00585     inline void check_index( int i ) const
00586         { /*if ( (i < 0) || (i >= nbits-1) ) invalid_index(i);*/ }
00587 
00588     void invalid_index( int i ) const;
00589 
00590     sc_unsigned_bitref& operator [] ( int i )
00591         {
00592             check_index(i);
00593             sc_unsigned_bitref* result_p = 
00594                 sc_unsigned_bitref::m_pool.allocate();
00595             result_p->initialize( this, i );
00596             return *result_p;
00597         }
00598 
00599     const sc_unsigned_bitref_r& operator [] ( int i ) const
00600         {
00601             check_index(i);
00602             sc_unsigned_bitref* result_p = 
00603                 sc_unsigned_bitref::m_pool.allocate();
00604             result_p->initialize( this, i );
00605             return *result_p;
00606         }
00607 
00608     sc_unsigned_bitref& bit( int i )
00609         {
00610             check_index(i);
00611             sc_unsigned_bitref* result_p = 
00612                 sc_unsigned_bitref::m_pool.allocate();
00613             result_p->initialize( this, i );
00614             return *result_p;
00615         }
00616 
00617     const sc_unsigned_bitref_r& bit( int i ) const
00618         {
00619             check_index(i);
00620             sc_unsigned_bitref* result_p = 
00621                 sc_unsigned_bitref::m_pool.allocate();
00622             result_p->initialize( this, i );
00623             return *result_p;
00624         }
00625 
00626 
00627     // part selection
00628 
00629     // Subref operators. Help access the range of bits from the ith to
00630     // jth. These indices have arbitrary precedence with respect to each
00631     // other, i.e., we can have i <= j or i > j. Note the equivalence
00632     // between range(i, j) and operator (i, j). Also note that
00633     // operator (i, i) returns an unsigned number that corresponds to the
00634     // bit operator [i], so these two forms are not the same.
00635 
00636     inline void check_range( int l, int r ) const
00637         {
00638 #if 0
00639             if ( l < r )
00640             {
00641                 if ( (l < 0) || (r >= nbits-1) ) invalid_range(l,r);
00642             }
00643             else
00644             {
00645                 if ( (r < 0) || (l >= nbits-1) ) invalid_range(l,r);
00646             }
00647 #endif // 0
00648         }
00649 
00650     void invalid_range( int l, int r ) const;
00651 
00652     sc_unsigned_subref& range( int i, int j )
00653         {
00654             check_range(i,j);
00655             sc_unsigned_subref* result_p = 
00656                 sc_unsigned_subref::m_pool.allocate();
00657             result_p->initialize( this, i, j );
00658             return *result_p;
00659         }
00660 
00661     const sc_unsigned_subref_r& range( int i, int j ) const
00662         {
00663             check_range(i,j);
00664             sc_unsigned_subref* result_p = 
00665                 sc_unsigned_subref::m_pool.allocate();
00666             result_p->initialize( this, i, j );
00667             return *result_p;
00668         }
00669 
00670     sc_unsigned_subref& operator () ( int i, int j )
00671         {
00672             check_range(i,j);
00673             sc_unsigned_subref* result_p = 
00674                 sc_unsigned_subref::m_pool.allocate();
00675             result_p->initialize( this, i, j );
00676             return *result_p;
00677         }
00678 
00679     const sc_unsigned_subref_r& operator () ( int i, int j ) const
00680         {
00681             check_range(i,j);
00682             sc_unsigned_subref* result_p = 
00683                 sc_unsigned_subref::m_pool.allocate();
00684             result_p->initialize( this, i, j );
00685             return *result_p;
00686         }
00687 
00688     // explicit conversions
00689 
00690     int           to_int() const;
00691     unsigned int  to_uint() const;
00692     long          to_long() const;
00693     unsigned long to_ulong() const;
00694     int64         to_int64() const;
00695     uint64        to_uint64() const;
00696     double        to_double() const;
00697 
00698 #ifdef SC_DT_DEPRECATED
00699     int to_signed() const
00700         { return to_int(); }
00701 
00702     unsigned int to_unsigned() const
00703         { return to_uint(); }
00704 #endif
00705 
00706     // explicit conversion to character string
00707 
00708     const std::string to_string( sc_numrep numrep = SC_DEC ) const;
00709     const std::string to_string( sc_numrep numrep, bool w_prefix ) const;
00710 
00711     // Print functions. dump prints the internals of the class.
00712 
00713     void print( ::std::ostream& os = ::std::cout ) const
00714         { os << to_string(sc_io_base(os,SC_DEC),sc_io_show_base(os)); }
00715 
00716     void scan( ::std::istream& is = ::std::cin );
00717 
00718     void dump( ::std::ostream& os = ::std::cout ) const;
00719 
00720 
00721   // Functions to find various properties.    
00722   int  length() const { return nbits - 1; }  // Bit width.
00723   bool iszero() const;                       // Is the number zero?
00724   bool sign() const { return 0; }            // Sign.
00725 
00726     // reduce methods
00727 
00728     bool and_reduce() const;
00729 
00730     bool nand_reduce() const
00731         { return ( ! and_reduce() ); }
00732 
00733     bool or_reduce() const;
00734 
00735     bool nor_reduce() const
00736         { return ( ! or_reduce() ); }
00737 
00738     bool xor_reduce() const;
00739 
00740     bool xnor_reduce() const  
00741         { return ( ! xor_reduce() ); }
00742 
00743 
00744   // Functions to access individual bits.  
00745   bool test(int i) const;      // Is the ith bit 0 or 1?
00746   void set(int i);             // Set the ith bit to 1.
00747   void clear(int i);           // Set the ith bit to 0.
00748   void set(int i, bool v)      // Set the ith bit to v.
00749     { if (v) set(i); else clear(i);  }
00750   void invert(int i)           // Negate the ith bit.
00751     { if (test(i)) clear(i); else set(i);  }
00752 
00753   // Make the number equal to its mirror image.
00754   void reverse();
00755 
00756   // Get/set a packed bit representation of the number.
00757   void get_packed_rep(unsigned long *buf) const;
00758   void set_packed_rep(unsigned long *buf);
00759 
00760   /*
00761     The comparison of the old and new semantics are as follows:
00762 
00763     Let s = sc_signed, 
00764         u = sc_unsigned,
00765         un = { uint64, unsigned long, unsigned int },
00766         sn = { int64, long, int, char* }, and
00767         OP = { +, -, *, /, % }.
00768 
00769     Old semantics:                     New semantics:
00770       u OP u -> u                        u OP u -> u
00771       s OP u -> u                        s OP u -> s
00772       u OP s -> u                        u OP s -> s
00773       s OP s -> s                        s OP s -> s
00774 
00775       u OP un = un OP u -> u             u OP un = un OP u -> u
00776       u OP sn = sn OP u -> u             u OP sn = sn OP u -> s
00777 
00778       s OP un = un OP s -> s             s OP un = un OP s -> s
00779       s OP sn = sn OP s -> s             s OP sn = sn OP s -> s
00780 
00781     In the new semantics, the result is u if both operands are u; the
00782     result is s otherwise. The only exception is subtraction. The result
00783     of a subtraction is always s.
00784 
00785     The old semantics is like C/C++ semantics on integer types; the
00786     new semantics is due to the VSIA C/C++ data types standard.  
00787    */
00788 
00789   // ARITHMETIC OPERATORS:
00790 
00791   // ADDition operators:
00792    
00793   friend   sc_signed operator + (const sc_unsigned&  u, const sc_signed&    v); 
00794   friend   sc_signed operator + (const sc_signed&    u, const sc_unsigned&  v); 
00795 
00796   friend sc_unsigned operator + (const sc_unsigned&  u, const sc_unsigned&  v);
00797   friend   sc_signed operator + (const sc_unsigned&  u, int64               v); 
00798   friend sc_unsigned operator + (const sc_unsigned&  u, uint64              v); 
00799   friend   sc_signed operator + (const sc_unsigned&  u, long                v); 
00800   friend sc_unsigned operator + (const sc_unsigned&  u, unsigned long       v);
00801   friend   sc_signed operator + (const sc_unsigned&  u, int                 v);
00802   friend sc_unsigned operator + (const sc_unsigned&  u, unsigned int        v) 
00803     { return operator+(u, (unsigned long) v); }
00804 
00805   friend   sc_signed operator + (int64               u, const sc_unsigned&  v); 
00806   friend sc_unsigned operator + (uint64              u, const sc_unsigned&  v); 
00807   friend   sc_signed operator + (long                u, const sc_unsigned&  v); 
00808   friend sc_unsigned operator + (unsigned long       u, const sc_unsigned&  v);
00809   friend   sc_signed operator + (int                 u, const sc_unsigned&  v);
00810   friend sc_unsigned operator + (unsigned int        u, const sc_unsigned&  v)  
00811     { return operator+((unsigned long) u,  v); } 
00812 
00813   const sc_unsigned& operator += (const sc_signed&    v); 
00814   const sc_unsigned& operator += (const sc_unsigned&  v); 
00815   const sc_unsigned& operator += (int64               v); 
00816   const sc_unsigned& operator += (uint64              v); 
00817   const sc_unsigned& operator += (long                v); 
00818   const sc_unsigned& operator += (unsigned long       v); 
00819   const sc_unsigned& operator += (int                 v) 
00820     { return operator+=((long) v); }
00821   const sc_unsigned& operator += (unsigned int        v) 
00822     { return operator+=((unsigned long) v); }
00823 
00824   friend sc_unsigned operator + (const sc_unsigned&  u, const sc_uint_base& v);
00825   friend   sc_signed operator + (const sc_unsigned&  u, const sc_int_base&  v);
00826   friend sc_unsigned operator + (const sc_uint_base& u, const sc_unsigned&  v);
00827   friend   sc_signed operator + (const sc_int_base&  u, const sc_unsigned&  v);
00828   const sc_unsigned& operator += (const sc_int_base&  v);
00829   const sc_unsigned& operator += (const sc_uint_base& v);
00830 
00831   // SUBtraction operators:
00832    
00833   friend   sc_signed operator - (const