sc_nbcommon.inc

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.3 (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_nbcommon.cpp -- Functions common to both sc_signed and sc_unsigned.
00021                      This file is included in sc_signed.cpp and
00022                      sc_unsigned.cpp after the macros are defined accordingly.
00023                      For example, sc_signed.cpp will first define CLASS_TYPE
00024                      as sc_signed before including this file. This file like
00025                      sc_nbfriends.cpp and sc_nbexterns.cpp is created in order
00026                      to ensure only one version of each function, regardless
00027                      of the class that they interface to.
00028  
00029   Original Author: Ali Dasdan, Synopsys, Inc.
00030   
00031  *****************************************************************************/
00032 
00033 /*****************************************************************************
00034 
00035   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00036   changes you are making here.
00037 
00038       Name, Affiliation, Date:
00039   Description of Modification:
00040 
00041  *****************************************************************************/
00042 
00043 
00044 // ----------------------------------------------------------------------------
00045 //  SECTION : Public members
00046 // ----------------------------------------------------------------------------
00047 
00048 // Create a CLASS_TYPE number with nb bits.
00049 CLASS_TYPE::CLASS_TYPE( int nb )
00050 {
00051     sgn = default_sign();
00052     if( nb > 0 ) {
00053     nbits = num_bits( nb );
00054     } else {
00055     char msg[BUFSIZ];
00056     std::sprintf( msg, "%s::%s( int nb ) : nb = %d is not valid",
00057          CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
00058     SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
00059     }
00060     ndigits = DIV_CEIL(nbits);
00061 #ifdef SC_MAX_NBITS
00062     test_bound(nb);
00063 #else
00064     digit = new sc_digit[ndigits];
00065 #endif
00066     makezero();
00067 }
00068 
00069 
00070 // Create a copy of v with sgn s. v is of the same type.
00071 CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE& v)
00072 {
00073   sgn = v.sgn;
00074   nbits = v.nbits;
00075   ndigits = v.ndigits;
00076 
00077 #ifndef SC_MAX_NBITS
00078   digit = new sc_digit[ndigits];
00079 #endif
00080 
00081   vec_copy(ndigits, digit, v.digit);
00082 }
00083 
00084 
00085 // Create a copy of v where v is of the different type.
00086 CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE& v)
00087 {
00088   sgn = v.sgn;
00089   nbits = num_bits(v.nbits);
00090 
00091 #if (IF_SC_SIGNED == 1)
00092   ndigits = v.ndigits;
00093 #else
00094   ndigits = DIV_CEIL(nbits);
00095 #endif
00096 
00097 #ifndef SC_MAX_NBITS
00098   digit = new sc_digit[ndigits];
00099 #endif
00100 
00101   copy_digits(v.nbits, v.ndigits, v.digit);
00102 }
00103 
00104 // Create a copy of v where v is an sign-less instance.
00105 CLASS_TYPE::CLASS_TYPE(const sc_bv_base& v) 
00106 {
00107     int nb = v.length();
00108     sgn = default_sign();
00109     if( nb > 0 ) {
00110         nbits = num_bits( nb );
00111     } else {
00112         char msg[BUFSIZ];
00113         std::sprintf( msg, "%s::%s( sc_bv_base ) : nb = %d is not valid",
00114                  CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
00115         SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
00116     }
00117     ndigits = DIV_CEIL(nbits);
00118 #   ifdef SC_MAX_NBITS
00119         test_bound(nb);
00120 #    else
00121         digit = new sc_digit[ndigits];
00122 #    endif
00123     makezero();
00124     *this = v;
00125 }
00126 
00127 CLASS_TYPE::CLASS_TYPE(const sc_lv_base& v) 
00128 {
00129     int nb = v.length();
00130     sgn = default_sign();
00131     if( nb > 0 ) {
00132         nbits = num_bits( nb );
00133     } else {
00134         char msg[BUFSIZ];
00135         std::sprintf( msg, "%s::%s( sc_lv_base ) : nb = %d is not valid",
00136                  CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
00137         SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
00138     }
00139     ndigits = DIV_CEIL(nbits);
00140 #   ifdef SC_MAX_NBITS
00141         test_bound(nb);
00142 #    else
00143         digit = new sc_digit[ndigits];
00144 #    endif
00145     makezero();
00146     *this = v;
00147 }
00148 
00149 CLASS_TYPE::CLASS_TYPE(const sc_int_subref_r& v) 
00150 {
00151     int nb = v.length();
00152     sgn = default_sign();
00153     if( nb > 0 ) {
00154         nbits = num_bits( nb );
00155     } else {
00156         char msg[BUFSIZ];
00157         std::sprintf( msg, "%s::%s( sc_int_subref ) : nb = %d is not valid",
00158                  CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
00159         SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
00160     }
00161     ndigits = DIV_CEIL(nbits);
00162 #   ifdef SC_MAX_NBITS
00163         test_bound(nb);
00164 #    else
00165         digit = new sc_digit[ndigits];
00166 #    endif
00167     makezero();
00168     *this = v.to_uint64();
00169 }
00170 
00171 CLASS_TYPE::CLASS_TYPE(const sc_uint_subref_r& v) 
00172 {
00173     int nb = v.length();
00174     sgn = default_sign();
00175     if( nb > 0 ) {
00176         nbits = num_bits( nb );
00177     } else {
00178         char msg[BUFSIZ];
00179         std::sprintf( msg, "%s::%s( sc_uint_subref ) : nb = %d is not valid",
00180                  CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
00181         SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
00182     }
00183     ndigits = DIV_CEIL(nbits);
00184 #   ifdef SC_MAX_NBITS
00185         test_bound(nb);
00186 #    else
00187         digit = new sc_digit[ndigits];
00188 #    endif
00189     makezero();
00190     *this = v.to_uint64();
00191 }
00192 
00193 CLASS_TYPE::CLASS_TYPE(const sc_signed_subref_r& v) 
00194 {
00195     int nb = v.length();
00196     sgn = default_sign();
00197     if( nb > 0 ) {
00198         nbits = num_bits( nb );
00199     } else {
00200         char msg[BUFSIZ];
00201         std::sprintf( msg, "%s::%s( sc_signed_subref ) : nb = %d is not valid",
00202                  CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
00203         SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
00204     }
00205     ndigits = DIV_CEIL(nbits);
00206 #   ifdef SC_MAX_NBITS
00207         test_bound(nb);
00208 #    else
00209         digit = new sc_digit[ndigits];
00210 #    endif
00211     makezero();
00212     *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right);
00213 }
00214 
00215 CLASS_TYPE::CLASS_TYPE(const sc_unsigned_subref_r& v) 
00216 {
00217     int nb = v.length();
00218     sgn = default_sign();
00219     if( nb > 0 ) {
00220         nbits = num_bits( nb );
00221     } else {
00222         char msg[BUFSIZ];
00223         std::sprintf( msg, "%s::%s( sc_unsigned_subref ) : nb = %d is not valid",
00224                  CLASS_TYPE_STR, CLASS_TYPE_STR, nb );
00225         SC_REPORT_ERROR( sc_core::SC_ID_INIT_FAILED_, msg );
00226     }
00227     ndigits = DIV_CEIL(nbits);
00228 #   ifdef SC_MAX_NBITS
00229         test_bound(nb);
00230 #    else
00231         digit = new sc_digit[ndigits];
00232 #    endif
00233     makezero();
00234     *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right);
00235 }
00236 
00237 // ----------------------------------------------------------------------------
00238 //  SECTION: Public members - Concatenation support.
00239 // ----------------------------------------------------------------------------
00240 
00241 
00242 // ----------------------------------------------------------------------------
00243 //  SECTION: Public members - Assignment operators.
00244 // ----------------------------------------------------------------------------
00245 
00246 // Assignment from v of the same type.
00247 const CLASS_TYPE&
00248 CLASS_TYPE::operator=(const CLASS_TYPE& v)
00249 {
00250   if (this != &v) {
00251 
00252     sgn = v.sgn;
00253 
00254     if (sgn == SC_ZERO)
00255       vec_zero(ndigits, digit);
00256 
00257     else
00258       copy_digits(v.nbits, v.ndigits, v.digit);
00259 
00260   }
00261 
00262   return *this;
00263 }
00264 
00265 
00266 // Assignment from v of the different type.
00267 const CLASS_TYPE&
00268 CLASS_TYPE::operator=(const OTHER_CLASS_TYPE& v)
00269 {
00270   sgn = v.sgn;
00271 
00272   if (sgn == SC_ZERO)
00273     vec_zero(ndigits, digit);
00274 
00275   else
00276     copy_digits(v.nbits, v.ndigits, v.digit);
00277     
00278   return *this;
00279 }
00280 
00281 
00282 // Assignment from an sc_unsigned_subref_r
00283 const CLASS_TYPE& 
00284 CLASS_TYPE::operator=(const sc_unsigned_subref_r& v)
00285 {
00286   return operator=(sc_unsigned(v));
00287 }
00288 
00289 
00290 // Assignment from an sc_signed_subref_r
00291 const CLASS_TYPE& 
00292 CLASS_TYPE::operator=(const sc_signed_subref_r& v)
00293 {
00294   return operator=(sc_unsigned(v));
00295 }
00296 
00297 
00298 // ----------------------------------------------------------------------------
00299 //  SECTION: Input and output operators
00300 // ----------------------------------------------------------------------------
00301 
00302 void
00303 CLASS_TYPE::scan( ::std::istream& is )
00304 {
00305     std::string s;
00306     is >> s;
00307     *this = s.c_str();
00308 }
00309 
00310 
00311 // ----------------------------------------------------------------------------
00312 //  SECTION: PLUS operators: +, +=, ++
00313 // ----------------------------------------------------------------------------
00314 
00315 // Cases to consider when computing u + v:
00316 // 1. 0 + v = v
00317 // 2. u + 0 = u
00318 // 3. if sgn(u) == sgn(v)
00319 //    3.1 u + v = +(u + v) = sgn(u) * (u + v) 
00320 //    3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v)
00321 // 4. if sgn(u) != sgn(v)
00322 //    4.1 u + (-v) = u - v = sgn(u) * (u - v)
00323 //    4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v)
00324 //
00325 // Specialization of above cases for computing ++u or u++: 
00326 // 1. 0 + 1 = 1
00327 // 3. u + 1 = u + 1 = sgn(u) * (u + 1)
00328 // 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1)
00329 
00330 const CLASS_TYPE&
00331 CLASS_TYPE::operator+=(const CLASS_TYPE& v)
00332 {
00333   // u = *this
00334 
00335   if (sgn == SC_ZERO) // case 1
00336     return (*this = v);
00337 
00338   if (v.sgn == SC_ZERO) // case 2
00339     return *this;
00340 
00341   // cases 3 and 4
00342   add_on_help(sgn, nbits, ndigits, digit,
00343               v.sgn, v.nbits, v.ndigits, v.digit);
00344 
00345   convert_SM_to_2C_to_SM();
00346 
00347   return *this; 
00348 }
00349 
00350 
00351 const CLASS_TYPE&
00352 CLASS_TYPE::operator+=(const OTHER_CLASS_TYPE& v)
00353 {
00354   // u = *this
00355 
00356   if (sgn == SC_ZERO) // case 1
00357     return (*this = v);
00358 
00359   if (v.sgn == SC_ZERO) // case 2
00360     return *this;
00361 
00362   // cases 3 and 4
00363   add_on_help(sgn, nbits, ndigits, digit,
00364               v.sgn, v.nbits, v.ndigits, v.digit);
00365 
00366   convert_SM_to_2C_to_SM();
00367 
00368   return *this; 
00369 }
00370 
00371 
00372 CLASS_TYPE&
00373 CLASS_TYPE::operator++() // prefix
00374 {
00375   // u = *this
00376 
00377   if (sgn == SC_ZERO) { // case 1
00378     digit[0] = 1;
00379     sgn = SC_POS;
00380   }
00381 
00382   else if (sgn == SC_POS)   // case 3
00383     vec_add_small_on(ndigits, digit, 1);
00384 
00385   else // case 4
00386     vec_sub_small_on(ndigits, digit, 1);
00387 
00388   sgn = convert_signed_SM_to_2C_to_SM(sgn, nbits, ndigits, digit);
00389 
00390   return *this;   
00391 }
00392 
00393 
00394 const CLASS_TYPE
00395 CLASS_TYPE::operator++(int) // postfix
00396 {
00397   // Copy digit into d.
00398 
00399 #ifdef SC_MAX_NBITS
00400   sc_digit d[MAX_NDIGITS];
00401 #else
00402   sc_digit *d = new sc_digit[ndigits];
00403 #endif
00404 
00405   small_type s = sgn;
00406 
00407   vec_copy(ndigits, d, digit);
00408 
00409   ++(*this);
00410 
00411   return CLASS_TYPE(s, nbits, ndigits, d);
00412 }
00413 
00414 
00415 const CLASS_TYPE&
00416 CLASS_TYPE::operator+=(int64 v)
00417 {
00418   // u = *this
00419 
00420   if (sgn == SC_ZERO)  // case 1
00421     return (*this = v);
00422 
00423   if (v == 0) // case 2
00424     return *this;
00425 
00426   CONVERT_INT64(v);
00427 
00428   // cases 3 and 4
00429   add_on_help(sgn, nbits, ndigits, digit,
00430               vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00431 
00432   convert_SM_to_2C_to_SM();
00433 
00434   return *this;
00435 }
00436 
00437 
00438 const CLASS_TYPE&
00439 CLASS_TYPE::operator+=(uint64 v)
00440 {
00441   // u = *this
00442 
00443   if (sgn == SC_ZERO)  // case 1
00444     return (*this = v);
00445 
00446   if (v == 0)  // case 2
00447     return *this;
00448 
00449   CONVERT_INT64(v);
00450 
00451   // cases 3 and 4
00452   add_on_help(sgn, nbits, ndigits, digit,
00453               vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00454 
00455   convert_SM_to_2C_to_SM();
00456 
00457   return *this;
00458 }
00459 
00460 
00461 const CLASS_TYPE&
00462 CLASS_TYPE::operator+=(long v)
00463 {
00464   // u = *this
00465 
00466   if (sgn == SC_ZERO)  // case 1
00467     return (*this = v);
00468 
00469   if (v == 0) // case 2
00470     return *this;
00471 
00472   CONVERT_LONG(v);
00473 
00474   // cases 3 and 4
00475   add_on_help(sgn, nbits, ndigits, digit,
00476               vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
00477 
00478   convert_SM_to_2C_to_SM();
00479 
00480   return *this;
00481 }
00482 
00483 
00484 const CLASS_TYPE&
00485 CLASS_TYPE::operator+=(unsigned long v)
00486 {
00487   // u = *this
00488 
00489   if (sgn == SC_ZERO)  // case 1
00490     return (*this = v);
00491 
00492   if (v == 0)  // case 2
00493     return *this;
00494 
00495   CONVERT_LONG(v);
00496 
00497   // cases 3 and 4
00498   add_on_help(sgn, nbits, ndigits, digit,
00499               vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
00500 
00501   convert_SM_to_2C_to_SM();
00502 
00503   return *this;
00504 }
00505 
00506 
00507 // ----------------------------------------------------------------------------
00508 //  SECTION: MINUS operators: -, -=, --
00509 // ----------------------------------------------------------------------------
00510 
00511 // Cases to consider when computing u + v:
00512 // 1. u - 0 = u 
00513 // 2. 0 - v = -v
00514 // 3. if sgn(u) != sgn(v)
00515 //    3.1 u - (-v) = u + v = sgn(u) * (u + v)
00516 //    3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)
00517 // 4. if sgn(u) == sgn(v)
00518 //    4.1 u - v = +(u - v) = sgn(u) * (u - v) 
00519 //    4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)
00520 //
00521 // Specialization of above cases for computing --u or u--: 
00522 // 1. 0 - 1 = -1
00523 // 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)
00524 // 4. u - 1 = u - 1 = sgn(u) * (u - 1)
00525 
00526 const CLASS_TYPE&
00527 CLASS_TYPE::operator-=(const CLASS_TYPE& v)
00528 {
00529   // u = *this
00530 
00531   if (v.sgn == SC_ZERO)  // case 1
00532     return *this;
00533 
00534   if (sgn == SC_ZERO) { // case 2
00535 
00536     sgn = -v.sgn;
00537     copy_digits(v.nbits, v.ndigits, v.digit);   
00538 
00539   }
00540   else {
00541     
00542     // cases 3 and 4
00543     add_on_help(sgn, nbits, ndigits, digit, 
00544                 -v.sgn, v.nbits, v.ndigits, v.digit);
00545 
00546     convert_SM_to_2C_to_SM();
00547 
00548   }
00549 
00550   return *this;
00551 }
00552 
00553 
00554 const CLASS_TYPE&
00555 CLASS_TYPE::operator-=(const OTHER_CLASS_TYPE& v)
00556 {
00557   // u = *this
00558 
00559   if (v.sgn == SC_ZERO)  // case 1
00560     return *this;
00561 
00562   if (sgn == SC_ZERO) { // case 2
00563 
00564     sgn = -v.sgn;
00565     copy_digits(v.nbits, v.ndigits, v.digit);   
00566 
00567   }
00568   else {
00569 
00570     // cases 3 and 4
00571     add_on_help(sgn, nbits, ndigits, digit, 
00572                 -v.sgn, v.nbits, v.ndigits, v.digit);
00573 
00574     convert_SM_to_2C_to_SM();
00575     
00576   }
00577   
00578   return *this;
00579 }
00580 
00581 
00582 CLASS_TYPE&
00583 CLASS_TYPE::operator--() // prefix
00584 {
00585   if (sgn == SC_ZERO) { // case 1
00586     digit[0] = 1;
00587     sgn = SC_NEG;
00588   }
00589 
00590   else if (sgn == SC_POS)   // case 3
00591     vec_sub_small_on(ndigits, digit, 1);
00592 
00593   else // case 4
00594     vec_add_small_on(ndigits, digit, 1);
00595 
00596   sgn = convert_signed_SM_to_2C_to_SM(sgn, nbits, ndigits, digit);
00597 
00598   return *this;   
00599 }
00600 
00601 
00602 const CLASS_TYPE
00603 CLASS_TYPE::operator--(int) // postfix
00604 {
00605   // Copy digit into d.
00606 
00607 #ifdef SC_MAX_NBITS
00608   sc_digit d[MAX_NDIGITS];
00609 #else
00610   sc_digit *d = new sc_digit[ndigits];
00611 #endif
00612 
00613   small_type s = sgn;
00614 
00615   vec_copy(ndigits, d, digit);
00616 
00617   --(*this);
00618 
00619   return CLASS_TYPE(s, nbits, ndigits, d);
00620 }
00621 
00622 
00623 const CLASS_TYPE&
00624 CLASS_TYPE::operator-=(int64 v)
00625 {
00626   // u = *this
00627 
00628   if (v == 0) // case 1
00629     return *this;
00630 
00631   if (sgn == SC_ZERO) // case 2
00632     return (*this = -v);
00633 
00634   CONVERT_INT64(v);
00635 
00636   // cases 3 and 4
00637   add_on_help(sgn, nbits, ndigits, digit,
00638               -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00639 
00640   convert_SM_to_2C_to_SM();
00641 
00642   return *this;
00643 }
00644 
00645 
00646 const CLASS_TYPE&
00647 CLASS_TYPE::operator-=(uint64 v)
00648 {
00649   // u = *this
00650 
00651   if (v == 0) // case 1
00652     return *this;
00653 
00654   int64 v2 = (int64) v;
00655 
00656   if (sgn == SC_ZERO) // case 2
00657     return (*this = -v2);
00658 
00659   CONVERT_INT64(v);
00660 
00661   // cases 3 and 4
00662   add_on_help(sgn, nbits, ndigits, digit,
00663               -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00664 
00665   convert_SM_to_2C_to_SM();
00666 
00667   return *this;
00668 }
00669 
00670 
00671 const CLASS_TYPE&
00672 CLASS_TYPE::operator-=(long v)
00673 {
00674   // u = *this
00675 
00676   if (v == 0) // case 1
00677     return *this;
00678 
00679   if (sgn == SC_ZERO) // case 2
00680     return (*this = -v);
00681 
00682   CONVERT_LONG(v);
00683 
00684   // cases 3 and 4
00685   add_on_help(sgn, nbits, ndigits, digit,
00686               -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
00687 
00688   convert_SM_to_2C_to_SM();
00689 
00690   return *this;
00691 }
00692 
00693 
00694 const CLASS_TYPE&
00695 CLASS_TYPE::operator-=(unsigned long v)
00696 {
00697   // u = *this
00698 
00699   if (v == 0) // case 1
00700     return *this;
00701 
00702   long v2 = (long) v;
00703 
00704   if (sgn == SC_ZERO) // case 2
00705     return (*this = -v2);
00706 
00707   CONVERT_LONG(v);
00708 
00709   // cases 3 and 4
00710   add_on_help(sgn, nbits, ndigits, digit,
00711               -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
00712 
00713   convert_SM_to_2C_to_SM();
00714 
00715   return *this;
00716 }
00717 
00718 
00719 // ----------------------------------------------------------------------------
00720 //  SECTION: MULTIPLICATION operators: *, *=
00721 // ----------------------------------------------------------------------------
00722 
00723 // Cases to consider when computing u * v:
00724 // 1. u * 0 = 0 * v = 0
00725 // 2. 1 * v = v and -1 * v = -v
00726 // 3. u * 1 = u and u * -1 = -u
00727 // 4. u * v = u * v
00728 
00729 const CLASS_TYPE&
00730 CLASS_TYPE::operator*=(const CLASS_TYPE& v)
00731 {
00732   // u = *this
00733 
00734   sgn = mul_signs(sgn, v.sgn);
00735 
00736   if (sgn == SC_ZERO) // case 1
00737     vec_zero(ndigits, digit);
00738 
00739   else
00740     // cases 2-4
00741     MUL_ON_HELPER(sgn,  nbits, ndigits, digit,
00742                   v.nbits, v.ndigits, v.digit);
00743 
00744   return *this;
00745 }
00746 
00747 
00748 const CLASS_TYPE&
00749 CLASS_TYPE::operator*=(const OTHER_CLASS_TYPE& v)
00750 {
00751   // u = *this
00752 
00753   sgn = mul_signs(sgn, v.sgn);
00754 
00755   if (sgn == SC_ZERO) // case 1
00756     vec_zero(ndigits, digit);
00757 
00758   else 
00759     // cases 2-4
00760     MUL_ON_HELPER(sgn,  nbits, ndigits, digit,
00761                   v.nbits, v.ndigits, v.digit);
00762 
00763   return *this;
00764 }
00765 
00766 
00767 const CLASS_TYPE&
00768 CLASS_TYPE::operator*=(int64 v)
00769 {
00770   // u = *this
00771 
00772   sgn = mul_signs(sgn, get_sign(v));
00773 
00774   if (sgn == SC_ZERO) // case 1
00775     vec_zero(ndigits, digit);
00776 
00777   else {  // cases 2-4
00778 
00779     CONVERT_INT64_2(v);
00780 
00781     MUL_ON_HELPER(sgn,  nbits, ndigits, digit,
00782                   BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00783 
00784   }
00785 
00786   return *this;
00787 }
00788 
00789 
00790 const CLASS_TYPE&
00791 CLASS_TYPE::operator*=(uint64 v)
00792 {
00793   // u = *this
00794 
00795   sgn = mul_signs(sgn, get_sign(v));
00796 
00797   if (sgn == SC_ZERO) // case 1
00798     vec_zero(ndigits, digit);
00799 
00800   else { // cases 2-4
00801 
00802     CONVERT_INT64_2(v);
00803 
00804     MUL_ON_HELPER(sgn,  nbits, ndigits, digit,
00805                   BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00806 
00807   }
00808 
00809   return *this;
00810 }
00811 
00812 
00813 const CLASS_TYPE&
00814 CLASS_TYPE::operator*=(long v)
00815 {
00816   // u = *this
00817 
00818   sgn = mul_signs(sgn, get_sign(v));
00819 
00820   if (sgn == SC_ZERO) // case 1
00821     vec_zero(ndigits, digit);
00822 
00823   else {   // cases 2-4
00824 
00825     CONVERT_LONG_2(v);
00826 
00827     MUL_ON_HELPER(sgn,  nbits, ndigits, digit,
00828                   BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
00829 
00830   }
00831 
00832   return *this;
00833 }
00834 
00835 
00836 const CLASS_TYPE&
00837 CLASS_TYPE::operator*=(unsigned long v)
00838 {
00839   // u = *this
00840 
00841   sgn = mul_signs(sgn, get_sign(v));
00842 
00843   if (sgn == SC_ZERO) // case 1
00844     vec_zero(ndigits, digit);
00845 
00846   else {  // cases 2-4
00847 
00848     CONVERT_LONG_2(v);
00849 
00850     MUL_ON_HELPER(sgn,  nbits, ndigits, digit,
00851                   BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
00852 
00853   }
00854 
00855   return *this;
00856 }
00857 
00858 
00859 // ----------------------------------------------------------------------------
00860 //  SECTION: DIVISION operators: /, /=
00861 // ----------------------------------------------------------------------------
00862 
00863 // Cases to consider when finding the quotient q = floor(u/v):
00864 // Note that u = q * v + r for r < q.
00865 // 1. 0 / 0 or u / 0 => error
00866 // 2. 0 / v => 0 = 0 * v + 0
00867 // 3. u / v && u = v => u = 1 * u + 0  - u or v can be 1 or -1
00868 // 4. u / v && u < v => u = 0 * v + u  - u can be 1 or -1
00869 // 5. u / v && u > v => u = q * v + r  - v can be 1 or -1
00870 
00871 const CLASS_TYPE&
00872 CLASS_TYPE::operator/=(const CLASS_TYPE& v)
00873 {
00874   sgn = mul_signs(sgn, v.sgn);
00875 
00876   if (sgn == SC_ZERO) {
00877 
00878     div_by_zero(v.sgn); // case 1
00879     vec_zero(ndigits, digit);  // case 2
00880 
00881   }
00882   else  // other cases
00883     DIV_ON_HELPER(sgn, nbits, ndigits, digit,
00884                   v.nbits, v.ndigits, v.digit);
00885 
00886   return *this;
00887 }
00888 
00889 
00890 const CLASS_TYPE&
00891 CLASS_TYPE::operator/=(const OTHER_CLASS_TYPE& v)
00892 {
00893   sgn = mul_signs(sgn, v.sgn);
00894 
00895   if (sgn == SC_ZERO) {
00896 
00897     div_by_zero(v.sgn); // case 1
00898     vec_zero(ndigits, digit);  // case 2
00899 
00900   }
00901   else  // other cases
00902     DIV_ON_HELPER(sgn, nbits, ndigits, digit,
00903                   v.nbits, v.ndigits, v.digit);
00904 
00905   return *this;
00906 }
00907 
00908 
00909 const CLASS_TYPE&
00910 CLASS_TYPE::operator/=(int64 v)
00911 {
00912   // u = *this
00913 
00914   sgn = mul_signs(sgn, get_sign(v));
00915 
00916   if (sgn == SC_ZERO) {
00917 
00918     div_by_zero(v);  // case 1
00919     vec_zero(ndigits, digit); // case 2
00920 
00921   }
00922   else {
00923 
00924     CONVERT_INT64_2(v);
00925 
00926     // other cases
00927     DIV_ON_HELPER(sgn, nbits, ndigits, digit,
00928                   BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00929 
00930   }
00931 
00932   return *this;
00933 }
00934 
00935 
00936 const CLASS_TYPE&
00937 CLASS_TYPE::operator/=(uint64 v)
00938 {
00939   // u = *this
00940 
00941   sgn = mul_signs(sgn, get_sign(v));
00942 
00943   if (sgn == SC_ZERO) {
00944 
00945     div_by_zero(v);  // case 1
00946     vec_zero(ndigits, digit);  // case 2
00947 
00948   }
00949   else {
00950 
00951     CONVERT_INT64_2(v);
00952 
00953     // other cases
00954     DIV_ON_HELPER(sgn, nbits, ndigits, digit,
00955                   BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
00956 
00957   }
00958 
00959   return *this;
00960 }
00961 
00962 
00963 const CLASS_TYPE&
00964 CLASS_TYPE::operator/=(long v)
00965 {
00966   // u = *this
00967 
00968   sgn = mul_signs(sgn, get_sign(v));
00969 
00970   if (sgn == SC_ZERO) {
00971 
00972     div_by_zero(v);  // case 1
00973     vec_zero(ndigits, digit); // case 2
00974 
00975   }
00976   else {
00977 
00978     CONVERT_LONG_2(v);
00979 
00980     // other cases
00981     DIV_ON_HELPER(sgn,  nbits, ndigits, digit,
00982                   BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
00983 
00984   }
00985 
00986   return *this;
00987 }
00988 
00989 
00990 const CLASS_TYPE&
00991 CLASS_TYPE::operator/=(unsigned long v)
00992 {
00993   // u = *this
00994 
00995   sgn = mul_signs(sgn, get_sign(v));
00996 
00997   if (sgn == SC_ZERO) {
00998 
00999     div_by_zero(v);  // case 1
01000     vec_zero(ndigits, digit);  // case 2
01001 
01002   }
01003   else {
01004     
01005     CONVERT_LONG_2(v);
01006 
01007     // other cases
01008     DIV_ON_HELPER(sgn,  nbits, ndigits, digit,
01009                   BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01010 
01011   }
01012 
01013   return *this;
01014 }
01015 
01016 
01017 // ----------------------------------------------------------------------------
01018 //  SECTION: MOD operators: %, %=.
01019 // ----------------------------------------------------------------------------
01020 
01021 // Cases to consider when finding the remainder r = u % v:
01022 // Note that u = q * v + r for r < q.
01023 // 1. 0 % 0 or u % 0 => error
01024 // 2. 0 % v => 0 = 0 * v + 0
01025 // 3. u % v && u = v => u = 1 * u + 0  - u or v can be 1 or -1
01026 // 4. u % v && u < v => u = 0 * v + u  - u can be 1 or -1
01027 // 5. u % v && u > v => u = q * v + r  - v can be 1 or -1
01028 
01029 const CLASS_TYPE&
01030 CLASS_TYPE::operator%=(const CLASS_TYPE& v)
01031 {
01032   if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
01033 
01034     div_by_zero(v.sgn);  // case 1
01035     vec_zero(ndigits, digit);  // case 2
01036 
01037   }
01038   else // other cases
01039     MOD_ON_HELPER(sgn, nbits, ndigits, digit,
01040                   v.nbits, v.ndigits, v.digit);
01041 
01042   return *this;
01043 }
01044 
01045 
01046 const CLASS_TYPE&
01047 CLASS_TYPE::operator%=(const OTHER_CLASS_TYPE& v)
01048 {
01049   if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {
01050 
01051     div_by_zero(v.sgn);  // case 1
01052     vec_zero(ndigits, digit);  // case 2
01053 
01054   }
01055   else  // other cases
01056     MOD_ON_HELPER(sgn, nbits, ndigits, digit,
01057                   v.nbits, v.ndigits, v.digit);
01058 
01059   return *this;
01060 }
01061 
01062 
01063 const CLASS_TYPE&
01064 CLASS_TYPE::operator%=(int64 v)
01065 {
01066   small_type vs = get_sign(v);
01067 
01068   if ((sgn == SC_ZERO) || (vs == SC_ZERO)) {
01069 
01070     div_by_zero(v);  // case 1
01071     vec_zero(ndigits, digit);  // case 2
01072 
01073   }
01074   else {
01075     
01076     CONVERT_INT64_2(v);
01077 
01078     // other cases
01079     MOD_ON_HELPER(sgn, nbits, ndigits, digit,
01080                   BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01081 
01082   }
01083 
01084   return *this;
01085 }
01086 
01087 
01088 const CLASS_TYPE&
01089 CLASS_TYPE::operator%=(uint64 v)
01090 {
01091   if ((sgn == SC_ZERO) || (v == 0)) {
01092 
01093     div_by_zero(v);  // case 1
01094     vec_zero(ndigits, digit);  // case 2
01095 
01096   }
01097   else {
01098     
01099     CONVERT_INT64_2(v);
01100 
01101     // other cases
01102     MOD_ON_HELPER(sgn, nbits, ndigits, digit,
01103                   BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01104 
01105   }
01106 
01107   return *this;
01108 }
01109 
01110 
01111 const CLASS_TYPE&
01112 CLASS_TYPE::operator%=(long v)
01113 {
01114   small_type vs = get_sign(v);
01115 
01116   if ((sgn == SC_ZERO) || (vs == SC_ZERO)) {
01117 
01118     div_by_zero(v);  // case 1
01119     vec_zero(ndigits, digit);  // case 2
01120 
01121   }
01122   else {
01123     
01124     CONVERT_LONG_2(v);
01125 
01126     // other cases
01127     MOD_ON_HELPER(sgn, nbits, ndigits, digit,
01128                   BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01129 
01130   }
01131 
01132   return *this;
01133 }
01134 
01135 
01136 const CLASS_TYPE&
01137 CLASS_TYPE::operator%=(unsigned long v)
01138 {
01139   if ((sgn == SC_ZERO) || (v == 0)) {
01140 
01141     div_by_zero(v);  // case 1
01142     vec_zero(ndigits, digit);  // case 2
01143 
01144   }
01145   else {
01146     
01147     CONVERT_LONG_2(v);
01148 
01149     // other cases
01150     MOD_ON_HELPER(sgn, nbits, ndigits, digit,
01151                   BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01152 
01153   }
01154 
01155   return *this;
01156 }
01157 
01158 
01159 // ----------------------------------------------------------------------------
01160 //  SECTION: Bitwise AND operators: &, &=
01161 // ----------------------------------------------------------------------------
01162 
01163 // Cases to consider when computing u & v:
01164 // 1. u & 0 = 0 & v = 0
01165 // 2. u & v => sgn = +
01166 // 3. (-u) & (-v) => sgn = -
01167 // 4. u & (-v) => sgn = +
01168 // 5. (-u) & v => sgn = +
01169 
01170 const CLASS_TYPE&
01171 CLASS_TYPE::operator&=(const CLASS_TYPE& v)
01172 {
01173   // u = *this
01174 
01175   if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
01176     makezero();
01177 
01178   else  {  // other cases
01179 
01180     and_on_help(sgn, nbits, ndigits, digit,
01181                 v.sgn, v.nbits, v.ndigits, v.digit);
01182 
01183     convert_2C_to_SM();
01184 
01185   }
01186 
01187   return *this;
01188 }
01189 
01190 
01191 const CLASS_TYPE&
01192 CLASS_TYPE::operator&=(const OTHER_CLASS_TYPE& v)
01193 {
01194   // u = *this
01195 
01196   if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1
01197     makezero();
01198 
01199   else {  // other cases
01200     
01201     and_on_help(sgn, nbits, ndigits, digit,
01202                 v.sgn, v.nbits, v.ndigits, v.digit);
01203 
01204     convert_2C_to_SM();
01205 
01206   }
01207 
01208   return *this;
01209 }
01210 
01211 
01212 const CLASS_TYPE&
01213 CLASS_TYPE::operator&=(int64 v)
01214 {
01215   // u = *this
01216 
01217   if ((sgn == SC_ZERO) || (v == 0)) // case 1
01218     makezero();
01219 
01220   else {    // other cases
01221 
01222     CONVERT_INT64(v);
01223 
01224     and_on_help(sgn, nbits, ndigits, digit,
01225                 vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01226 
01227     convert_2C_to_SM();
01228 
01229   }
01230 
01231   return *this;
01232 }
01233 
01234 
01235 const CLASS_TYPE&
01236 CLASS_TYPE::operator&=(uint64 v)
01237 {
01238   // u = *this
01239 
01240   if ((sgn == SC_ZERO) || (v == 0))  // case 1
01241     makezero();
01242 
01243   else {  // other cases
01244 
01245     CONVERT_INT64(v);
01246 
01247     and_on_help(sgn, nbits, ndigits, digit,
01248                 vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01249 
01250     convert_2C_to_SM();
01251     
01252   }
01253 
01254   return *this;
01255 }
01256 
01257 
01258 const CLASS_TYPE&
01259 CLASS_TYPE::operator&=(long v)
01260 {
01261   // u = *this
01262 
01263   if ((sgn == SC_ZERO) || (v == 0))  // case 1
01264     makezero();
01265 
01266   else {      // other cases
01267 
01268     CONVERT_LONG(v);
01269 
01270     and_on_help(sgn, nbits, ndigits, digit,
01271                 vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01272 
01273     convert_2C_to_SM();
01274 
01275   }
01276 
01277   return *this;
01278 }
01279 
01280 
01281 const CLASS_TYPE&
01282 CLASS_TYPE::operator&=(unsigned long v)
01283 {
01284   // u = *this
01285 
01286   if ((sgn == SC_ZERO) || (v == 0))  // case 1
01287     makezero();
01288 
01289   else {  // other cases
01290 
01291     CONVERT_LONG(v);
01292 
01293     and_on_help(sgn, nbits, ndigits, digit,
01294                 vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01295 
01296     convert_2C_to_SM();
01297 
01298   }
01299 
01300   return *this;
01301 }
01302 
01303 
01304 // ----------------------------------------------------------------------------
01305 //  SECTION: Bitwise OR operators: |, |=
01306 // ----------------------------------------------------------------------------
01307 
01308 // Cases to consider when computing u | v:
01309 // 1. u | 0 = u
01310 // 2. 0 | v = v
01311 // 3. u | v => sgn = +
01312 // 4. (-u) | (-v) => sgn = -
01313 // 5. u | (-v) => sgn = -
01314 // 6. (-u) | v => sgn = -
01315 
01316 const CLASS_TYPE&
01317 CLASS_TYPE::operator|=(const CLASS_TYPE& v)
01318 {
01319   if (v.sgn == SC_ZERO)  // case 1
01320     return *this;
01321 
01322   if (sgn == SC_ZERO)  // case 2
01323     return (*this = v);
01324 
01325   // other cases
01326   or_on_help(sgn, nbits, ndigits, digit,
01327              v.sgn, v.nbits, v.ndigits, v.digit);
01328 
01329   convert_2C_to_SM();
01330 
01331   return *this;
01332 }
01333 
01334 
01335 const CLASS_TYPE&
01336 CLASS_TYPE::operator|=(const OTHER_CLASS_TYPE& v)
01337 {
01338   if (v.sgn == SC_ZERO)  // case 1
01339     return *this;
01340 
01341   if (sgn == SC_ZERO)  // case 2
01342     return (*this = v);
01343 
01344   // other cases
01345   or_on_help(sgn, nbits, ndigits, digit,
01346              v.sgn, v.nbits, v.ndigits, v.digit);
01347 
01348   convert_2C_to_SM();
01349 
01350   return *this;
01351 }
01352 
01353 
01354 const CLASS_TYPE&
01355 CLASS_TYPE::operator|=(int64 v)
01356 {
01357   if (v == 0)  // case 1
01358     return *this;
01359 
01360   if (sgn == SC_ZERO)  // case 2
01361     return (*this = v);
01362 
01363   // other cases
01364 
01365   CONVERT_INT64(v);
01366 
01367   or_on_help(sgn, nbits, ndigits, digit,
01368              vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01369 
01370   convert_2C_to_SM();
01371 
01372   return *this;
01373 }
01374 
01375 
01376 const CLASS_TYPE&
01377 CLASS_TYPE::operator|=(uint64 v)
01378 {
01379   if (v == 0)  // case 1
01380     return *this;
01381 
01382   if (sgn == SC_ZERO)  // case 2
01383     return (*this = v);
01384 
01385   // other cases
01386 
01387   CONVERT_INT64(v);
01388 
01389   or_on_help(sgn, nbits, ndigits, digit,
01390              vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01391 
01392   convert_2C_to_SM();
01393 
01394   return *this;
01395 }
01396 
01397 
01398 const CLASS_TYPE&
01399 CLASS_TYPE::operator|=(long v)
01400 {
01401   if (v == 0)  // case 1
01402     return *this;
01403 
01404   if (sgn == SC_ZERO)  // case 2
01405     return (*this = v);
01406 
01407   // other cases
01408 
01409   CONVERT_LONG(v);
01410 
01411   or_on_help(sgn, nbits, ndigits, digit,
01412              vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01413 
01414   convert_2C_to_SM();
01415 
01416   return *this;
01417 }
01418 
01419 
01420 const CLASS_TYPE&
01421 CLASS_TYPE::operator|=(unsigned long v)
01422 {
01423   if (v == 0)  // case 1
01424     return *this;
01425 
01426   if (sgn == SC_ZERO)  // case 2
01427     return (*this = v);
01428 
01429   // other cases
01430 
01431   CONVERT_LONG(v);
01432 
01433   or_on_help(sgn, nbits, ndigits, digit,
01434              vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01435 
01436   convert_2C_to_SM();
01437 
01438   return *this;
01439 }
01440 
01441 
01442 // ----------------------------------------------------------------------------
01443 //  SECTION: Bitwise XOR operators: ^, ^=
01444 // ----------------------------------------------------------------------------
01445 
01446 // Cases to consider when computing u ^ v:
01447 // Note that  u ^ v = (~u & v) | (u & ~v).
01448 // 1. u ^ 0 = u
01449 // 2. 0 ^ v = v
01450 // 3. u ^ v => sgn = +
01451 // 4. (-u) ^ (-v) => sgn = -
01452 // 5. u ^ (-v) => sgn = -
01453 // 6. (-u) ^ v => sgn = +
01454 
01455 const CLASS_TYPE&
01456 CLASS_TYPE::operator^=(const CLASS_TYPE& v)
01457 {
01458   // u = *this
01459 
01460   if (v.sgn == SC_ZERO)  // case 1
01461     return *this;
01462 
01463   if (sgn == SC_ZERO)  // case 2
01464     return (*this = v);
01465 
01466   // other cases
01467   xor_on_help(sgn, nbits, ndigits, digit,
01468               v.sgn, v.nbits, v.ndigits, v.digit);
01469 
01470   convert_2C_to_SM();
01471 
01472   return *this;
01473 }
01474 
01475 
01476 const CLASS_TYPE&
01477 CLASS_TYPE::operator^=(const OTHER_CLASS_TYPE& v)
01478 {
01479   // u = *this
01480 
01481   if (v.sgn == SC_ZERO)  // case 1
01482     return *this;
01483 
01484   if (sgn == SC_ZERO)  // case 2
01485     return (*this = v);
01486 
01487   // other cases
01488   xor_on_help(sgn, nbits, ndigits, digit,
01489               v.sgn, v.nbits, v.ndigits, v.digit);
01490 
01491   convert_2C_to_SM();
01492 
01493   return *this;
01494 }
01495 
01496 
01497 const CLASS_TYPE&
01498 CLASS_TYPE::operator^=(int64 v)
01499 {
01500   if (v == 0)  // case 1
01501     return *this;
01502 
01503   if (sgn == SC_ZERO)  // case 2
01504     return (*this = v);
01505 
01506   // other cases
01507 
01508   CONVERT_INT64(v);
01509 
01510   xor_on_help(sgn, nbits, ndigits, digit,
01511               vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01512 
01513   convert_2C_to_SM();
01514 
01515   return *this;
01516 }
01517 
01518 
01519 const CLASS_TYPE&
01520 CLASS_TYPE::operator^=(uint64 v)
01521 {
01522   if (v == 0)  // case 1
01523     return *this;
01524 
01525   if (sgn == SC_ZERO)  // case 2
01526     return (*this = v);
01527 
01528   // other cases
01529 
01530   CONVERT_INT64(v);
01531 
01532   xor_on_help(sgn, nbits, ndigits, digit,
01533               vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);
01534   
01535   convert_2C_to_SM();
01536 
01537   return *this;
01538 }
01539 
01540 
01541 const CLASS_TYPE&
01542 CLASS_TYPE::operator^=(long v)
01543 {
01544   if (v == 0)  // case 1
01545     return *this;
01546 
01547   if (sgn == SC_ZERO)  // case 2
01548     return (*this = v);
01549 
01550   // other cases
01551 
01552   CONVERT_LONG(v);
01553 
01554   xor_on_help(sgn, nbits, ndigits, digit,
01555               vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01556 
01557   convert_2C_to_SM();
01558 
01559   return *this;
01560 }
01561 
01562 
01563 const CLASS_TYPE&
01564 CLASS_TYPE::operator^=(unsigned long v)
01565 {
01566   if (v == 0)  // case 1
01567     return *this;
01568 
01569   if (sgn == SC_ZERO)  // case 2
01570     return (*this = v);
01571 
01572   // other cases
01573 
01574   CONVERT_LONG(v);
01575 
01576   xor_on_help(sgn, nbits, ndigits, digit,
01577               vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);
01578   
01579   convert_2C_to_SM();
01580 
01581   return *this;
01582 }
01583 
01584 
01585 // ----------------------------------------------------------------------------
01586 //  SECTION: Bitwise NOT operator: ~
01587 // ----------------------------------------------------------------------------
01588 
01589 CLASS_TYPE
01590 operator~(const CLASS_TYPE& u)
01591 {
01592   small_type s = u.sgn;
01593 
01594   if (s == SC_ZERO) {
01595 
01596     sc_digit d = 1;
01597     return CLASS_TYPE(SC_NEG, u.nbits, 1, &d, false);
01598 
01599   }
01600 
01601   int nd = u.ndigits;
01602 
01603 #ifdef SC_MAX_NBITS
01604   sc_digit d[MAX_NDIGITS];
01605 #else
01606   sc_digit *d = new sc_digit[nd];
01607 #endif
01608 
01609   vec_copy(nd, d, u.digit);
01610 
01611   if (s == SC_POS) {
01612 
01613     s = SC_NEG;
01614     vec_add_small_on(nd, d, 1);
01615 
01616   }
01617   else {
01618 
01619     s = SC_POS;
01620     vec_sub_small_on(nd, d, 1);
01621 
01622     if (check_for_zero(nd, d))
01623       s = SC_ZERO;
01624 
01625   }
01626 
01627   return CLASS_TYPE(s, u.nbits, nd, d);
01628 }
01629 
01630 
01631 // ----------------------------------------------------------------------------
01632 //  SECTION: LEFT SHIFT operators: <<, <<=
01633 // ----------------------------------------------------------------------------
01634 
01635 CLASS_TYPE
01636 operator<<(const CLASS_TYPE& u, const CLASS_TYPE& v)
01637 {
01638   if (v.sgn == SC_ZERO) 
01639     return CLASS_TYPE(u);
01640 
01641 #ifdef SC_SIGNED
01642   if (v.sgn == SC_NEG)
01643     return CLASS_TYPE(u);
01644 #endif
01645 
01646   return operator<<(u, v.to_ulong());
01647 }
01648 
01649 
01650 const CLASS_TYPE&
01651 CLASS_TYPE::operator<<=(const CLASS_TYPE& v)
01652 {
01653   if (v.sgn == SC_ZERO)
01654     return *this;
01655 
01656 #ifdef SC_SIGNED
01657   if (v.sgn == SC_NEG)
01658     return *this;
01659 #endif 
01660 
01661   return operator<<=(v.to_ulong());
01662 }
01663 
01664 
01665 const CLASS_TYPE&
01666 CLASS_TYPE::operator<<=(const OTHER_CLASS_TYPE& v)
01667 {
01668   if (v.sgn == SC_ZERO)
01669     return *this;
01670 
01671 #ifdef SC_UNSIGNED
01672   if (v.sgn == SC_NEG)
01673     return *this;
01674 #endif
01675 
01676   return operator<<=(v.to_ulong());
01677 }
01678 
01679 
01680 CLASS_TYPE
01681 operator<<(const CLASS_TYPE& u, int64 v)
01682 {
01683   if (v <= 0)
01684     return CLASS_TYPE(u);
01685 
01686   return operator<<(u, (unsigned long) v);
01687 }
01688 
01689 
01690 CLASS_TYPE
01691 operator<<(const CLASS_TYPE& u, uint64 v)
01692 {
01693   if (v == 0)
01694     return CLASS_TYPE(u);
01695 
01696   return operator<<(u, (unsigned long) v);
01697 }
01698 
01699 
01700 const CLASS_TYPE&
01701 CLASS_TYPE::operator<<=(int64 v)
01702 {
01703   if (v <= 0)
01704     return *this;
01705 
01706   return operator<<=((unsigned long) v);
01707 }
01708 
01709 
01710 const CLASS_TYPE&
01711 CLASS_TYPE::operator<<=(uint64 v)
01712 {
01713   if (v == 0)
01714     return *this;
01715 
01716   return operator<<=((unsigned long) v);
01717 }
01718 
01719 
01720 CLASS_TYPE
01721 operator<<(const CLASS_TYPE& u, long v)
01722 {
01723   if (v <= 0)
01724     return CLASS_TYPE(u);
01725 
01726   return operator<<(u, (unsigned long) v);
01727 }
01728 
01729 CLASS_TYPE
01730 operator<<(const CLASS_TYPE& u, unsigned long v)
01731 {
01732   if (v == 0)
01733     return CLASS_TYPE(u);
01734 
01735   if (u.sgn == SC_ZERO)
01736     return CLASS_TYPE(u);
01737 
01738   int nb = u.nbits + v;
01739   int nd = DIV_CEIL(nb);
01740 
01741 #ifdef SC_MAX_NBITS
01742   test_bound(nb);
01743   sc_digit d[MAX_NDIGITS];
01744 #else
01745   sc_digit *d = new sc_digit[nd];
01746 #endif  
01747 
01748   vec_copy_and_zero(nd, d, u.ndigits, u.digit);
01749 
01750   convert_SM_to_2C(u.sgn, nd, d);
01751 
01752   vec_shift_left(nd, d, v);
01753 
01754   small_type s = convert_signed_2C_to_SM(nb, nd, d);
01755 
01756   return CLASS_TYPE(s, nb, nd, d);
01757 }
01758 
01759 
01760 const CLASS_TYPE&
01761 CLASS_TYPE::operator<<=(long v)
01762 {
01763   if (v <= 0)
01764     return *this;
01765 
01766   return operator<<=((unsigned long) v);
01767 }
01768 
01769 
01770 const CLASS_TYPE&
01771 CLASS_TYPE::operator<<=(unsigned long v)
01772 {
01773   if (v == 0)
01774     return *this;
01775 
01776   if (sgn == SC_ZERO)
01777     return *this;
01778 
01779   convert_SM_to_2C();
01780 
01781   vec_shift_left(ndigits, digit, v);
01782 
01783   convert_2C_to_SM();
01784 
01785   return *this;
01786 }
01787 
01788 
01789 // ----------------------------------------------------------------------------
01790 //  SECTION: RIGHT SHIFT operators: >>, >>=
01791 // ----------------------------------------------------------------------------
01792 
01793 CLASS_TYPE
01794 operator>>(const CLASS_TYPE& u, const CLASS_TYPE& v)
01795 {
01796   if (v.sgn == SC_ZERO)
01797     return CLASS_TYPE(u);
01798 
01799 #ifdef SC_SIGNED
01800   if (v.sgn == SC_NEG)
01801     return CLASS_TYPE(u);
01802 #endif
01803 
01804   return operator>>(u, v.to_long());
01805 }
01806 
01807 
01808 const CLASS_TYPE&
01809 CLASS_TYPE::operator>>=(const CLASS_TYPE& v)
01810 {
01811   if (v.sgn == SC_ZERO)
01812     return *this;
01813 
01814 #ifdef SC_SIGNED
01815   if (v.sgn == SC_NEG)
01816     return *this;
01817 #endif
01818 
01819   return operator>>=(v.to_long());
01820 }
01821 
01822 
01823 const CLASS_TYPE&
01824 CLASS_TYPE::operator>>=(const OTHER_CLASS_TYPE& v)
01825 {
01826   if (v.sgn == SC_ZERO)
01827     return *this;
01828 
01829 #ifdef SC_UNSIGNED
01830   if (v.sgn == SC_NEG)
01831     return *this;
01832 #endif
01833 
01834   return operator>>=(v.to_ulong());
01835 }
01836 
01837 
01838 CLASS_TYPE
01839 operator>>(const CLASS_TYPE& u, int64 v)
01840 {
01841   if (v <= 0)
01842     return CLASS_TYPE(u);
01843 
01844   return operator>>(u, (unsigned long) v);
01845 }
01846 
01847 
01848 CLASS_TYPE
01849 operator>>(const CLASS_TYPE& u, uint64 v)
01850 {
01851   if (v == 0)
01852     return CLASS_TYPE(u);
01853 
01854   return operator>>(u, (unsigned long) v);
01855 }
01856 
01857 const CLASS_TYPE&
01858 CLASS_TYPE::operator>>=(int64 v)
01859 {
01860   if (v <= 0)
01861     return *this;
01862 
01863   return operator>>=((unsigned long) v);
01864 }
01865 
01866 
01867 const CLASS_TYPE&
01868 CLASS_TYPE::operator>>=(uint64 v)
01869 {
01870   if (v == 0)
01871     return *this;
01872 
01873   return operator>>=((unsigned long) v);
01874 }
01875 
01876 
01877 CLASS_TYPE
01878 operator>>(const CLASS_TYPE& u, long v)
01879 {
01880   if (v <= 0)
01881     return CLASS_TYPE(u);
01882 
01883   return operator>>(u, (unsigned long) v);
01884 }
01885 
01886 
01887 CLASS_TYPE
01888 operator>>(const CLASS_TYPE& u, unsigned long v)
01889 {
01890   if (v == 0)
01891     return CLASS_TYPE(u);
01892 
01893   if (u.sgn == SC_ZERO)
01894     return CLASS_TYPE(u);
01895 
01896   int nb = u.nbits;
01897   int nd = u.ndigits;
01898 
01899 #ifdef SC_MAX_NBITS
01900   sc_digit d[MAX_NDIGITS];
01901 #else
01902   sc_digit *d = new sc_digit[nd];
01903 #endif  
01904 
01905   vec_copy(nd, d, u.digit);
01906 
01907   convert_SM_to_2C(u.sgn, nd, d);
01908 
01909   if (u.sgn == SC_NEG)
01910     vec_shift_right(nd, d, v, DIGIT_MASK);
01911   else
01912     vec_shift_right(nd, d, v, 0);
01913     
01914   small_type s = convert_signed_2C_to_SM(nb, nd, d);
01915 
01916   return CLASS_TYPE(s, nb, nd, d);
01917 }
01918 
01919 
01920 const CLASS_TYPE&
01921 CLASS_TYPE::operator>>=(long v)
01922 {
01923   if (v <= 0)
01924     return *this;
01925 
01926   return operator>>=((unsigned long) v);
01927 }
01928 
01929 
01930 const CLASS_TYPE&
01931 CLASS_TYPE::operator>>=(unsigned long v)
01932 {
01933   if (v == 0)
01934     return *this;
01935 
01936   if (sgn == SC_ZERO)
01937     return *this;
01938 
01939   convert_SM_to_2C();
01940 
01941   if (sgn == SC_NEG)
01942     vec_shift_right(ndigits, digit, v, DIGIT_MASK);
01943   else 
01944     vec_shift_right(ndigits, digit, v, 0);
01945 
01946   convert_2C_to_SM();
01947 
01948   return *this;
01949 }
01950 
01951 
01952 // ----------------------------------------------------------------------------
01953 //  SECTION: EQUAL TO operator: ==
01954 // ----------------------------------------------------------------------------
01955 
01956 // Defined in the sc_signed.cpp and sc_unsigned.cpp.
01957 
01958 
01959 // ----------------------------------------------------------------------------
01960 //  SECTION: NOT_EQUAL operator: !=
01961 // ----------------------------------------------------------------------------
01962 
01963 bool
01964 operator!=(const CLASS_TYPE& u, const CLASS_TYPE& v)
01965 {
01966   return (! operator==(u, v));
01967 }
01968 
01969 
01970 bool
01971 operator!=(const CLASS_TYPE& u, int64 v)
01972 {
01973   return (! operator==(u, v));
01974 }
01975 
01976 
01977 bool
01978 operator!=(int64 u, const CLASS_TYPE& v)
01979 {
01980   return (! operator==(u, v));  
01981 }
01982 
01983 
01984 bool
01985 operator!=(const CLASS_TYPE& u, uint64 v)
01986 {
01987   return (! operator==(u, v));  
01988 }
01989 
01990 
01991 bool
01992 operator!=(uint64 u, const CLASS_TYPE& v)
01993 {
01994   return (! operator==(u, v));  
01995 }
01996 
01997 
01998 bool
01999 operator!=(const CLASS_TYPE& u, long v)
02000 {
02001   return (! operator==(u, v));
02002 }
02003 
02004 
02005 bool
02006 operator!=(long u, const CLASS_TYPE& v)
02007 {
02008   return (! operator==(u, v));  
02009 }
02010 
02011 
02012 bool
02013 operator!=(const CLASS_TYPE& u, unsigned long v)
02014 {
02015   return (! operator==(u, v));  
02016 }
02017 
02018 
02019 bool
02020 operator!=(unsigned long u, const CLASS_TYPE& v)
02021 {
02022   return (! operator==(u, v));  
02023 }
02024 
02025 
02026 // ----------------------------------------------------------------------------
02027 //  SECTION: LESS THAN operator: <
02028 // ----------------------------------------------------------------------------
02029 
02030 // Defined in the sc_signed.cpp and sc_unsigned.cpp.
02031 
02032 
02033 // ----------------------------------------------------------------------------
02034 //  SECTION: LESS THAN or EQUAL operator: <=
02035 // ----------------------------------------------------------------------------
02036 
02037 bool
02038 operator<=(const CLASS_TYPE& u, const CLASS_TYPE& v)
02039 {
02040   return (operator<(u, v) || operator==(u, v));
02041 }
02042 
02043 
02044 bool
02045 operator<=(const CLASS_TYPE& u, int64 v)
02046 {
02047   return (operator<(u, v) || operator==(u, v));
02048 }
02049 
02050 
02051 bool
02052 operator<=(int64 u, const CLASS_TYPE& v)
02053 {
02054   return (operator<(u, v) || operator==(u, v));
02055 }
02056 
02057 
02058 bool
02059 operator<=(const CLASS_TYPE& u, uint64 v)
02060 {
02061   return (operator<(u, v) || operator==(u, v));
02062 }
02063 
02064 
02065 bool
02066 operator<=(uint64 u, const CLASS_TYPE& v)
02067 {
02068   return (operator<(u, v) || operator==(u, v));
02069 }
02070 
02071 
02072 bool
02073 operator<=(const CLASS_TYPE& u, long v)
02074 {
02075   return (operator<(u, v) || operator==(u, v));
02076 }
02077 
02078 
02079 bool
02080 operator<=(long u, const CLASS_TYPE& v)
02081 {
02082   return (operator<(u, v) || operator==(u, v));
02083 }
02084 
02085 
02086 bool
02087 operator<=(const CLASS_TYPE& u, unsigned long v)
02088 {
02089   return (operator<(u, v) || operator==(u, v));
02090 }
02091 
02092 
02093 bool
02094 operator<=(unsigned long u, const CLASS_TYPE& v)
02095 {
02096   return (operator<(u, v) || operator==(u, v));
02097 }
02098 
02099 
02100 // ----------------------------------------------------------------------------
02101 //  SECTION: GREATER THAN operator: >
02102 // ----------------------------------------------------------------------------
02103 
02104 bool
02105 operator>(const CLASS_TYPE& u, const CLASS_TYPE& v)
02106 {
02107   return (! (operator<=(u, v)));
02108 }
02109 
02110 
02111 bool
02112 operator>(const CLASS_TYPE& u, int64 v)
02113 {
02114   return (! (operator<=(u, v)));
02115 }
02116 
02117 
02118 bool
02119 operator>(int64 u, const CLASS_TYPE& v)
02120 {
02121   return (! (operator<=(u, v)));
02122 }
02123 
02124 
02125 bool
02126 operator>(const CLASS_TYPE& u, uint64 v)
02127 {
02128   return (! (operator<=(u, v)));
02129 }
02130 
02131 
02132 bool
02133 operator>(uint64 u, const CLASS_TYPE& v)
02134 {
02135   return (! (operator<=(u, v)));
02136 }
02137 
02138 
02139 bool
02140 operator>(const CLASS_TYPE& u, long v)
02141 {
02142   return (! (operator<=(u, v)));
02143 }
02144 
02145 
02146 bool
02147 operator>(long u, const CLASS_TYPE& v)
02148 {
02149   return (! (operator<=(u, v)));
02150 }
02151 
02152 
02153 bool
02154 operator>(const CLASS_TYPE& u, unsigned long v)
02155 {
02156   return (! (operator<=(u, v)));
02157 }
02158 
02159 
02160 bool
02161 operator>(unsigned long u, const CLASS_TYPE& v)
02162 {
02163   return (! (operator<=(u, v)));
02164 }
02165 
02166 
02167 // ----------------------------------------------------------------------------
02168 //  SECTION: GREATER THAN or EQUAL operator: >=
02169 // ----------------------------------------------------------------------------
02170 
02171 bool
02172 operator>=(const CLASS_TYPE& u, const CLASS_TYPE& v)
02173 {
02174   return (! (operator<(u, v)));
02175 }
02176 
02177 
02178 bool
02179 operator>=(const CLASS_TYPE& u, int64 v)
02180 {
02181   return (! (operator<(u, v)));
02182 }
02183 
02184 
02185 bool
02186 operator>=(int64 u, const CLASS_TYPE& v)
02187 {
02188   return (! (operator<(u, v)));
02189 }
02190 
02191 
02192 bool
02193 operator>=(const CLASS_TYPE& u, uint64 v)
02194 {
02195   return (! (operator<(u, v)));
02196 }
02197 
02198 
02199 bool
02200 operator>=(uint64 u, const CLASS_TYPE& v)
02201 {
02202   return (! (operator<(u, v)));
02203 }
02204 
02205 
02206 bool
02207 operator>=(const CLASS_TYPE& u, long v)
02208 {
02209   return (! (operator<(u, v)));
02210 }
02211 
02212 
02213 bool
02214 operator>=(long u, const CLASS_TYPE& v)
02215 {
02216   return (! (operator<(u, v)));
02217 }
02218 
02219 
02220 bool
02221 operator>=(const CLASS_TYPE& u, unsigned long v)
02222 {
02223   return (! (operator<(u, v)));
02224 }
02225 
02226 
02227 bool
02228 operator>=(unsigned long u, const CLASS_TYPE& v)
02229 {
02230   return (! (operator<(u, v)));
02231 }
02232 
02233 
02234 // ----------------------------------------------------------------------------
02235 //  SECTION: Public members - Other utils.
02236 // ----------------------------------------------------------------------------
02237 
02238 // Convert to int64, long, or int.
02239 #define TO_INTX(RET_TYPE, UP_RET_TYPE)   \
02240                                                              \
02241 if (sgn == SC_ZERO)                                          \
02242 return 0;                                                    \
02243                                                              \
02244 int vnd = sc_min((int)DIGITS_PER_ ## UP_RET_TYPE, ndigits); \
02245                                                              \
02246 RET_TYPE v = 0;                                              \
02247 while (--vnd >= 0)                                           \
02248 v = (v << BITS_PER_DIGIT) + digit[vnd];                      \
02249                                                              \
02250 if (sgn == SC_NEG)                                           \
02251 return -v;                                                   \
02252 else                                                         \
02253 return v;                                                    
02254 
02255 
02256 int64
02257 CLASS_TYPE::to_int64() const
02258 {
02259   TO_INTX(int64, INT64);
02260 }
02261 
02262 
02263 long
02264 CLASS_TYPE::to_long() const
02265 {
02266   TO_INTX(long, LONG);
02267 }
02268 
02269 
02270 int
02271 CLASS_TYPE::to_int() const
02272 {
02273   TO_INTX(int, INT);
02274 }
02275 
02276 
02277 // Convert to unsigned int64, unsigned long or unsigned
02278 // int. to_uint64, to_ulong, and to_uint have the same body except for
02279 // the type of v defined inside.
02280 uint64
02281 CLASS_TYPE::to_uint64() const
02282 {
02283   if (sgn == SC_ZERO)
02284     return 0;
02285 
02286   int vnd = sc_min((int)DIGITS_PER_INT64, ndigits);
02287 
02288   uint64 v = 0;
02289 
02290   if (sgn == SC_NEG) {
02291 
02292 #ifdef SC_MAX_NBITS
02293     sc_digit d[MAX_NDIGITS];
02294 #else
02295     sc_digit *d = new sc_digit[ndigits];
02296 #endif
02297 
02298     vec_copy(ndigits, d, digit);
02299 
02300     convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d);
02301 
02302     while (--vnd >= 0)
02303       v = (v << BITS_PER_DIGIT) + d[vnd];
02304 
02305 #ifndef SC_MAX_NBITS
02306     delete [] d;
02307 #endif
02308 
02309   }
02310   else {
02311 
02312     while (--vnd >= 0)
02313       v = (v << BITS_PER_DIGIT) + digit[vnd];
02314 
02315   }
02316 
02317   return v;
02318 }
02319 
02320 
02321 unsigned long
02322 CLASS_TYPE::to_ulong() const
02323 {
02324   if (sgn == SC_ZERO)
02325     return 0;
02326 
02327   int vnd = sc_min((int)DIGITS_PER_LONG, ndigits);
02328 
02329   unsigned long v = 0;
02330 
02331   if (sgn == SC_NEG) {
02332 
02333 #ifdef SC_MAX_NBITS
02334     sc_digit d[MAX_NDIGITS];
02335 #else
02336     sc_digit *d = new sc_digit[ndigits];
02337 #endif
02338 
02339     vec_copy(ndigits, d, digit);
02340 
02341     convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d);
02342 
02343     while (--vnd >= 0)
02344       v = (v << BITS_PER_DIGIT) + d[vnd];
02345 
02346 #ifndef SC_MAX_NBITS
02347     delete [] d;
02348 #endif
02349 
02350   }
02351   else {
02352 
02353     while (--vnd >= 0)
02354       v = (v << BITS_PER_DIGIT) + digit[vnd];
02355 
02356   }
02357 
02358   return v;
02359 }
02360 
02361 
02362 unsigned int
02363 CLASS_TYPE::to_uint() const
02364 {
02365   if (sgn == SC_ZERO)
02366     return 0;
02367 
02368   int vnd = sc_min((int)DIGITS_PER_INT, ndigits);
02369 
02370   unsigned int v = 0;
02371 
02372   if (sgn == SC_NEG) {
02373 
02374 #ifdef SC_MAX_NBITS
02375     sc_digit d[MAX_NDIGITS];
02376 #else
02377     sc_digit *d = new sc_digit[ndigits];
02378 #endif
02379 
02380     vec_copy(ndigits, d, digit);
02381 
02382     convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d);
02383 
02384     while (--vnd >= 0)
02385       v = (v << BITS_PER_DIGIT) + d[vnd];
02386 
02387 #ifndef SC_MAX_NBITS
02388     delete [] d;
02389 #endif
02390 
02391   }
02392   else {
02393 
02394     while (--vnd >= 0)
02395       v = (v << BITS_PER_DIGIT) + digit[vnd];
02396 
02397   }
02398 
02399   return v;
02400 }
02401 
02402 
02403 // Convert to double.
02404 double
02405 CLASS_TYPE::to_double() const
02406 {
02407   if (sgn == SC_ZERO)
02408     return (double) 0.0;
02409 
02410   int vnd = ndigits;
02411 
02412   double v = 0.0;
02413   while (--vnd >= 0)
02414     v = v * DIGIT_RADIX + digit[vnd];
02415 
02416   if (sgn == SC_NEG)
02417     return -v;
02418   else
02419     return v;
02420 }
02421 
02422 
02423 // Return true if the bit i is 1, false otherwise. If i is outside the
02424 // bounds, return 1/0 according to the sign of the number by assuming
02425 // that the number has infinite length.
02426 
02427 bool
02428 CLASS_TYPE::test(int i) const
02429 {
02430 #ifdef SC_SIGNED
02431   if (check_if_outside(i)) {
02432     if (sgn == SC_NEG)
02433       return 1;
02434     else
02435       return 0;
02436   }
02437 #else
02438   if (check_if_outside(i))
02439     return 0;
02440 #endif  
02441 
02442   int bit_num = bit_ord(i);
02443   int digit_num = digit_ord(i);
02444 
02445   if (sgn == SC_NEG) {
02446 
02447 #ifdef SC_MAX_NBITS
02448     sc_digit d[MAX_NDIGITS];
02449 #else
02450     sc_digit *d = new sc_digit[ndigits];
02451 #endif
02452 
02453     vec_copy(ndigits, d, digit);
02454     vec_complement(ndigits, d);
02455     bool val = ((d[digit_num] & one_and_zeros(bit_num)) != 0);
02456 
02457 #ifndef SC_MAX_NBITS
02458     delete [] d;
02459 #endif
02460 
02461     return val;
02462 
02463   }
02464   else 
02465     return ((digit[digit_num] & one_and_zeros(bit_num)) != 0);
02466 }
02467 
02468 
02469 // Set the ith bit with 1.
02470 void 
02471 CLASS_TYPE::set(int i) 
02472 {
02473   if (check_if_outside(i))
02474     return;
02475 
02476   int bit_num = bit_ord(i);
02477   int digit_num = digit_ord(i);
02478 
02479   convert_SM_to_2C();
02480   digit[digit_num] |= one_and_zeros(bit_num);    
02481   digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits.
02482   convert_2C_to_SM();
02483 }
02484 
02485 
02486 // Set the ith bit with 0, i.e., clear the ith bit.
02487 void 
02488 CLASS_TYPE::clear(int i)
02489 {
02490   if (check_if_outside(i))
02491     return;
02492 
02493   int bit_num = bit_ord(i);
02494   int digit_num = digit_ord(i);
02495 
02496   convert_SM_to_2C();
02497   digit[digit_num] &= ~(one_and_zeros(bit_num));
02498   digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits.
02499   convert_2C_to_SM();
02500 }
02501 
02502 
02503 // Create a mirror image of the number.
02504 void
02505 CLASS_TYPE::reverse()
02506 {
02507   convert_SM_to_2C();
02508   vec_reverse(length(), ndigits, digit, length() - 1);
02509   convert_2C_to_SM();
02510 }
02511 
02512 
02513 // Get a packed bit representation of the number.
02514 void 
02515 CLASS_TYPE::get_packed_rep(sc_digit *buf) const
02516 {
02517   int buf_ndigits = (length() - 1) / BITS_PER_DIGIT_TYPE + 1;
02518 
02519   // Initialize buf to zero.
02520   vec_zero(buf_ndigits, buf);
02521 
02522   if (sgn == SC_ZERO)
02523     return;
02524 
02525   const sc_digit *digit_or_d;
02526 #ifdef SC_MAX_NBITS
02527   sc_digit d[MAX_NDIGITS];
02528 #else
02529   sc_digit *d = new sc_digit[ndigits];
02530 #endif
02531 
02532   if (sgn == SC_POS)
02533     digit_or_d = digit;
02534 
02535   else 
02536   {
02537     // If sgn is negative, we have to convert digit to its 2's
02538     // complement. Since this function is const, we can not do it on
02539     // digit. Since buf doesn't have overflow bits, we cannot also do
02540     // it on buf. Thus, we have to do the complementation on a copy of
02541     // digit, i.e., on d.
02542 
02543     vec_copy(ndigits, d, digit);
02544     vec_complement(ndigits, d);
02545 
02546     buf[buf_ndigits - 1] = ~((sc_digit) 0);
02547 
02548     digit_or_d = d;
02549 
02550   }
02551 
02552   // Copy the bits from digit to buf. The division and mod operations
02553   // below can be converted to addition/subtraction and comparison
02554   // operations at the expense of complicating the code. We can do it
02555   // if we see any performance problems.
02556 
02557   for (register int i = length() - 1; i >= 0; --i) {
02558 
02559     if ((digit_or_d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test.
02560 
02561       buf[i / BITS_PER_DIGIT_TYPE] |= 
02562         one_and_zeros(i % BITS_PER_DIGIT_TYPE); // Set.
02563 
02564     else  
02565 
02566       buf[i / BITS_PER_DIGIT_TYPE] &= 
02567         ~(one_and_zeros(i % BITS_PER_DIGIT_TYPE));  // Clear.
02568 
02569   }
02570 
02571 #ifndef SC_MAX_NBITS
02572     delete[] d;
02573 #endif
02574 }
02575 
02576 
02577 // Set a packed bit representation of the number.
02578 void 
02579 CLASS_TYPE::set_packed_rep(sc_digit *buf)
02580 {
02581   // Initialize digit to zero.
02582   vec_zero(ndigits, digit);
02583 
02584   // Copy the bits from buf to digit.
02585   for (register int i = length() - 1; i >= 0; --i) {
02586 
02587     if ((buf[i / BITS_PER_DIGIT_TYPE] & 
02588          one_and_zeros(i % BITS_PER_DIGIT_TYPE)) != 0) // Test.
02589 
02590       digit[digit_ord(i)] |= one_and_zeros(bit_ord(i));     // Set.
02591 
02592     else  
02593 
02594       digit[digit_ord(i)] &= ~(one_and_zeros(bit_ord(i)));  // Clear
02595 
02596   }
02597 
02598   convert_2C_to_SM();
02599 }
02600 
02601 
02602 // ----------------------------------------------------------------------------
02603 //  SECTION: Private members.
02604 // ----------------------------------------------------------------------------
02605 
02606 // Create a copy of v with sgn s.
02607 CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE& v, small_type s)
02608 {
02609   sgn = s;
02610   nbits = v.nbits;
02611   ndigits = v.ndigits;
02612 
02613 #ifndef SC_MAX_NBITS
02614   digit = new sc_digit[ndigits];
02615 #endif
02616 
02617   vec_copy(ndigits, digit, v.digit);
02618 }
02619 
02620 
02621 // Create a copy of v where v is of the different type.
02622 CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE& v, small_type s)
02623 {
02624   sgn = s;
02625   nbits = num_bits(v.nbits);
02626 
02627 #if (IF_SC_SIGNED == 1)
02628   ndigits = v.ndigits;
02629 #else
02630   ndigits = DIV_CEIL(nbits);
02631 #endif
02632 
02633 #ifndef SC_MAX_NBITS
02634   digit = new sc_digit[ndigits];
02635 #endif
02636 
02637   copy_digits(v.nbits, v.ndigits, v.digit);
02638 }
02639 
02640 
02641 // Create a signed number with (s, nb, nd, d) as its attributes (as
02642 // defined in class CLASS_TYPE). If alloc is set, delete d.
02643 CLASS_TYPE::CLASS_TYPE(small_type s, int nb, 
02644                        int nd, sc_digit *d, 
02645                        bool alloc)
02646 {
02647   sgn = s;
02648   nbits = nb;
02649   ndigits = DIV_CEIL(nbits);
02650 
02651 #ifndef SC_MAX_NBITS
02652   digit = new sc_digit[ndigits];
02653 #endif
02654 
02655   if (ndigits <= nd)
02656     vec_copy(ndigits, digit, d);
02657   else
02658     vec_copy_and_zero(ndigits, digit, nd, d);
02659 
02660 #ifndef SC_MAX_NBITS
02661   if (alloc)
02662     delete [] d;
02663 #endif
02664 }
02665 
02666 // This constructor is mainly used in finding a "range" of bits from a
02667 // number of type CLASS_TYPE. The function range(l, r) can have
02668 // arbitrary precedence between l and r. If l is smaller than r, then
02669 // the output is the reverse of range(r, l). 
02670 CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE* u, int l, int r)
02671 {
02672   bool reversed = false;
02673 
02674   if( l < r ) {
02675     reversed = true;
02676     int tmp = l;
02677     l = r;
02678     r = tmp;
02679   }
02680 
02681   // at this point, l >= r
02682 
02683   // make sure that l and r point to the bits of u
02684   r = sc_max( r, 0 );
02685   l = sc_min( l, u->nbits - 1 );
02686     
02687   nbits = num_bits( l - r + 1 );
02688 
02689   // nbits can still be <= 0 because l and r have just been updated
02690   // with the bounds of u.
02691 
02692   // if u == 0 or the range is out of bounds, return 0
02693   if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) {
02694     sgn = SC_ZERO;
02695     if( nbits <= num_bits( 0 ) ) {
02696       nbits = 1;
02697     }
02698     ndigits = DIV_CEIL( nbits );
02699 #ifndef SC_MAX_NBITS
02700     digit = new sc_digit[ndigits];
02701 #endif
02702     vec_zero( ndigits, digit );
02703     return;
02704   }
02705 
02706   // The rest will be executed if u is not zero.
02707 
02708   ndigits = DIV_CEIL(nbits);
02709   
02710   // The number of bits up to and including l and r, respectively.
02711   int nl = l + 1; 
02712   int nr = r + 1; 
02713   
02714   // The indices of the digits that have lth and rth bits, respectively.
02715   int left_digit = DIV_CEIL(nl) - 1;
02716   int right_digit = DIV_CEIL(nr) - 1;
02717   
02718   int nd;
02719 
02720   // The range is performed on the 2's complement representation, so
02721   // first get the indices for that.
02722   if (u->sgn == SC_NEG)
02723     nd = left_digit + 1;
02724   else
02725     nd = left_digit - right_digit + 1;
02726 
02727   // Allocate memory for the range.
02728 #ifdef SC_MAX_NBITS
02729   sc_digit d[MAX_NDIGITS];
02730 #else
02731   digit = new sc_digit[ndigits];
02732   sc_digit *d = new sc_digit[nd];
02733 #endif
02734   
02735   // Getting the range on the 2's complement representation.
02736   if (u->sgn == SC_NEG) {
02737     
02738     vec_copy(nd, d, u->digit);
02739     vec_complement(nd, d);  // d = -d;
02740     vec_shift_right(nd, d, r, DIGIT_MASK);
02741     
02742   }
02743   else {
02744     
02745     for (register int i = right_digit; i <= left_digit; ++i)
02746       d[i - right_digit] = u->digit[i];
02747     
02748     vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0);
02749     
02750   }
02751   
02752   vec_zero(ndigits, digit);
02753 
02754   if (! reversed)
02755     vec_copy(sc_min(nd, ndigits), digit, d);
02756   
02757   else {
02758 
02759     // If l < r, i.e., reversed is set, reverse the bits of digit.  d
02760     // will be used as a temporary store. The following code tries to
02761     // minimize the use of bit_ord and digit_ord, which use mod and
02762     // div operators. Since these operators are function calls to
02763     // standard library routines, they are slow. The main idea in
02764     // reversing is "read bits out of d from left to right and push
02765     // them into digit using right shifting."
02766 
02767     // Take care of the last digit.
02768     int nd_less_1 = nd - 1;
02769 
02770     // Deletions will start from the left end and move one position
02771     // after each deletion.
02772     register sc_digit del_mask = one_and_zeros(bit_ord(l - r));
02773       
02774     while (del_mask) {
02775       vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0));
02776       del_mask >>= 1;
02777     }
02778 
02779     // Take care of the other digits if any.
02780 
02781     // Insertion to digit will always occur at the left end.
02782     sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1);
02783 
02784     for (register int j = nd - 2; j >= 0; --j) { // j = nd - 2
02785 
02786       // Deletions will start from the left end and move one position
02787       // after each deletion.
02788       del_mask = ins_mask;
02789 
02790       while (del_mask) {
02791         vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0));
02792         del_mask >>= 1;
02793       }
02794     }
02795 
02796     if (u->sgn == SC_NEG)
02797       vec_shift_right(ndigits, digit, 
02798                       ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK);
02799     else
02800       vec_shift_right(ndigits, digit, 
02801                       ndigits * BITS_PER_DIGIT - length(), 0);
02802 
02803 
02804   }  // if reversed.
02805 
02806   convert_2C_to_SM();
02807   
02808 #ifndef SC_MAX_NBITS
02809   delete [] d;
02810 #endif
02811 }
02812 
02813 // This constructor is mainly used in finding a "range" of bits from a
02814 // number of type OTHER_CLASS_TYPE. The function range(l, r) can have
02815 // arbitrary precedence between l and r. If l is smaller than r, then
02816 // the output is the reverse of range(r, l). 
02817 CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE* u, int l, int r)
02818 {
02819   bool reversed = false;
02820 
02821   if( l < r ) {
02822     reversed = true;
02823     int tmp = l;
02824     l = r;
02825     r = tmp;
02826   }
02827 
02828   // at this point, l >= r
02829 
02830   // make sure that l and r point to the bits of u
02831   r = sc_max( r, 0 );
02832   l = sc_min( l, u->nbits - 1 );
02833     
02834   nbits = num_bits( l - r + 1 );
02835 
02836   // nbits can still be <= 0 because l and r have just been updated
02837   // with the bounds of u.
02838 
02839   // if u == 0 or the range is out of bounds, return 0
02840   if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) {
02841     sgn = SC_ZERO;
02842     if( nbits <= num_bits( 0 ) ) {
02843       nbits = 1;
02844     }
02845     ndigits = DIV_CEIL( nbits );
02846 #ifndef SC_MAX_NBITS
02847     digit = new sc_digit[ndigits];
02848 #endif
02849     vec_zero( ndigits, digit );
02850     return;
02851   }
02852 
02853   // The rest will be executed if u is not zero.
02854 
02855   ndigits = DIV_CEIL(nbits);
02856   
02857   // The number of bits up to and including l and r, respectively.
02858   int nl = l + 1; 
02859   int nr = r + 1; 
02860   
02861   // The indices of the digits that have lth and rth bits, respectively.
02862   int left_digit = DIV_CEIL(nl) - 1;
02863   int right_digit = DIV_CEIL(nr) - 1;
02864   
02865   int nd;
02866 
02867   // The range is performed on the 2's complement representation, so
02868   // first get the indices for that.
02869   if (u->sgn == SC_NEG)
02870     nd = left_digit + 1;
02871   else
02872     nd = left_digit - right_digit + 1;
02873 
02874   // Allocate memory for the range.
02875 #ifdef SC_MAX_NBITS
02876   sc_digit d[MAX_NDIGITS];
02877 #else
02878   digit = new sc_digit[ndigits];
02879   sc_digit *d = new sc_digit[nd];
02880 #endif
02881   
02882   // Getting the range on the 2's complement representation.
02883   if (u->sgn == SC_NEG) {
02884     
02885     vec_copy(nd, d, u->digit);
02886     vec_complement(nd, d);  // d = -d;
02887     vec_shift_right(nd, d, r, DIGIT_MASK);
02888     
02889   }
02890   else {
02891     
02892     for (register int i = right_digit; i <= left_digit; ++i)
02893       d[i - right_digit] = u->digit[i];
02894     
02895     vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0);
02896     
02897   }
02898   
02899   vec_zero(ndigits, digit);
02900 
02901   if (! reversed)
02902     vec_copy(sc_min(nd, ndigits), digit, d);
02903   
02904   else {
02905 
02906     // If l < r, i.e., reversed is set, reverse the bits of digit.  d
02907     // will be used as a temporary store. The following code tries to
02908     // minimize the use of bit_ord and digit_ord, which use mod and
02909     // div operators. Since these operators are function calls to
02910     // standard library routines, they are slow. The main idea in
02911     // reversing is "read bits out of d from left to right and push
02912     // them into digit using right shifting."
02913 
02914     // Take care of the last digit.
02915     int nd_less_1 = nd - 1;
02916 
02917     // Deletions will start from the left end and move one position
02918     // after each deletion.
02919     register sc_digit del_mask = one_and_zeros(bit_ord(l - r));
02920       
02921     while (del_mask) {
02922       vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0));
02923       del_mask >>= 1;
02924     }
02925 
02926     // Take care of the other digits if any.
02927 
02928     // Insertion to digit will always occur at the left end.
02929     sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1);
02930 
02931     for (register int j = nd - 2; j >= 0; --j) { // j = nd - 2
02932 
02933       // Deletions will start from the left end and move one position
02934       // after each deletion.
02935       del_mask = ins_mask;
02936 
02937       while (del_mask) {
02938         vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0));
02939         del_mask >>= 1;
02940       }
02941     }
02942 
02943     if (u->sgn == SC_NEG)
02944       vec_shift_right(ndigits, digit, 
02945                       ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK);
02946     else
02947       vec_shift_right(ndigits, digit, 
02948                       ndigits * BITS_PER_DIGIT - length(), 0);
02949 
02950 
02951   }  // if reversed.
02952 
02953   convert_2C_to_SM();
02954   
02955 #ifndef SC_MAX_NBITS
02956   delete [] d;
02957 #endif
02958 }
02959 
02960 
02961 // Print out all the physical attributes.
02962 void
02963 CLASS_TYPE::dump(::std::ostream& os) const
02964 {
02965   // Save the current setting, and set the base to decimal.
02966   fmtflags old_flags = os.setf(::std::ios::dec, ::std::ios::basefield);
02967 
02968   os << "width = " << length() << ::std::endl;
02969   os << "value = " << *this << ::std::endl;
02970   os << "bits  = ";
02971 
02972   int len = length();
02973 
02974   for (int i = len - 1; i >= 0; --i) {
02975 
02976     os << "01"[test(i)];
02977     if (--len % 4 == 0)
02978       os << " ";
02979 
02980   }
02981 
02982   os << ::std::endl;
02983 
02984   // Restore old_flags.
02985   os.setf(old_flags, ::std::ios::basefield);
02986 }
02987 
02988 
02989 // Checks to see if bit_num is out of bounds.
02990 bool
02991 CLASS_TYPE::check_if_outside(int bit_num) const
02992 {
02993   if ((bit_num < 0) || (num_bits(bit_num) >= nbits)) {
02994 
02995 #ifdef DEBUG_SYSTEMC
02996       if( bit_num < 0 || bit_num >= nbits ) {
02997       char msg[BUFSIZ];
02998       std::sprintf( msg, "%s::check_if_outside( int bit_num ) : "
02999            "bit_num = %d is out of bounds",
03000            CLASS_TYPE_STR, bit_num );
03001       SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
03002       }
03003 #endif
03004 
03005     return true;
03006   }
03007 
03008   return false;
03009 }
03010 
03011 // End of file.
03012 

Generated on Wed Jan 21 15:32:08 2009 for SystemC by  doxygen 1.5.5