sc_nbcommon.inc revision 12854
112854Sgabeblack@google.com/***************************************************************************** 212854Sgabeblack@google.com 312854Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412854Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 512854Sgabeblack@google.com with this work for additional information regarding copyright ownership. 612854Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 712854Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 812854Sgabeblack@google.com License. You may obtain a copy of the License at 912854Sgabeblack@google.com 1012854Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1112854Sgabeblack@google.com 1212854Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1312854Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1412854Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512854Sgabeblack@google.com implied. See the License for the specific language governing 1612854Sgabeblack@google.com permissions and limitations under the License. 1712854Sgabeblack@google.com 1812854Sgabeblack@google.com *****************************************************************************/ 1912854Sgabeblack@google.com 2012854Sgabeblack@google.com/***************************************************************************** 2112854Sgabeblack@google.com 2212854Sgabeblack@google.com sc_nbcommon.cpp -- Functions common to both sc_signed and sc_unsigned. 2312854Sgabeblack@google.com This file is included in sc_signed.cpp and 2412854Sgabeblack@google.com sc_unsigned.cpp after the macros are defined accordingly. 2512854Sgabeblack@google.com For example, sc_signed.cpp will first define CLASS_TYPE 2612854Sgabeblack@google.com as sc_signed before including this file. This file like 2712854Sgabeblack@google.com sc_nbfriends.cpp and sc_nbexterns.cpp is created in order 2812854Sgabeblack@google.com to ensure only one version of each function, regardless 2912854Sgabeblack@google.com of the class that they interface to. 3012854Sgabeblack@google.com 3112854Sgabeblack@google.com Original Author: Ali Dasdan, Synopsys, Inc. 3212854Sgabeblack@google.com 3312854Sgabeblack@google.com *****************************************************************************/ 3412854Sgabeblack@google.com 3512854Sgabeblack@google.com/***************************************************************************** 3612854Sgabeblack@google.com 3712854Sgabeblack@google.com MODIFICATION LOG - modifiers, enter your name, affiliation, date and 3812854Sgabeblack@google.com changes you are making here. 3912854Sgabeblack@google.com 4012854Sgabeblack@google.com Name, Affiliation, Date: 4112854Sgabeblack@google.com Description of Modification: 4212854Sgabeblack@google.com 4312854Sgabeblack@google.com *****************************************************************************/ 4412854Sgabeblack@google.com 4512854Sgabeblack@google.com 4612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 4712854Sgabeblack@google.com// SECTION : Public members 4812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 4912854Sgabeblack@google.com 5012854Sgabeblack@google.com// Create a CLASS_TYPE number with nb bits. 5112854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(int nb) : 5212854Sgabeblack@google.com sc_value_base(), sgn(), nbits(), ndigits(), digit() 5312854Sgabeblack@google.com{ 5412854Sgabeblack@google.com sgn = default_sign(); 5512854Sgabeblack@google.com if (nb > 0) { 5612854Sgabeblack@google.com nbits = num_bits(nb); 5712854Sgabeblack@google.com } else { 5812854Sgabeblack@google.com invalid_init("int nb", nb); 5912854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 6012854Sgabeblack@google.com } 6112854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 6212854Sgabeblack@google.com#ifdef SC_MAX_NBITS 6312854Sgabeblack@google.com test_bound(nb); 6412854Sgabeblack@google.com#else 6512854Sgabeblack@google.com digit = new sc_digit[ndigits]; 6612854Sgabeblack@google.com#endif 6712854Sgabeblack@google.com makezero(); 6812854Sgabeblack@google.com} 6912854Sgabeblack@google.com 7012854Sgabeblack@google.com 7112854Sgabeblack@google.com// Create a copy of v with sgn s. v is of the same type. 7212854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const CLASS_TYPE &v) : 7312854Sgabeblack@google.com sc_value_base(v), sgn(v.sgn), nbits(v.nbits), ndigits(v.ndigits), digit() 7412854Sgabeblack@google.com{ 7512854Sgabeblack@google.com#ifndef SC_MAX_NBITS 7612854Sgabeblack@google.com digit = new sc_digit[ndigits]; 7712854Sgabeblack@google.com#endif 7812854Sgabeblack@google.com 7912854Sgabeblack@google.com vec_copy(ndigits, digit, v.digit); 8012854Sgabeblack@google.com} 8112854Sgabeblack@google.com 8212854Sgabeblack@google.com 8312854Sgabeblack@google.com// Create a copy of v where v is of the different type. 8412854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE &v) : 8512854Sgabeblack@google.com sc_value_base(v), sgn(v.sgn), nbits(num_bits(v.nbits)), ndigits(), digit() 8612854Sgabeblack@google.com{ 8712854Sgabeblack@google.com#if (IF_SC_SIGNED == 1) 8812854Sgabeblack@google.com ndigits = v.ndigits; 8912854Sgabeblack@google.com#else 9012854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 9112854Sgabeblack@google.com#endif 9212854Sgabeblack@google.com 9312854Sgabeblack@google.com#ifndef SC_MAX_NBITS 9412854Sgabeblack@google.com digit = new sc_digit[ndigits]; 9512854Sgabeblack@google.com#endif 9612854Sgabeblack@google.com 9712854Sgabeblack@google.com copy_digits(v.nbits, v.ndigits, v.digit); 9812854Sgabeblack@google.com} 9912854Sgabeblack@google.com 10012854Sgabeblack@google.com// Create a copy of v where v is an sign-less instance. 10112854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const sc_bv_base &v) : 10212854Sgabeblack@google.com sc_value_base(), sgn(), nbits(), ndigits(), digit() 10312854Sgabeblack@google.com{ 10412854Sgabeblack@google.com int nb = v.length(); 10512854Sgabeblack@google.com sgn = default_sign(); 10612854Sgabeblack@google.com if (nb > 0) { 10712854Sgabeblack@google.com nbits = num_bits(nb); 10812854Sgabeblack@google.com } else { 10912854Sgabeblack@google.com invalid_init("sc_bv_base", nb); 11012854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 11112854Sgabeblack@google.com } 11212854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 11312854Sgabeblack@google.com# ifdef SC_MAX_NBITS 11412854Sgabeblack@google.com test_bound(nb); 11512854Sgabeblack@google.com# else 11612854Sgabeblack@google.com digit = new sc_digit[ndigits]; 11712854Sgabeblack@google.com# endif 11812854Sgabeblack@google.com makezero(); 11912854Sgabeblack@google.com *this = v; 12012854Sgabeblack@google.com} 12112854Sgabeblack@google.com 12212854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const sc_lv_base &v) : 12312854Sgabeblack@google.com sc_value_base(), sgn(), nbits(), ndigits(), digit() 12412854Sgabeblack@google.com{ 12512854Sgabeblack@google.com int nb = v.length(); 12612854Sgabeblack@google.com sgn = default_sign(); 12712854Sgabeblack@google.com if (nb > 0) { 12812854Sgabeblack@google.com nbits = num_bits(nb); 12912854Sgabeblack@google.com } else { 13012854Sgabeblack@google.com invalid_init("sc_lv_base", nb); 13112854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 13212854Sgabeblack@google.com } 13312854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 13412854Sgabeblack@google.com# ifdef SC_MAX_NBITS 13512854Sgabeblack@google.com test_bound(nb); 13612854Sgabeblack@google.com# else 13712854Sgabeblack@google.com digit = new sc_digit[ndigits]; 13812854Sgabeblack@google.com# endif 13912854Sgabeblack@google.com makezero(); 14012854Sgabeblack@google.com *this = v; 14112854Sgabeblack@google.com} 14212854Sgabeblack@google.com 14312854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const sc_int_subref_r &v) : 14412854Sgabeblack@google.com sc_value_base(v), sgn(), nbits(), ndigits(), digit() 14512854Sgabeblack@google.com{ 14612854Sgabeblack@google.com int nb = v.length(); 14712854Sgabeblack@google.com sgn = default_sign(); 14812854Sgabeblack@google.com if (nb > 0) { 14912854Sgabeblack@google.com nbits = num_bits(nb); 15012854Sgabeblack@google.com } else { 15112854Sgabeblack@google.com invalid_init("sc_int_subref", nb); 15212854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 15312854Sgabeblack@google.com } 15412854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 15512854Sgabeblack@google.com# ifdef SC_MAX_NBITS 15612854Sgabeblack@google.com test_bound(nb); 15712854Sgabeblack@google.com# else 15812854Sgabeblack@google.com digit = new sc_digit[ndigits]; 15912854Sgabeblack@google.com# endif 16012854Sgabeblack@google.com makezero(); 16112854Sgabeblack@google.com *this = v.to_uint64(); 16212854Sgabeblack@google.com} 16312854Sgabeblack@google.com 16412854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const sc_uint_subref_r &v) : 16512854Sgabeblack@google.com sc_value_base(v), sgn(), nbits(), ndigits(), digit() 16612854Sgabeblack@google.com{ 16712854Sgabeblack@google.com int nb = v.length(); 16812854Sgabeblack@google.com sgn = default_sign(); 16912854Sgabeblack@google.com if (nb > 0) { 17012854Sgabeblack@google.com nbits = num_bits(nb); 17112854Sgabeblack@google.com } else { 17212854Sgabeblack@google.com invalid_init("sc_uint_subref", nb); 17312854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 17412854Sgabeblack@google.com } 17512854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 17612854Sgabeblack@google.com# ifdef SC_MAX_NBITS 17712854Sgabeblack@google.com test_bound(nb); 17812854Sgabeblack@google.com# else 17912854Sgabeblack@google.com digit = new sc_digit[ndigits]; 18012854Sgabeblack@google.com# endif 18112854Sgabeblack@google.com makezero(); 18212854Sgabeblack@google.com *this = v.to_uint64(); 18312854Sgabeblack@google.com} 18412854Sgabeblack@google.com 18512854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const sc_signed_subref_r &v) : 18612854Sgabeblack@google.com sc_value_base(v), sgn(), nbits(), ndigits(), digit() 18712854Sgabeblack@google.com{ 18812854Sgabeblack@google.com int nb = v.length(); 18912854Sgabeblack@google.com sgn = default_sign(); 19012854Sgabeblack@google.com if (nb > 0) { 19112854Sgabeblack@google.com nbits = num_bits(nb); 19212854Sgabeblack@google.com } else { 19312854Sgabeblack@google.com invalid_init("sc_signed_subref", nb); 19412854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 19512854Sgabeblack@google.com } 19612854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 19712854Sgabeblack@google.com# ifdef SC_MAX_NBITS 19812854Sgabeblack@google.com test_bound(nb); 19912854Sgabeblack@google.com# else 20012854Sgabeblack@google.com digit = new sc_digit[ndigits]; 20112854Sgabeblack@google.com# endif 20212854Sgabeblack@google.com makezero(); 20312854Sgabeblack@google.com *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right); 20412854Sgabeblack@google.com} 20512854Sgabeblack@google.com 20612854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const sc_unsigned_subref_r &v) : 20712854Sgabeblack@google.com sc_value_base(v), sgn(), nbits(), ndigits(), digit() 20812854Sgabeblack@google.com{ 20912854Sgabeblack@google.com int nb = v.length(); 21012854Sgabeblack@google.com sgn = default_sign(); 21112854Sgabeblack@google.com if (nb > 0) { 21212854Sgabeblack@google.com nbits = num_bits(nb); 21312854Sgabeblack@google.com } else { 21412854Sgabeblack@google.com invalid_init("sc_unsigned_subref", nb); 21512854Sgabeblack@google.com sc_core::sc_abort(); // can't recover from here 21612854Sgabeblack@google.com } 21712854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 21812854Sgabeblack@google.com# ifdef SC_MAX_NBITS 21912854Sgabeblack@google.com test_bound(nb); 22012854Sgabeblack@google.com# else 22112854Sgabeblack@google.com digit = new sc_digit[ndigits]; 22212854Sgabeblack@google.com# endif 22312854Sgabeblack@google.com makezero(); 22412854Sgabeblack@google.com *this = sc_unsigned(v.m_obj_p, v.m_left, v.m_right); 22512854Sgabeblack@google.com} 22612854Sgabeblack@google.com 22712854Sgabeblack@google.com// ---------------------------------------------------------------------------- 22812854Sgabeblack@google.com// SECTION: Public members - Concatenation support. 22912854Sgabeblack@google.com// ---------------------------------------------------------------------------- 23012854Sgabeblack@google.com 23112854Sgabeblack@google.com 23212854Sgabeblack@google.com// ---------------------------------------------------------------------------- 23312854Sgabeblack@google.com// SECTION: Public members - Assignment operators. 23412854Sgabeblack@google.com// ---------------------------------------------------------------------------- 23512854Sgabeblack@google.com 23612854Sgabeblack@google.com// Assignment from v of the same type. 23712854Sgabeblack@google.comconst CLASS_TYPE & 23812854Sgabeblack@google.comCLASS_TYPE::operator = (const CLASS_TYPE &v) 23912854Sgabeblack@google.com{ 24012854Sgabeblack@google.com if (this != &v) { 24112854Sgabeblack@google.com sgn = v.sgn; 24212854Sgabeblack@google.com 24312854Sgabeblack@google.com if (sgn == SC_ZERO) 24412854Sgabeblack@google.com vec_zero(ndigits, digit); 24512854Sgabeblack@google.com else 24612854Sgabeblack@google.com copy_digits(v.nbits, v.ndigits, v.digit); 24712854Sgabeblack@google.com } 24812854Sgabeblack@google.com return *this; 24912854Sgabeblack@google.com} 25012854Sgabeblack@google.com 25112854Sgabeblack@google.com 25212854Sgabeblack@google.com// Assignment from v of the different type. 25312854Sgabeblack@google.comconst CLASS_TYPE & 25412854Sgabeblack@google.comCLASS_TYPE::operator = (const OTHER_CLASS_TYPE &v) 25512854Sgabeblack@google.com{ 25612854Sgabeblack@google.com sgn = v.sgn; 25712854Sgabeblack@google.com 25812854Sgabeblack@google.com if (sgn == SC_ZERO) 25912854Sgabeblack@google.com vec_zero(ndigits, digit); 26012854Sgabeblack@google.com else 26112854Sgabeblack@google.com copy_digits(v.nbits, v.ndigits, v.digit); 26212854Sgabeblack@google.com 26312854Sgabeblack@google.com return *this; 26412854Sgabeblack@google.com} 26512854Sgabeblack@google.com 26612854Sgabeblack@google.com 26712854Sgabeblack@google.com// Assignment from an sc_unsigned_subref_r 26812854Sgabeblack@google.comconst CLASS_TYPE & 26912854Sgabeblack@google.comCLASS_TYPE::operator = (const sc_unsigned_subref_r &v) 27012854Sgabeblack@google.com{ 27112854Sgabeblack@google.com return operator=(sc_unsigned(v)); 27212854Sgabeblack@google.com} 27312854Sgabeblack@google.com 27412854Sgabeblack@google.com 27512854Sgabeblack@google.com// Assignment from an sc_signed_subref_r 27612854Sgabeblack@google.comconst CLASS_TYPE & 27712854Sgabeblack@google.comCLASS_TYPE::operator = (const sc_signed_subref_r &v) 27812854Sgabeblack@google.com{ 27912854Sgabeblack@google.com return operator = (sc_unsigned(v)); 28012854Sgabeblack@google.com} 28112854Sgabeblack@google.com 28212854Sgabeblack@google.com 28312854Sgabeblack@google.com// ---------------------------------------------------------------------------- 28412854Sgabeblack@google.com// SECTION: Input and output operators 28512854Sgabeblack@google.com// ---------------------------------------------------------------------------- 28612854Sgabeblack@google.com 28712854Sgabeblack@google.comvoid 28812854Sgabeblack@google.comCLASS_TYPE::scan(::std::istream &is) 28912854Sgabeblack@google.com{ 29012854Sgabeblack@google.com std::string s; 29112854Sgabeblack@google.com is >> s; 29212854Sgabeblack@google.com *this = s.c_str(); 29312854Sgabeblack@google.com} 29412854Sgabeblack@google.com 29512854Sgabeblack@google.com 29612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 29712854Sgabeblack@google.com// SECTION: PLUS operators: +, +=, ++ 29812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 29912854Sgabeblack@google.com 30012854Sgabeblack@google.com// Cases to consider when computing u + v: 30112854Sgabeblack@google.com// 1. 0 + v = v 30212854Sgabeblack@google.com// 2. u + 0 = u 30312854Sgabeblack@google.com// 3. if sgn(u) == sgn(v) 30412854Sgabeblack@google.com// 3.1 u + v = +(u + v) = sgn(u) * (u + v) 30512854Sgabeblack@google.com// 3.2 (-u) + (-v) = -(u + v) = sgn(u) * (u + v) 30612854Sgabeblack@google.com// 4. if sgn(u) != sgn(v) 30712854Sgabeblack@google.com// 4.1 u + (-v) = u - v = sgn(u) * (u - v) 30812854Sgabeblack@google.com// 4.2 (-u) + v = -(u - v) ==> sgn(u) * (u - v) 30912854Sgabeblack@google.com// 31012854Sgabeblack@google.com// Specialization of above cases for computing ++u or u++: 31112854Sgabeblack@google.com// 1. 0 + 1 = 1 31212854Sgabeblack@google.com// 3. u + 1 = u + 1 = sgn(u) * (u + 1) 31312854Sgabeblack@google.com// 4. (-u) + 1 = -(u - 1) = sgn(u) * (u - 1) 31412854Sgabeblack@google.com 31512854Sgabeblack@google.comconst CLASS_TYPE & 31612854Sgabeblack@google.comCLASS_TYPE::operator += (const CLASS_TYPE &v) 31712854Sgabeblack@google.com{ 31812854Sgabeblack@google.com // u = *this 31912854Sgabeblack@google.com 32012854Sgabeblack@google.com if (sgn == SC_ZERO) // case 1 32112854Sgabeblack@google.com return (*this = v); 32212854Sgabeblack@google.com 32312854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 2 32412854Sgabeblack@google.com return *this; 32512854Sgabeblack@google.com 32612854Sgabeblack@google.com // cases 3 and 4 32712854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 32812854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 32912854Sgabeblack@google.com 33012854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 33112854Sgabeblack@google.com 33212854Sgabeblack@google.com return *this; 33312854Sgabeblack@google.com} 33412854Sgabeblack@google.com 33512854Sgabeblack@google.com 33612854Sgabeblack@google.comconst CLASS_TYPE & 33712854Sgabeblack@google.comCLASS_TYPE::operator += (const OTHER_CLASS_TYPE &v) 33812854Sgabeblack@google.com{ 33912854Sgabeblack@google.com // u = *this 34012854Sgabeblack@google.com 34112854Sgabeblack@google.com if (sgn == SC_ZERO) // case 1 34212854Sgabeblack@google.com return (*this = v); 34312854Sgabeblack@google.com 34412854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 2 34512854Sgabeblack@google.com return *this; 34612854Sgabeblack@google.com 34712854Sgabeblack@google.com // cases 3 and 4 34812854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 34912854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 35012854Sgabeblack@google.com 35112854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 35212854Sgabeblack@google.com 35312854Sgabeblack@google.com return *this; 35412854Sgabeblack@google.com} 35512854Sgabeblack@google.com 35612854Sgabeblack@google.com 35712854Sgabeblack@google.comCLASS_TYPE & 35812854Sgabeblack@google.comCLASS_TYPE::operator ++ () // prefix 35912854Sgabeblack@google.com{ 36012854Sgabeblack@google.com *this = *this + 1; 36112854Sgabeblack@google.com return *this; 36212854Sgabeblack@google.com} 36312854Sgabeblack@google.com 36412854Sgabeblack@google.com 36512854Sgabeblack@google.comconst CLASS_TYPE 36612854Sgabeblack@google.comCLASS_TYPE::operator ++ (int) // postfix 36712854Sgabeblack@google.com{ 36812854Sgabeblack@google.com // Copy digit into d. 36912854Sgabeblack@google.com 37012854Sgabeblack@google.com#ifdef SC_MAX_NBITS 37112854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 37212854Sgabeblack@google.com#else 37312854Sgabeblack@google.com sc_digit *d = new sc_digit[ndigits]; 37412854Sgabeblack@google.com#endif 37512854Sgabeblack@google.com 37612854Sgabeblack@google.com small_type s = sgn; 37712854Sgabeblack@google.com 37812854Sgabeblack@google.com vec_copy(ndigits, d, digit); 37912854Sgabeblack@google.com 38012854Sgabeblack@google.com *this = *this + 1; 38112854Sgabeblack@google.com 38212854Sgabeblack@google.com return CLASS_TYPE(s, nbits, ndigits, d); 38312854Sgabeblack@google.com} 38412854Sgabeblack@google.com 38512854Sgabeblack@google.com 38612854Sgabeblack@google.comconst CLASS_TYPE & 38712854Sgabeblack@google.comCLASS_TYPE::operator += (int64 v) 38812854Sgabeblack@google.com{ 38912854Sgabeblack@google.com // u = *this 39012854Sgabeblack@google.com 39112854Sgabeblack@google.com if (sgn == SC_ZERO) // case 1 39212854Sgabeblack@google.com return (*this = v); 39312854Sgabeblack@google.com 39412854Sgabeblack@google.com if (v == 0) // case 2 39512854Sgabeblack@google.com return *this; 39612854Sgabeblack@google.com 39712854Sgabeblack@google.com CONVERT_INT64(v); 39812854Sgabeblack@google.com 39912854Sgabeblack@google.com // cases 3 and 4 40012854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 40112854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 40212854Sgabeblack@google.com 40312854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 40412854Sgabeblack@google.com 40512854Sgabeblack@google.com return *this; 40612854Sgabeblack@google.com} 40712854Sgabeblack@google.com 40812854Sgabeblack@google.com 40912854Sgabeblack@google.comconst CLASS_TYPE & 41012854Sgabeblack@google.comCLASS_TYPE::operator += (uint64 v) 41112854Sgabeblack@google.com{ 41212854Sgabeblack@google.com // u = *this 41312854Sgabeblack@google.com 41412854Sgabeblack@google.com if (sgn == SC_ZERO) // case 1 41512854Sgabeblack@google.com return (*this = v); 41612854Sgabeblack@google.com 41712854Sgabeblack@google.com if (v == 0) // case 2 41812854Sgabeblack@google.com return *this; 41912854Sgabeblack@google.com 42012854Sgabeblack@google.com CONVERT_INT64(v); 42112854Sgabeblack@google.com 42212854Sgabeblack@google.com // cases 3 and 4 42312854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 42412854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 42512854Sgabeblack@google.com 42612854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 42712854Sgabeblack@google.com 42812854Sgabeblack@google.com return *this; 42912854Sgabeblack@google.com} 43012854Sgabeblack@google.com 43112854Sgabeblack@google.com 43212854Sgabeblack@google.comconst CLASS_TYPE & 43312854Sgabeblack@google.comCLASS_TYPE::operator += (long v) 43412854Sgabeblack@google.com{ 43512854Sgabeblack@google.com // u = *this 43612854Sgabeblack@google.com 43712854Sgabeblack@google.com if (sgn == SC_ZERO) // case 1 43812854Sgabeblack@google.com return (*this = v); 43912854Sgabeblack@google.com 44012854Sgabeblack@google.com if (v == 0) // case 2 44112854Sgabeblack@google.com return *this; 44212854Sgabeblack@google.com 44312854Sgabeblack@google.com CONVERT_LONG(v); 44412854Sgabeblack@google.com 44512854Sgabeblack@google.com // cases 3 and 4 44612854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 44712854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 44812854Sgabeblack@google.com 44912854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 45012854Sgabeblack@google.com 45112854Sgabeblack@google.com return *this; 45212854Sgabeblack@google.com} 45312854Sgabeblack@google.com 45412854Sgabeblack@google.com 45512854Sgabeblack@google.comconst CLASS_TYPE & 45612854Sgabeblack@google.comCLASS_TYPE::operator += (unsigned long v) 45712854Sgabeblack@google.com{ 45812854Sgabeblack@google.com // u = *this 45912854Sgabeblack@google.com 46012854Sgabeblack@google.com if (sgn == SC_ZERO) // case 1 46112854Sgabeblack@google.com return (*this = v); 46212854Sgabeblack@google.com 46312854Sgabeblack@google.com if (v == 0) // case 2 46412854Sgabeblack@google.com return *this; 46512854Sgabeblack@google.com 46612854Sgabeblack@google.com CONVERT_LONG(v); 46712854Sgabeblack@google.com 46812854Sgabeblack@google.com // cases 3 and 4 46912854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 47012854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 47112854Sgabeblack@google.com 47212854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 47312854Sgabeblack@google.com 47412854Sgabeblack@google.com return *this; 47512854Sgabeblack@google.com} 47612854Sgabeblack@google.com 47712854Sgabeblack@google.com 47812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 47912854Sgabeblack@google.com// SECTION: MINUS operators: -, -=, -- 48012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 48112854Sgabeblack@google.com 48212854Sgabeblack@google.com// Cases to consider when computing u + v: 48312854Sgabeblack@google.com// 1. u - 0 = u 48412854Sgabeblack@google.com// 2. 0 - v = -v 48512854Sgabeblack@google.com// 3. if sgn(u) != sgn(v) 48612854Sgabeblack@google.com// 3.1 u - (-v) = u + v = sgn(u) * (u + v) 48712854Sgabeblack@google.com// 3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v) 48812854Sgabeblack@google.com// 4. if sgn(u) == sgn(v) 48912854Sgabeblack@google.com// 4.1 u - v = +(u - v) = sgn(u) * (u - v) 49012854Sgabeblack@google.com// 4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v) 49112854Sgabeblack@google.com// 49212854Sgabeblack@google.com// Specialization of above cases for computing --u or u--: 49312854Sgabeblack@google.com// 1. 0 - 1 = -1 49412854Sgabeblack@google.com// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1) 49512854Sgabeblack@google.com// 4. u - 1 = u - 1 = sgn(u) * (u - 1) 49612854Sgabeblack@google.com 49712854Sgabeblack@google.comconst CLASS_TYPE & 49812854Sgabeblack@google.comCLASS_TYPE::operator -= (const CLASS_TYPE &v) 49912854Sgabeblack@google.com{ 50012854Sgabeblack@google.com // u = *this 50112854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 1 50212854Sgabeblack@google.com return *this; 50312854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 2 50412854Sgabeblack@google.com sgn = -v.sgn; 50512854Sgabeblack@google.com copy_digits(v.nbits, v.ndigits, v.digit); 50612854Sgabeblack@google.com } else { 50712854Sgabeblack@google.com // cases 3 and 4 50812854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 50912854Sgabeblack@google.com -v.sgn, v.nbits, v.ndigits, v.digit); 51012854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 51112854Sgabeblack@google.com } 51212854Sgabeblack@google.com 51312854Sgabeblack@google.com return *this; 51412854Sgabeblack@google.com} 51512854Sgabeblack@google.com 51612854Sgabeblack@google.com 51712854Sgabeblack@google.comconst CLASS_TYPE & 51812854Sgabeblack@google.comCLASS_TYPE::operator -= (const OTHER_CLASS_TYPE &v) 51912854Sgabeblack@google.com{ 52012854Sgabeblack@google.com // u = *this 52112854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 1 52212854Sgabeblack@google.com return *this; 52312854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 2 52412854Sgabeblack@google.com sgn = -v.sgn; 52512854Sgabeblack@google.com copy_digits(v.nbits, v.ndigits, v.digit); 52612854Sgabeblack@google.com } else { 52712854Sgabeblack@google.com // cases 3 and 4 52812854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 52912854Sgabeblack@google.com -v.sgn, v.nbits, v.ndigits, v.digit); 53012854Sgabeblack@google.com 53112854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 53212854Sgabeblack@google.com } 53312854Sgabeblack@google.com return *this; 53412854Sgabeblack@google.com} 53512854Sgabeblack@google.com 53612854Sgabeblack@google.comCLASS_TYPE & 53712854Sgabeblack@google.comCLASS_TYPE::operator -- () // prefix 53812854Sgabeblack@google.com{ 53912854Sgabeblack@google.com *this = *this - 1; 54012854Sgabeblack@google.com return *this; 54112854Sgabeblack@google.com} 54212854Sgabeblack@google.com 54312854Sgabeblack@google.comconst CLASS_TYPE 54412854Sgabeblack@google.comCLASS_TYPE::operator -- (int) // postfix 54512854Sgabeblack@google.com{ 54612854Sgabeblack@google.com // Copy digit into d. 54712854Sgabeblack@google.com#ifdef SC_MAX_NBITS 54812854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 54912854Sgabeblack@google.com#else 55012854Sgabeblack@google.com sc_digit *d = new sc_digit[ndigits]; 55112854Sgabeblack@google.com#endif 55212854Sgabeblack@google.com small_type s = sgn; 55312854Sgabeblack@google.com vec_copy(ndigits, d, digit); 55412854Sgabeblack@google.com *this = *this - 1; 55512854Sgabeblack@google.com return CLASS_TYPE(s, nbits, ndigits, d); 55612854Sgabeblack@google.com} 55712854Sgabeblack@google.com 55812854Sgabeblack@google.com 55912854Sgabeblack@google.comconst CLASS_TYPE & 56012854Sgabeblack@google.comCLASS_TYPE::operator -= (int64 v) 56112854Sgabeblack@google.com{ 56212854Sgabeblack@google.com // u = *this 56312854Sgabeblack@google.com if (v == 0) // case 1 56412854Sgabeblack@google.com return *this; 56512854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 56612854Sgabeblack@google.com return (*this = -v); 56712854Sgabeblack@google.com 56812854Sgabeblack@google.com CONVERT_INT64(v); 56912854Sgabeblack@google.com 57012854Sgabeblack@google.com // cases 3 and 4 57112854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 57212854Sgabeblack@google.com -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 57312854Sgabeblack@google.com 57412854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 57512854Sgabeblack@google.com 57612854Sgabeblack@google.com return *this; 57712854Sgabeblack@google.com} 57812854Sgabeblack@google.com 57912854Sgabeblack@google.com 58012854Sgabeblack@google.comconst CLASS_TYPE & 58112854Sgabeblack@google.comCLASS_TYPE::operator -= (uint64 v) 58212854Sgabeblack@google.com{ 58312854Sgabeblack@google.com // u = *this 58412854Sgabeblack@google.com 58512854Sgabeblack@google.com if (v == 0) // case 1 58612854Sgabeblack@google.com return *this; 58712854Sgabeblack@google.com 58812854Sgabeblack@google.com int64 v2 = (int64) v; 58912854Sgabeblack@google.com 59012854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 59112854Sgabeblack@google.com return (*this = -v2); 59212854Sgabeblack@google.com 59312854Sgabeblack@google.com CONVERT_INT64(v); 59412854Sgabeblack@google.com 59512854Sgabeblack@google.com // cases 3 and 4 59612854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 59712854Sgabeblack@google.com -vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 59812854Sgabeblack@google.com 59912854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 60012854Sgabeblack@google.com 60112854Sgabeblack@google.com return *this; 60212854Sgabeblack@google.com} 60312854Sgabeblack@google.com 60412854Sgabeblack@google.comconst CLASS_TYPE & 60512854Sgabeblack@google.comCLASS_TYPE::operator -= (long v) 60612854Sgabeblack@google.com{ 60712854Sgabeblack@google.com // u = *this 60812854Sgabeblack@google.com 60912854Sgabeblack@google.com if (v == 0) // case 1 61012854Sgabeblack@google.com return *this; 61112854Sgabeblack@google.com 61212854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 61312854Sgabeblack@google.com return (*this = -v); 61412854Sgabeblack@google.com 61512854Sgabeblack@google.com CONVERT_LONG(v); 61612854Sgabeblack@google.com 61712854Sgabeblack@google.com // cases 3 and 4 61812854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 61912854Sgabeblack@google.com -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 62012854Sgabeblack@google.com 62112854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 62212854Sgabeblack@google.com 62312854Sgabeblack@google.com return *this; 62412854Sgabeblack@google.com} 62512854Sgabeblack@google.com 62612854Sgabeblack@google.com 62712854Sgabeblack@google.comconst CLASS_TYPE & 62812854Sgabeblack@google.comCLASS_TYPE::operator -= (unsigned long v) 62912854Sgabeblack@google.com{ 63012854Sgabeblack@google.com // u = *this 63112854Sgabeblack@google.com 63212854Sgabeblack@google.com if (v == 0) // case 1 63312854Sgabeblack@google.com return *this; 63412854Sgabeblack@google.com 63512854Sgabeblack@google.com long v2 = (long) v; 63612854Sgabeblack@google.com 63712854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 63812854Sgabeblack@google.com return (*this = -v2); 63912854Sgabeblack@google.com 64012854Sgabeblack@google.com CONVERT_LONG(v); 64112854Sgabeblack@google.com 64212854Sgabeblack@google.com // cases 3 and 4 64312854Sgabeblack@google.com add_on_help(sgn, nbits, ndigits, digit, 64412854Sgabeblack@google.com -vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 64512854Sgabeblack@google.com 64612854Sgabeblack@google.com convert_SM_to_2C_to_SM(); 64712854Sgabeblack@google.com 64812854Sgabeblack@google.com return *this; 64912854Sgabeblack@google.com} 65012854Sgabeblack@google.com 65112854Sgabeblack@google.com 65212854Sgabeblack@google.com// ---------------------------------------------------------------------------- 65312854Sgabeblack@google.com// SECTION: MULTIPLICATION operators: *, *= 65412854Sgabeblack@google.com// ---------------------------------------------------------------------------- 65512854Sgabeblack@google.com 65612854Sgabeblack@google.com// Cases to consider when computing u * v: 65712854Sgabeblack@google.com// 1. u * 0 = 0 * v = 0 65812854Sgabeblack@google.com// 2. 1 * v = v and -1 * v = -v 65912854Sgabeblack@google.com// 3. u * 1 = u and u * -1 = -u 66012854Sgabeblack@google.com// 4. u * v = u * v 66112854Sgabeblack@google.com 66212854Sgabeblack@google.comconst CLASS_TYPE & 66312854Sgabeblack@google.comCLASS_TYPE::operator *= (const CLASS_TYPE &v) 66412854Sgabeblack@google.com{ 66512854Sgabeblack@google.com // u = *this 66612854Sgabeblack@google.com 66712854Sgabeblack@google.com sgn = mul_signs(sgn, v.sgn); 66812854Sgabeblack@google.com 66912854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 1 67012854Sgabeblack@google.com vec_zero(ndigits, digit); 67112854Sgabeblack@google.com } else { 67212854Sgabeblack@google.com // cases 2-4 67312854Sgabeblack@google.com MUL_ON_HELPER(sgn, nbits, ndigits, digit, 67412854Sgabeblack@google.com v.nbits, v.ndigits, v.digit); 67512854Sgabeblack@google.com } 67612854Sgabeblack@google.com 67712854Sgabeblack@google.com return *this; 67812854Sgabeblack@google.com} 67912854Sgabeblack@google.com 68012854Sgabeblack@google.com 68112854Sgabeblack@google.comconst CLASS_TYPE & 68212854Sgabeblack@google.comCLASS_TYPE::operator *= (const OTHER_CLASS_TYPE &v) 68312854Sgabeblack@google.com{ 68412854Sgabeblack@google.com // u = *this 68512854Sgabeblack@google.com 68612854Sgabeblack@google.com sgn = mul_signs(sgn, v.sgn); 68712854Sgabeblack@google.com 68812854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 1 68912854Sgabeblack@google.com vec_zero(ndigits, digit); 69012854Sgabeblack@google.com } else { 69112854Sgabeblack@google.com // cases 2-4 69212854Sgabeblack@google.com MUL_ON_HELPER(sgn, nbits, ndigits, digit, 69312854Sgabeblack@google.com v.nbits, v.ndigits, v.digit); 69412854Sgabeblack@google.com } 69512854Sgabeblack@google.com 69612854Sgabeblack@google.com return *this; 69712854Sgabeblack@google.com} 69812854Sgabeblack@google.com 69912854Sgabeblack@google.com 70012854Sgabeblack@google.comconst CLASS_TYPE & 70112854Sgabeblack@google.comCLASS_TYPE::operator *= (int64 v) 70212854Sgabeblack@google.com{ 70312854Sgabeblack@google.com // u = *this 70412854Sgabeblack@google.com 70512854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 70612854Sgabeblack@google.com 70712854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 1 70812854Sgabeblack@google.com vec_zero(ndigits, digit); 70912854Sgabeblack@google.com } else { // cases 2-4 71012854Sgabeblack@google.com CONVERT_INT64_2(v); 71112854Sgabeblack@google.com MUL_ON_HELPER(sgn, nbits, ndigits, digit, 71212854Sgabeblack@google.com BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 71312854Sgabeblack@google.com } 71412854Sgabeblack@google.com 71512854Sgabeblack@google.com return *this; 71612854Sgabeblack@google.com} 71712854Sgabeblack@google.com 71812854Sgabeblack@google.com 71912854Sgabeblack@google.comconst CLASS_TYPE & 72012854Sgabeblack@google.comCLASS_TYPE::operator *= (uint64 v) 72112854Sgabeblack@google.com{ 72212854Sgabeblack@google.com // u = *this 72312854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 72412854Sgabeblack@google.com 72512854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 1 72612854Sgabeblack@google.com vec_zero(ndigits, digit); 72712854Sgabeblack@google.com } else { // cases 2-4 72812854Sgabeblack@google.com CONVERT_INT64_2(v); 72912854Sgabeblack@google.com MUL_ON_HELPER(sgn, nbits, ndigits, digit, 73012854Sgabeblack@google.com BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 73112854Sgabeblack@google.com } 73212854Sgabeblack@google.com 73312854Sgabeblack@google.com return *this; 73412854Sgabeblack@google.com} 73512854Sgabeblack@google.com 73612854Sgabeblack@google.com 73712854Sgabeblack@google.comconst CLASS_TYPE & 73812854Sgabeblack@google.comCLASS_TYPE::operator *= (long v) 73912854Sgabeblack@google.com{ 74012854Sgabeblack@google.com // u = *this 74112854Sgabeblack@google.com 74212854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 74312854Sgabeblack@google.com 74412854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 1 74512854Sgabeblack@google.com vec_zero(ndigits, digit); 74612854Sgabeblack@google.com } else { // cases 2-4 74712854Sgabeblack@google.com CONVERT_LONG_2(v); 74812854Sgabeblack@google.com MUL_ON_HELPER(sgn, nbits, ndigits, digit, 74912854Sgabeblack@google.com BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 75012854Sgabeblack@google.com } 75112854Sgabeblack@google.com return *this; 75212854Sgabeblack@google.com} 75312854Sgabeblack@google.com 75412854Sgabeblack@google.com 75512854Sgabeblack@google.comconst CLASS_TYPE & 75612854Sgabeblack@google.comCLASS_TYPE::operator *= (unsigned long v) 75712854Sgabeblack@google.com{ 75812854Sgabeblack@google.com // u = *this 75912854Sgabeblack@google.com 76012854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 76112854Sgabeblack@google.com 76212854Sgabeblack@google.com if (sgn == SC_ZERO) { // case 1 76312854Sgabeblack@google.com vec_zero(ndigits, digit); 76412854Sgabeblack@google.com } else { // cases 2-4 76512854Sgabeblack@google.com CONVERT_LONG_2(v); 76612854Sgabeblack@google.com MUL_ON_HELPER(sgn, nbits, ndigits, digit, 76712854Sgabeblack@google.com BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 76812854Sgabeblack@google.com } 76912854Sgabeblack@google.com 77012854Sgabeblack@google.com return *this; 77112854Sgabeblack@google.com} 77212854Sgabeblack@google.com 77312854Sgabeblack@google.com 77412854Sgabeblack@google.com// ---------------------------------------------------------------------------- 77512854Sgabeblack@google.com// SECTION: DIVISION operators: /, /= 77612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 77712854Sgabeblack@google.com 77812854Sgabeblack@google.com// Cases to consider when finding the quotient q = floor(u/v): 77912854Sgabeblack@google.com// Note that u = q * v + r for r < q. 78012854Sgabeblack@google.com// 1. 0 / 0 or u / 0 => error 78112854Sgabeblack@google.com// 2. 0 / v => 0 = 0 * v + 0 78212854Sgabeblack@google.com// 3. u / v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 78312854Sgabeblack@google.com// 4. u / v && u < v => u = 0 * v + u - u can be 1 or -1 78412854Sgabeblack@google.com// 5. u / v && u > v => u = q * v + r - v can be 1 or -1 78512854Sgabeblack@google.com 78612854Sgabeblack@google.comconst CLASS_TYPE & 78712854Sgabeblack@google.comCLASS_TYPE::operator /= (const CLASS_TYPE &v) 78812854Sgabeblack@google.com{ 78912854Sgabeblack@google.com sgn = mul_signs(sgn, v.sgn); 79012854Sgabeblack@google.com 79112854Sgabeblack@google.com if (sgn == SC_ZERO) { 79212854Sgabeblack@google.com div_by_zero(v.sgn); // case 1 79312854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 79412854Sgabeblack@google.com } else { // other cases 79512854Sgabeblack@google.com DIV_ON_HELPER(sgn, nbits, ndigits, digit, 79612854Sgabeblack@google.com v.nbits, v.ndigits, v.digit); 79712854Sgabeblack@google.com } 79812854Sgabeblack@google.com return *this; 79912854Sgabeblack@google.com} 80012854Sgabeblack@google.com 80112854Sgabeblack@google.com 80212854Sgabeblack@google.comconst CLASS_TYPE & 80312854Sgabeblack@google.comCLASS_TYPE::operator /= (const OTHER_CLASS_TYPE &v) 80412854Sgabeblack@google.com{ 80512854Sgabeblack@google.com sgn = mul_signs(sgn, v.sgn); 80612854Sgabeblack@google.com 80712854Sgabeblack@google.com if (sgn == SC_ZERO) { 80812854Sgabeblack@google.com div_by_zero(v.sgn); // case 1 80912854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 81012854Sgabeblack@google.com } else { // other cases 81112854Sgabeblack@google.com DIV_ON_HELPER(sgn, nbits, ndigits, digit, 81212854Sgabeblack@google.com v.nbits, v.ndigits, v.digit); 81312854Sgabeblack@google.com } 81412854Sgabeblack@google.com return *this; 81512854Sgabeblack@google.com} 81612854Sgabeblack@google.com 81712854Sgabeblack@google.com 81812854Sgabeblack@google.comconst CLASS_TYPE & 81912854Sgabeblack@google.comCLASS_TYPE::operator /= (int64 v) 82012854Sgabeblack@google.com{ 82112854Sgabeblack@google.com // u = *this 82212854Sgabeblack@google.com 82312854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 82412854Sgabeblack@google.com 82512854Sgabeblack@google.com if (sgn == SC_ZERO) { 82612854Sgabeblack@google.com div_by_zero(v); // case 1 82712854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 82812854Sgabeblack@google.com } else { 82912854Sgabeblack@google.com CONVERT_INT64_2(v); 83012854Sgabeblack@google.com // other cases 83112854Sgabeblack@google.com DIV_ON_HELPER(sgn, nbits, ndigits, digit, 83212854Sgabeblack@google.com BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 83312854Sgabeblack@google.com } 83412854Sgabeblack@google.com return *this; 83512854Sgabeblack@google.com} 83612854Sgabeblack@google.com 83712854Sgabeblack@google.com 83812854Sgabeblack@google.comconst CLASS_TYPE & 83912854Sgabeblack@google.comCLASS_TYPE::operator /= (uint64 v) 84012854Sgabeblack@google.com{ 84112854Sgabeblack@google.com // u = *this 84212854Sgabeblack@google.com 84312854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 84412854Sgabeblack@google.com 84512854Sgabeblack@google.com if (sgn == SC_ZERO) { 84612854Sgabeblack@google.com div_by_zero(v); // case 1 84712854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 84812854Sgabeblack@google.com } else { 84912854Sgabeblack@google.com CONVERT_INT64_2(v); 85012854Sgabeblack@google.com // other cases 85112854Sgabeblack@google.com DIV_ON_HELPER(sgn, nbits, ndigits, digit, 85212854Sgabeblack@google.com BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 85312854Sgabeblack@google.com } 85412854Sgabeblack@google.com return *this; 85512854Sgabeblack@google.com} 85612854Sgabeblack@google.com 85712854Sgabeblack@google.com 85812854Sgabeblack@google.comconst CLASS_TYPE & 85912854Sgabeblack@google.comCLASS_TYPE::operator /= (long v) 86012854Sgabeblack@google.com{ 86112854Sgabeblack@google.com // u = *this 86212854Sgabeblack@google.com 86312854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 86412854Sgabeblack@google.com 86512854Sgabeblack@google.com if (sgn == SC_ZERO) { 86612854Sgabeblack@google.com div_by_zero(v); // case 1 86712854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 86812854Sgabeblack@google.com } else { 86912854Sgabeblack@google.com CONVERT_LONG_2(v); 87012854Sgabeblack@google.com // other cases 87112854Sgabeblack@google.com DIV_ON_HELPER(sgn, nbits, ndigits, digit, 87212854Sgabeblack@google.com BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 87312854Sgabeblack@google.com } 87412854Sgabeblack@google.com return *this; 87512854Sgabeblack@google.com} 87612854Sgabeblack@google.com 87712854Sgabeblack@google.com 87812854Sgabeblack@google.comconst CLASS_TYPE & 87912854Sgabeblack@google.comCLASS_TYPE::operator /= (unsigned long v) 88012854Sgabeblack@google.com{ 88112854Sgabeblack@google.com // u = *this 88212854Sgabeblack@google.com 88312854Sgabeblack@google.com sgn = mul_signs(sgn, get_sign(v)); 88412854Sgabeblack@google.com 88512854Sgabeblack@google.com if (sgn == SC_ZERO) { 88612854Sgabeblack@google.com div_by_zero(v); // case 1 88712854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 88812854Sgabeblack@google.com } else { 88912854Sgabeblack@google.com CONVERT_LONG_2(v); 89012854Sgabeblack@google.com // other cases 89112854Sgabeblack@google.com DIV_ON_HELPER(sgn, nbits, ndigits, digit, 89212854Sgabeblack@google.com BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 89312854Sgabeblack@google.com } 89412854Sgabeblack@google.com return *this; 89512854Sgabeblack@google.com} 89612854Sgabeblack@google.com 89712854Sgabeblack@google.com 89812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 89912854Sgabeblack@google.com// SECTION: MOD operators: %, %=. 90012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 90112854Sgabeblack@google.com 90212854Sgabeblack@google.com// Cases to consider when finding the remainder r = u % v: 90312854Sgabeblack@google.com// Note that u = q * v + r for r < q. 90412854Sgabeblack@google.com// 1. 0 % 0 or u % 0 => error 90512854Sgabeblack@google.com// 2. 0 % v => 0 = 0 * v + 0 90612854Sgabeblack@google.com// 3. u % v && u = v => u = 1 * u + 0 - u or v can be 1 or -1 90712854Sgabeblack@google.com// 4. u % v && u < v => u = 0 * v + u - u can be 1 or -1 90812854Sgabeblack@google.com// 5. u % v && u > v => u = q * v + r - v can be 1 or -1 90912854Sgabeblack@google.com 91012854Sgabeblack@google.comconst CLASS_TYPE & 91112854Sgabeblack@google.comCLASS_TYPE::operator %= (const CLASS_TYPE &v) 91212854Sgabeblack@google.com{ 91312854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { 91412854Sgabeblack@google.com div_by_zero(v.sgn); // case 1 91512854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 91612854Sgabeblack@google.com } else { // other cases 91712854Sgabeblack@google.com MOD_ON_HELPER(sgn, nbits, ndigits, digit, 91812854Sgabeblack@google.com v.nbits, v.ndigits, v.digit); 91912854Sgabeblack@google.com } 92012854Sgabeblack@google.com return *this; 92112854Sgabeblack@google.com} 92212854Sgabeblack@google.com 92312854Sgabeblack@google.com 92412854Sgabeblack@google.comconst CLASS_TYPE & 92512854Sgabeblack@google.comCLASS_TYPE::operator %= (const OTHER_CLASS_TYPE &v) 92612854Sgabeblack@google.com{ 92712854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { 92812854Sgabeblack@google.com div_by_zero(v.sgn); // case 1 92912854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 93012854Sgabeblack@google.com } else { // other cases 93112854Sgabeblack@google.com MOD_ON_HELPER(sgn, nbits, ndigits, digit, 93212854Sgabeblack@google.com v.nbits, v.ndigits, v.digit); 93312854Sgabeblack@google.com } 93412854Sgabeblack@google.com 93512854Sgabeblack@google.com return *this; 93612854Sgabeblack@google.com} 93712854Sgabeblack@google.com 93812854Sgabeblack@google.com 93912854Sgabeblack@google.comconst CLASS_TYPE & 94012854Sgabeblack@google.comCLASS_TYPE::operator %= (int64 v) 94112854Sgabeblack@google.com{ 94212854Sgabeblack@google.com small_type vs = get_sign(v); 94312854Sgabeblack@google.com 94412854Sgabeblack@google.com if ((sgn == SC_ZERO) || (vs == SC_ZERO)) { 94512854Sgabeblack@google.com div_by_zero(v); // case 1 94612854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 94712854Sgabeblack@google.com } else { 94812854Sgabeblack@google.com CONVERT_INT64_2(v); 94912854Sgabeblack@google.com // other cases 95012854Sgabeblack@google.com MOD_ON_HELPER(sgn, nbits, ndigits, digit, 95112854Sgabeblack@google.com BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 95212854Sgabeblack@google.com } 95312854Sgabeblack@google.com return *this; 95412854Sgabeblack@google.com} 95512854Sgabeblack@google.com 95612854Sgabeblack@google.com 95712854Sgabeblack@google.comconst CLASS_TYPE & 95812854Sgabeblack@google.comCLASS_TYPE::operator %= (uint64 v) 95912854Sgabeblack@google.com{ 96012854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v == 0)) { 96112854Sgabeblack@google.com div_by_zero(v); // case 1 96212854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 96312854Sgabeblack@google.com } else { 96412854Sgabeblack@google.com CONVERT_INT64_2(v); 96512854Sgabeblack@google.com // other cases 96612854Sgabeblack@google.com MOD_ON_HELPER(sgn, nbits, ndigits, digit, 96712854Sgabeblack@google.com BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 96812854Sgabeblack@google.com 96912854Sgabeblack@google.com } 97012854Sgabeblack@google.com return *this; 97112854Sgabeblack@google.com} 97212854Sgabeblack@google.com 97312854Sgabeblack@google.com 97412854Sgabeblack@google.comconst CLASS_TYPE & 97512854Sgabeblack@google.comCLASS_TYPE::operator %= (long v) 97612854Sgabeblack@google.com{ 97712854Sgabeblack@google.com small_type vs = get_sign(v); 97812854Sgabeblack@google.com 97912854Sgabeblack@google.com if ((sgn == SC_ZERO) || (vs == SC_ZERO)) { 98012854Sgabeblack@google.com div_by_zero(v); // case 1 98112854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 98212854Sgabeblack@google.com } else { 98312854Sgabeblack@google.com CONVERT_LONG_2(v); 98412854Sgabeblack@google.com // other cases 98512854Sgabeblack@google.com MOD_ON_HELPER(sgn, nbits, ndigits, digit, 98612854Sgabeblack@google.com BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 98712854Sgabeblack@google.com } 98812854Sgabeblack@google.com return *this; 98912854Sgabeblack@google.com} 99012854Sgabeblack@google.com 99112854Sgabeblack@google.com 99212854Sgabeblack@google.comconst CLASS_TYPE & 99312854Sgabeblack@google.comCLASS_TYPE::operator %= (unsigned long v) 99412854Sgabeblack@google.com{ 99512854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v == 0)) { 99612854Sgabeblack@google.com div_by_zero(v); // case 1 99712854Sgabeblack@google.com vec_zero(ndigits, digit); // case 2 99812854Sgabeblack@google.com } else { 99912854Sgabeblack@google.com CONVERT_LONG_2(v); 100012854Sgabeblack@google.com // other cases 100112854Sgabeblack@google.com MOD_ON_HELPER(sgn, nbits, ndigits, digit, 100212854Sgabeblack@google.com BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 100312854Sgabeblack@google.com } 100412854Sgabeblack@google.com return *this; 100512854Sgabeblack@google.com} 100612854Sgabeblack@google.com 100712854Sgabeblack@google.com 100812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 100912854Sgabeblack@google.com// SECTION: Bitwise AND operators: &, &= 101012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 101112854Sgabeblack@google.com 101212854Sgabeblack@google.com// Cases to consider when computing u &v: 101312854Sgabeblack@google.com// 1. u & 0 = 0 &v = 0 101412854Sgabeblack@google.com// 2. u &v => sgn = + 101512854Sgabeblack@google.com// 3. (-u) & (-v) => sgn = - 101612854Sgabeblack@google.com// 4. u & (-v) => sgn = + 101712854Sgabeblack@google.com// 5. (-u) &v => sgn = + 101812854Sgabeblack@google.com 101912854Sgabeblack@google.comconst CLASS_TYPE & 102012854Sgabeblack@google.comCLASS_TYPE::operator &= (const CLASS_TYPE &v) 102112854Sgabeblack@google.com{ 102212854Sgabeblack@google.com // u = *this 102312854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { // case 1 102412854Sgabeblack@google.com makezero(); 102512854Sgabeblack@google.com } else { // other cases 102612854Sgabeblack@google.com and_on_help(sgn, nbits, ndigits, digit, 102712854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 102812854Sgabeblack@google.com convert_2C_to_SM(); 102912854Sgabeblack@google.com } 103012854Sgabeblack@google.com return *this; 103112854Sgabeblack@google.com} 103212854Sgabeblack@google.com 103312854Sgabeblack@google.com 103412854Sgabeblack@google.comconst CLASS_TYPE & 103512854Sgabeblack@google.comCLASS_TYPE::operator &= (const OTHER_CLASS_TYPE &v) 103612854Sgabeblack@google.com{ 103712854Sgabeblack@google.com // u = *this 103812854Sgabeblack@google.com 103912854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v.sgn == SC_ZERO)) { // case 1 104012854Sgabeblack@google.com makezero(); 104112854Sgabeblack@google.com } else { // other cases 104212854Sgabeblack@google.com and_on_help(sgn, nbits, ndigits, digit, 104312854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 104412854Sgabeblack@google.com convert_2C_to_SM(); 104512854Sgabeblack@google.com } 104612854Sgabeblack@google.com return *this; 104712854Sgabeblack@google.com} 104812854Sgabeblack@google.com 104912854Sgabeblack@google.com 105012854Sgabeblack@google.comconst CLASS_TYPE & 105112854Sgabeblack@google.comCLASS_TYPE::operator &= (int64 v) 105212854Sgabeblack@google.com{ 105312854Sgabeblack@google.com // u = *this 105412854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v == 0)) { // case 1 105512854Sgabeblack@google.com makezero(); 105612854Sgabeblack@google.com } else { // other cases 105712854Sgabeblack@google.com CONVERT_INT64(v); 105812854Sgabeblack@google.com and_on_help(sgn, nbits, ndigits, digit, 105912854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 106012854Sgabeblack@google.com convert_2C_to_SM(); 106112854Sgabeblack@google.com } 106212854Sgabeblack@google.com return *this; 106312854Sgabeblack@google.com} 106412854Sgabeblack@google.com 106512854Sgabeblack@google.com 106612854Sgabeblack@google.comconst CLASS_TYPE & 106712854Sgabeblack@google.comCLASS_TYPE::operator &= (uint64 v) 106812854Sgabeblack@google.com{ 106912854Sgabeblack@google.com // u = *this 107012854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v == 0)) { // case 1 107112854Sgabeblack@google.com makezero(); 107212854Sgabeblack@google.com } else { // other cases 107312854Sgabeblack@google.com CONVERT_INT64(v); 107412854Sgabeblack@google.com and_on_help(sgn, nbits, ndigits, digit, 107512854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 107612854Sgabeblack@google.com convert_2C_to_SM(); 107712854Sgabeblack@google.com } 107812854Sgabeblack@google.com return *this; 107912854Sgabeblack@google.com} 108012854Sgabeblack@google.com 108112854Sgabeblack@google.com 108212854Sgabeblack@google.comconst CLASS_TYPE & 108312854Sgabeblack@google.comCLASS_TYPE::operator &= (long v) 108412854Sgabeblack@google.com{ 108512854Sgabeblack@google.com // u = *this 108612854Sgabeblack@google.com 108712854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v == 0)) { // case 1 108812854Sgabeblack@google.com makezero(); 108912854Sgabeblack@google.com } else { // other cases 109012854Sgabeblack@google.com CONVERT_LONG(v); 109112854Sgabeblack@google.com and_on_help(sgn, nbits, ndigits, digit, 109212854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 109312854Sgabeblack@google.com convert_2C_to_SM(); 109412854Sgabeblack@google.com } 109512854Sgabeblack@google.com 109612854Sgabeblack@google.com return *this; 109712854Sgabeblack@google.com} 109812854Sgabeblack@google.com 109912854Sgabeblack@google.com 110012854Sgabeblack@google.comconst CLASS_TYPE & 110112854Sgabeblack@google.comCLASS_TYPE::operator &= (unsigned long v) 110212854Sgabeblack@google.com{ 110312854Sgabeblack@google.com // u = *this 110412854Sgabeblack@google.com if ((sgn == SC_ZERO) || (v == 0)) { // case 1 110512854Sgabeblack@google.com makezero(); 110612854Sgabeblack@google.com } else { // other cases 110712854Sgabeblack@google.com CONVERT_LONG(v); 110812854Sgabeblack@google.com and_on_help(sgn, nbits, ndigits, digit, 110912854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 111012854Sgabeblack@google.com convert_2C_to_SM(); 111112854Sgabeblack@google.com } 111212854Sgabeblack@google.com return *this; 111312854Sgabeblack@google.com} 111412854Sgabeblack@google.com 111512854Sgabeblack@google.com 111612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 111712854Sgabeblack@google.com// SECTION: Bitwise OR operators: |, |= 111812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 111912854Sgabeblack@google.com 112012854Sgabeblack@google.com// Cases to consider when computing u | v: 112112854Sgabeblack@google.com// 1. u | 0 = u 112212854Sgabeblack@google.com// 2. 0 | v = v 112312854Sgabeblack@google.com// 3. u | v => sgn = + 112412854Sgabeblack@google.com// 4. (-u) | (-v) => sgn = - 112512854Sgabeblack@google.com// 5. u | (-v) => sgn = - 112612854Sgabeblack@google.com// 6. (-u) | v => sgn = - 112712854Sgabeblack@google.com 112812854Sgabeblack@google.comconst CLASS_TYPE & 112912854Sgabeblack@google.comCLASS_TYPE::operator |= (const CLASS_TYPE &v) 113012854Sgabeblack@google.com{ 113112854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 1 113212854Sgabeblack@google.com return *this; 113312854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 113412854Sgabeblack@google.com return (*this = v); 113512854Sgabeblack@google.com // other cases 113612854Sgabeblack@google.com or_on_help(sgn, nbits, ndigits, digit, 113712854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 113812854Sgabeblack@google.com convert_2C_to_SM(); 113912854Sgabeblack@google.com return *this; 114012854Sgabeblack@google.com} 114112854Sgabeblack@google.com 114212854Sgabeblack@google.com 114312854Sgabeblack@google.comconst CLASS_TYPE & 114412854Sgabeblack@google.comCLASS_TYPE::operator |= (const OTHER_CLASS_TYPE &v) 114512854Sgabeblack@google.com{ 114612854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 1 114712854Sgabeblack@google.com return *this; 114812854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 114912854Sgabeblack@google.com return (*this = v); 115012854Sgabeblack@google.com // other cases 115112854Sgabeblack@google.com or_on_help(sgn, nbits, ndigits, digit, 115212854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 115312854Sgabeblack@google.com convert_2C_to_SM(); 115412854Sgabeblack@google.com return *this; 115512854Sgabeblack@google.com} 115612854Sgabeblack@google.com 115712854Sgabeblack@google.com 115812854Sgabeblack@google.comconst CLASS_TYPE& 115912854Sgabeblack@google.comCLASS_TYPE::operator |= (int64 v) 116012854Sgabeblack@google.com{ 116112854Sgabeblack@google.com if (v == 0) // case 1 116212854Sgabeblack@google.com return *this; 116312854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 116412854Sgabeblack@google.com return (*this = v); 116512854Sgabeblack@google.com // other cases 116612854Sgabeblack@google.com CONVERT_INT64(v); 116712854Sgabeblack@google.com or_on_help(sgn, nbits, ndigits, digit, 116812854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 116912854Sgabeblack@google.com convert_2C_to_SM(); 117012854Sgabeblack@google.com return *this; 117112854Sgabeblack@google.com} 117212854Sgabeblack@google.com 117312854Sgabeblack@google.com 117412854Sgabeblack@google.comconst CLASS_TYPE& 117512854Sgabeblack@google.comCLASS_TYPE::operator |= (uint64 v) 117612854Sgabeblack@google.com{ 117712854Sgabeblack@google.com if (v == 0) // case 1 117812854Sgabeblack@google.com return *this; 117912854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 118012854Sgabeblack@google.com return (*this = v); 118112854Sgabeblack@google.com // other cases 118212854Sgabeblack@google.com CONVERT_INT64(v); 118312854Sgabeblack@google.com or_on_help(sgn, nbits, ndigits, digit, 118412854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 118512854Sgabeblack@google.com convert_2C_to_SM(); 118612854Sgabeblack@google.com return *this; 118712854Sgabeblack@google.com} 118812854Sgabeblack@google.com 118912854Sgabeblack@google.com 119012854Sgabeblack@google.comconst CLASS_TYPE & 119112854Sgabeblack@google.comCLASS_TYPE::operator |= (long v) 119212854Sgabeblack@google.com{ 119312854Sgabeblack@google.com if (v == 0) // case 1 119412854Sgabeblack@google.com return *this; 119512854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 119612854Sgabeblack@google.com return (*this = v); 119712854Sgabeblack@google.com // other cases 119812854Sgabeblack@google.com CONVERT_LONG(v); 119912854Sgabeblack@google.com or_on_help(sgn, nbits, ndigits, digit, 120012854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 120112854Sgabeblack@google.com convert_2C_to_SM(); 120212854Sgabeblack@google.com return *this; 120312854Sgabeblack@google.com} 120412854Sgabeblack@google.com 120512854Sgabeblack@google.com 120612854Sgabeblack@google.comconst CLASS_TYPE & 120712854Sgabeblack@google.comCLASS_TYPE::operator |= (unsigned long v) 120812854Sgabeblack@google.com{ 120912854Sgabeblack@google.com if (v == 0) // case 1 121012854Sgabeblack@google.com return *this; 121112854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 121212854Sgabeblack@google.com return (*this = v); 121312854Sgabeblack@google.com // other cases 121412854Sgabeblack@google.com CONVERT_LONG(v); 121512854Sgabeblack@google.com or_on_help(sgn, nbits, ndigits, digit, 121612854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 121712854Sgabeblack@google.com convert_2C_to_SM(); 121812854Sgabeblack@google.com return *this; 121912854Sgabeblack@google.com} 122012854Sgabeblack@google.com 122112854Sgabeblack@google.com 122212854Sgabeblack@google.com// ---------------------------------------------------------------------------- 122312854Sgabeblack@google.com// SECTION: Bitwise XOR operators: ^, ^= 122412854Sgabeblack@google.com// ---------------------------------------------------------------------------- 122512854Sgabeblack@google.com 122612854Sgabeblack@google.com// Cases to consider when computing u ^ v: 122712854Sgabeblack@google.com// Note that u ^ v = (~u &v) | (u & ~v). 122812854Sgabeblack@google.com// 1. u ^ 0 = u 122912854Sgabeblack@google.com// 2. 0 ^ v = v 123012854Sgabeblack@google.com// 3. u ^ v => sgn = + 123112854Sgabeblack@google.com// 4. (-u) ^ (-v) => sgn = - 123212854Sgabeblack@google.com// 5. u ^ (-v) => sgn = - 123312854Sgabeblack@google.com// 6. (-u) ^ v => sgn = + 123412854Sgabeblack@google.com 123512854Sgabeblack@google.comconst CLASS_TYPE & 123612854Sgabeblack@google.comCLASS_TYPE::operator ^= (const CLASS_TYPE &v) 123712854Sgabeblack@google.com{ 123812854Sgabeblack@google.com // u = *this 123912854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 1 124012854Sgabeblack@google.com return *this; 124112854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 124212854Sgabeblack@google.com return (*this = v); 124312854Sgabeblack@google.com // other cases 124412854Sgabeblack@google.com xor_on_help(sgn, nbits, ndigits, digit, 124512854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 124612854Sgabeblack@google.com convert_2C_to_SM(); 124712854Sgabeblack@google.com return *this; 124812854Sgabeblack@google.com} 124912854Sgabeblack@google.com 125012854Sgabeblack@google.com 125112854Sgabeblack@google.comconst CLASS_TYPE & 125212854Sgabeblack@google.comCLASS_TYPE::operator ^= (const OTHER_CLASS_TYPE &v) 125312854Sgabeblack@google.com{ 125412854Sgabeblack@google.com // u = *this 125512854Sgabeblack@google.com if (v.sgn == SC_ZERO) // case 1 125612854Sgabeblack@google.com return *this; 125712854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 125812854Sgabeblack@google.com return (*this = v); 125912854Sgabeblack@google.com // other cases 126012854Sgabeblack@google.com xor_on_help(sgn, nbits, ndigits, digit, 126112854Sgabeblack@google.com v.sgn, v.nbits, v.ndigits, v.digit); 126212854Sgabeblack@google.com convert_2C_to_SM(); 126312854Sgabeblack@google.com return *this; 126412854Sgabeblack@google.com} 126512854Sgabeblack@google.com 126612854Sgabeblack@google.com 126712854Sgabeblack@google.comconst CLASS_TYPE& 126812854Sgabeblack@google.comCLASS_TYPE::operator ^= (int64 v) 126912854Sgabeblack@google.com{ 127012854Sgabeblack@google.com if (v == 0) // case 1 127112854Sgabeblack@google.com return *this; 127212854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 127312854Sgabeblack@google.com return (*this = v); 127412854Sgabeblack@google.com // other cases 127512854Sgabeblack@google.com CONVERT_INT64(v); 127612854Sgabeblack@google.com xor_on_help(sgn, nbits, ndigits, digit, 127712854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 127812854Sgabeblack@google.com convert_2C_to_SM(); 127912854Sgabeblack@google.com return *this; 128012854Sgabeblack@google.com} 128112854Sgabeblack@google.com 128212854Sgabeblack@google.com 128312854Sgabeblack@google.comconst CLASS_TYPE & 128412854Sgabeblack@google.comCLASS_TYPE::operator ^= (uint64 v) 128512854Sgabeblack@google.com{ 128612854Sgabeblack@google.com if (v == 0) // case 1 128712854Sgabeblack@google.com return *this; 128812854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 128912854Sgabeblack@google.com return (*this = v); 129012854Sgabeblack@google.com // other cases 129112854Sgabeblack@google.com CONVERT_INT64(v); 129212854Sgabeblack@google.com xor_on_help(sgn, nbits, ndigits, digit, 129312854Sgabeblack@google.com vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd); 129412854Sgabeblack@google.com convert_2C_to_SM(); 129512854Sgabeblack@google.com return *this; 129612854Sgabeblack@google.com} 129712854Sgabeblack@google.com 129812854Sgabeblack@google.com 129912854Sgabeblack@google.comconst CLASS_TYPE & 130012854Sgabeblack@google.comCLASS_TYPE::operator ^= (long v) 130112854Sgabeblack@google.com{ 130212854Sgabeblack@google.com if (v == 0) // case 1 130312854Sgabeblack@google.com return *this; 130412854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 130512854Sgabeblack@google.com return (*this = v); 130612854Sgabeblack@google.com // other cases 130712854Sgabeblack@google.com CONVERT_LONG(v); 130812854Sgabeblack@google.com xor_on_help(sgn, nbits, ndigits, digit, 130912854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 131012854Sgabeblack@google.com convert_2C_to_SM(); 131112854Sgabeblack@google.com return *this; 131212854Sgabeblack@google.com} 131312854Sgabeblack@google.com 131412854Sgabeblack@google.com 131512854Sgabeblack@google.comconst CLASS_TYPE & 131612854Sgabeblack@google.comCLASS_TYPE::operator ^= (unsigned long v) 131712854Sgabeblack@google.com{ 131812854Sgabeblack@google.com if (v == 0) // case 1 131912854Sgabeblack@google.com return *this; 132012854Sgabeblack@google.com if (sgn == SC_ZERO) // case 2 132112854Sgabeblack@google.com return (*this = v); 132212854Sgabeblack@google.com // other cases 132312854Sgabeblack@google.com CONVERT_LONG(v); 132412854Sgabeblack@google.com xor_on_help(sgn, nbits, ndigits, digit, 132512854Sgabeblack@google.com vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd); 132612854Sgabeblack@google.com convert_2C_to_SM(); 132712854Sgabeblack@google.com return *this; 132812854Sgabeblack@google.com} 132912854Sgabeblack@google.com 133012854Sgabeblack@google.com 133112854Sgabeblack@google.com// ---------------------------------------------------------------------------- 133212854Sgabeblack@google.com// SECTION: Bitwise NOT operator: ~ 133312854Sgabeblack@google.com// ---------------------------------------------------------------------------- 133412854Sgabeblack@google.com 133512854Sgabeblack@google.comCLASS_TYPE 133612854Sgabeblack@google.comoperator ~ (const CLASS_TYPE &u) 133712854Sgabeblack@google.com{ 133812854Sgabeblack@google.com small_type s = u.sgn; 133912854Sgabeblack@google.com if (s == SC_ZERO) { 134012854Sgabeblack@google.com sc_digit d = 1; 134112854Sgabeblack@google.com return CLASS_TYPE(SC_NEG, u.nbits, 1, &d, false); 134212854Sgabeblack@google.com } 134312854Sgabeblack@google.com 134412854Sgabeblack@google.com int nd = u.ndigits; 134512854Sgabeblack@google.com 134612854Sgabeblack@google.com#ifdef SC_MAX_NBITS 134712854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 134812854Sgabeblack@google.com#else 134912854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 135012854Sgabeblack@google.com#endif 135112854Sgabeblack@google.com 135212854Sgabeblack@google.com vec_copy(nd, d, u.digit); 135312854Sgabeblack@google.com if (s == SC_POS) { 135412854Sgabeblack@google.com s = SC_NEG; 135512854Sgabeblack@google.com vec_add_small_on(nd, d, 1); 135612854Sgabeblack@google.com } else { 135712854Sgabeblack@google.com s = SC_POS; 135812854Sgabeblack@google.com vec_sub_small_on(nd, d, 1); 135912854Sgabeblack@google.com if (check_for_zero(nd, d)) 136012854Sgabeblack@google.com s = SC_ZERO; 136112854Sgabeblack@google.com } 136212854Sgabeblack@google.com return CLASS_TYPE(s, u.nbits, nd, d); 136312854Sgabeblack@google.com} 136412854Sgabeblack@google.com 136512854Sgabeblack@google.com 136612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 136712854Sgabeblack@google.com// SECTION: LEFT SHIFT operators: <<, <<= 136812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 136912854Sgabeblack@google.com 137012854Sgabeblack@google.comCLASS_TYPE 137112854Sgabeblack@google.comoperator << (const CLASS_TYPE &u, const CLASS_TYPE &v) 137212854Sgabeblack@google.com{ 137312854Sgabeblack@google.com if (v.sgn == SC_ZERO) 137412854Sgabeblack@google.com return CLASS_TYPE(u); 137512854Sgabeblack@google.com#ifdef SC_SIGNED 137612854Sgabeblack@google.com if (v.sgn == SC_NEG) 137712854Sgabeblack@google.com return CLASS_TYPE(u); 137812854Sgabeblack@google.com#endif 137912854Sgabeblack@google.com return operator << (u, v.to_ulong()); 138012854Sgabeblack@google.com} 138112854Sgabeblack@google.com 138212854Sgabeblack@google.com 138312854Sgabeblack@google.comconst CLASS_TYPE & 138412854Sgabeblack@google.comCLASS_TYPE::operator <<= (const CLASS_TYPE &v) 138512854Sgabeblack@google.com{ 138612854Sgabeblack@google.com if (v.sgn == SC_ZERO) 138712854Sgabeblack@google.com return *this; 138812854Sgabeblack@google.com#ifdef SC_SIGNED 138912854Sgabeblack@google.com if (v.sgn == SC_NEG) 139012854Sgabeblack@google.com return *this; 139112854Sgabeblack@google.com#endif 139212854Sgabeblack@google.com return operator <<= (v.to_ulong()); 139312854Sgabeblack@google.com} 139412854Sgabeblack@google.com 139512854Sgabeblack@google.com 139612854Sgabeblack@google.comconst CLASS_TYPE & 139712854Sgabeblack@google.comCLASS_TYPE::operator <<= (const OTHER_CLASS_TYPE &v) 139812854Sgabeblack@google.com{ 139912854Sgabeblack@google.com if (v.sgn == SC_ZERO) 140012854Sgabeblack@google.com return *this; 140112854Sgabeblack@google.com#ifdef SC_UNSIGNED 140212854Sgabeblack@google.com if (v.sgn == SC_NEG) 140312854Sgabeblack@google.com return *this; 140412854Sgabeblack@google.com#endif 140512854Sgabeblack@google.com return operator <<= (v.to_ulong()); 140612854Sgabeblack@google.com} 140712854Sgabeblack@google.com 140812854Sgabeblack@google.com 140912854Sgabeblack@google.comCLASS_TYPE 141012854Sgabeblack@google.comoperator << (const CLASS_TYPE &u, int64 v) 141112854Sgabeblack@google.com{ 141212854Sgabeblack@google.com if (v <= 0) 141312854Sgabeblack@google.com return CLASS_TYPE(u); 141412854Sgabeblack@google.com return operator << (u, (unsigned long)v); 141512854Sgabeblack@google.com} 141612854Sgabeblack@google.com 141712854Sgabeblack@google.com 141812854Sgabeblack@google.comCLASS_TYPE 141912854Sgabeblack@google.comoperator << (const CLASS_TYPE &u, uint64 v) 142012854Sgabeblack@google.com{ 142112854Sgabeblack@google.com if (v == 0) 142212854Sgabeblack@google.com return CLASS_TYPE(u); 142312854Sgabeblack@google.com return operator << (u, (unsigned long)v); 142412854Sgabeblack@google.com} 142512854Sgabeblack@google.com 142612854Sgabeblack@google.com 142712854Sgabeblack@google.comconst CLASS_TYPE & 142812854Sgabeblack@google.comCLASS_TYPE::operator <<= (int64 v) 142912854Sgabeblack@google.com{ 143012854Sgabeblack@google.com if (v <= 0) 143112854Sgabeblack@google.com return *this; 143212854Sgabeblack@google.com return operator <<= ((unsigned long)v); 143312854Sgabeblack@google.com} 143412854Sgabeblack@google.com 143512854Sgabeblack@google.com 143612854Sgabeblack@google.comconst CLASS_TYPE & 143712854Sgabeblack@google.comCLASS_TYPE::operator <<= (uint64 v) 143812854Sgabeblack@google.com{ 143912854Sgabeblack@google.com if (v == 0) 144012854Sgabeblack@google.com return *this; 144112854Sgabeblack@google.com return operator <<= ((unsigned long)v); 144212854Sgabeblack@google.com} 144312854Sgabeblack@google.com 144412854Sgabeblack@google.com 144512854Sgabeblack@google.comCLASS_TYPE 144612854Sgabeblack@google.comoperator << (const CLASS_TYPE &u, long v) 144712854Sgabeblack@google.com{ 144812854Sgabeblack@google.com if (v <= 0) 144912854Sgabeblack@google.com return CLASS_TYPE(u); 145012854Sgabeblack@google.com return operator << (u, (unsigned long)v); 145112854Sgabeblack@google.com} 145212854Sgabeblack@google.com 145312854Sgabeblack@google.comCLASS_TYPE 145412854Sgabeblack@google.comoperator << (const CLASS_TYPE &u, unsigned long v) 145512854Sgabeblack@google.com{ 145612854Sgabeblack@google.com if (v == 0) 145712854Sgabeblack@google.com return CLASS_TYPE(u); 145812854Sgabeblack@google.com if (u.sgn == SC_ZERO) 145912854Sgabeblack@google.com return CLASS_TYPE(u); 146012854Sgabeblack@google.com 146112854Sgabeblack@google.com int nb = u.nbits + v; 146212854Sgabeblack@google.com int nd = DIV_CEIL(nb); 146312854Sgabeblack@google.com 146412854Sgabeblack@google.com#ifdef SC_MAX_NBITS 146512854Sgabeblack@google.com test_bound(nb); 146612854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 146712854Sgabeblack@google.com#else 146812854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 146912854Sgabeblack@google.com#endif 147012854Sgabeblack@google.com 147112854Sgabeblack@google.com vec_copy_and_zero(nd, d, u.ndigits, u.digit); 147212854Sgabeblack@google.com convert_SM_to_2C(u.sgn, nd, d); 147312854Sgabeblack@google.com vec_shift_left(nd, d, v); 147412854Sgabeblack@google.com small_type s = convert_signed_2C_to_SM(nb, nd, d); 147512854Sgabeblack@google.com return CLASS_TYPE(s, nb, nd, d); 147612854Sgabeblack@google.com} 147712854Sgabeblack@google.com 147812854Sgabeblack@google.com 147912854Sgabeblack@google.comconst CLASS_TYPE & 148012854Sgabeblack@google.comCLASS_TYPE::operator <<= (long v) 148112854Sgabeblack@google.com{ 148212854Sgabeblack@google.com if (v <= 0) 148312854Sgabeblack@google.com return *this; 148412854Sgabeblack@google.com return operator <<= ((unsigned long)v); 148512854Sgabeblack@google.com} 148612854Sgabeblack@google.com 148712854Sgabeblack@google.com 148812854Sgabeblack@google.comconst CLASS_TYPE & 148912854Sgabeblack@google.comCLASS_TYPE::operator <<= (unsigned long v) 149012854Sgabeblack@google.com{ 149112854Sgabeblack@google.com if (v == 0) 149212854Sgabeblack@google.com return *this; 149312854Sgabeblack@google.com if (sgn == SC_ZERO) 149412854Sgabeblack@google.com return *this; 149512854Sgabeblack@google.com convert_SM_to_2C(); 149612854Sgabeblack@google.com vec_shift_left(ndigits, digit, v); 149712854Sgabeblack@google.com convert_2C_to_SM(); 149812854Sgabeblack@google.com return *this; 149912854Sgabeblack@google.com} 150012854Sgabeblack@google.com 150112854Sgabeblack@google.com 150212854Sgabeblack@google.com// ---------------------------------------------------------------------------- 150312854Sgabeblack@google.com// SECTION: RIGHT SHIFT operators: >>, >>= 150412854Sgabeblack@google.com// ---------------------------------------------------------------------------- 150512854Sgabeblack@google.com 150612854Sgabeblack@google.comCLASS_TYPE 150712854Sgabeblack@google.comoperator >> (const CLASS_TYPE &u, const CLASS_TYPE &v) 150812854Sgabeblack@google.com{ 150912854Sgabeblack@google.com if (v.sgn == SC_ZERO) 151012854Sgabeblack@google.com return CLASS_TYPE(u); 151112854Sgabeblack@google.com#ifdef SC_SIGNED 151212854Sgabeblack@google.com if (v.sgn == SC_NEG) 151312854Sgabeblack@google.com return CLASS_TYPE(u); 151412854Sgabeblack@google.com#endif 151512854Sgabeblack@google.com return operator >> (u, v.to_long()); 151612854Sgabeblack@google.com} 151712854Sgabeblack@google.com 151812854Sgabeblack@google.com 151912854Sgabeblack@google.comconst CLASS_TYPE & 152012854Sgabeblack@google.comCLASS_TYPE::operator >>= (const CLASS_TYPE &v) 152112854Sgabeblack@google.com{ 152212854Sgabeblack@google.com if (v.sgn == SC_ZERO) 152312854Sgabeblack@google.com return *this; 152412854Sgabeblack@google.com#ifdef SC_SIGNED 152512854Sgabeblack@google.com if (v.sgn == SC_NEG) 152612854Sgabeblack@google.com return *this; 152712854Sgabeblack@google.com#endif 152812854Sgabeblack@google.com return operator >>= (v.to_long()); 152912854Sgabeblack@google.com} 153012854Sgabeblack@google.com 153112854Sgabeblack@google.com 153212854Sgabeblack@google.comconst CLASS_TYPE & 153312854Sgabeblack@google.comCLASS_TYPE::operator >>= (const OTHER_CLASS_TYPE &v) 153412854Sgabeblack@google.com{ 153512854Sgabeblack@google.com if (v.sgn == SC_ZERO) 153612854Sgabeblack@google.com return *this; 153712854Sgabeblack@google.com#ifdef SC_UNSIGNED 153812854Sgabeblack@google.com if (v.sgn == SC_NEG) 153912854Sgabeblack@google.com return *this; 154012854Sgabeblack@google.com#endif 154112854Sgabeblack@google.com return operator >>= (v.to_ulong()); 154212854Sgabeblack@google.com} 154312854Sgabeblack@google.com 154412854Sgabeblack@google.com 154512854Sgabeblack@google.comCLASS_TYPE 154612854Sgabeblack@google.comoperator >> (const CLASS_TYPE &u, int64 v) 154712854Sgabeblack@google.com{ 154812854Sgabeblack@google.com if (v <= 0) 154912854Sgabeblack@google.com return CLASS_TYPE(u); 155012854Sgabeblack@google.com return operator >> (u, (unsigned long)v); 155112854Sgabeblack@google.com} 155212854Sgabeblack@google.com 155312854Sgabeblack@google.com 155412854Sgabeblack@google.comCLASS_TYPE 155512854Sgabeblack@google.comoperator >> (const CLASS_TYPE &u, uint64 v) 155612854Sgabeblack@google.com{ 155712854Sgabeblack@google.com if (v == 0) 155812854Sgabeblack@google.com return CLASS_TYPE(u); 155912854Sgabeblack@google.com return operator >> (u, (unsigned long)v); 156012854Sgabeblack@google.com} 156112854Sgabeblack@google.com 156212854Sgabeblack@google.comconst CLASS_TYPE & 156312854Sgabeblack@google.comCLASS_TYPE::operator >>= (int64 v) 156412854Sgabeblack@google.com{ 156512854Sgabeblack@google.com if (v <= 0) 156612854Sgabeblack@google.com return *this; 156712854Sgabeblack@google.com return operator >>= ((unsigned long)v); 156812854Sgabeblack@google.com} 156912854Sgabeblack@google.com 157012854Sgabeblack@google.com 157112854Sgabeblack@google.comconst CLASS_TYPE & 157212854Sgabeblack@google.comCLASS_TYPE::operator >>= (uint64 v) 157312854Sgabeblack@google.com{ 157412854Sgabeblack@google.com if (v == 0) 157512854Sgabeblack@google.com return *this; 157612854Sgabeblack@google.com return operator >>= ((unsigned long)v); 157712854Sgabeblack@google.com} 157812854Sgabeblack@google.com 157912854Sgabeblack@google.com 158012854Sgabeblack@google.comCLASS_TYPE 158112854Sgabeblack@google.comoperator >> (const CLASS_TYPE &u, long v) 158212854Sgabeblack@google.com{ 158312854Sgabeblack@google.com if (v <= 0) 158412854Sgabeblack@google.com return CLASS_TYPE(u); 158512854Sgabeblack@google.com return operator >> (u, (unsigned long)v); 158612854Sgabeblack@google.com} 158712854Sgabeblack@google.com 158812854Sgabeblack@google.com 158912854Sgabeblack@google.comCLASS_TYPE 159012854Sgabeblack@google.comoperator >> (const CLASS_TYPE &u, unsigned long v) 159112854Sgabeblack@google.com{ 159212854Sgabeblack@google.com if (v == 0) 159312854Sgabeblack@google.com return CLASS_TYPE(u); 159412854Sgabeblack@google.com if (u.sgn == SC_ZERO) 159512854Sgabeblack@google.com return CLASS_TYPE(u); 159612854Sgabeblack@google.com 159712854Sgabeblack@google.com int nb = u.nbits; 159812854Sgabeblack@google.com int nd = u.ndigits; 159912854Sgabeblack@google.com 160012854Sgabeblack@google.com#ifdef SC_MAX_NBITS 160112854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 160212854Sgabeblack@google.com#else 160312854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 160412854Sgabeblack@google.com#endif 160512854Sgabeblack@google.com 160612854Sgabeblack@google.com vec_copy(nd, d, u.digit); 160712854Sgabeblack@google.com convert_SM_to_2C(u.sgn, nd, d); 160812854Sgabeblack@google.com if (u.sgn == SC_NEG) 160912854Sgabeblack@google.com vec_shift_right(nd, d, v, DIGIT_MASK); 161012854Sgabeblack@google.com else 161112854Sgabeblack@google.com vec_shift_right(nd, d, v, 0); 161212854Sgabeblack@google.com small_type s = convert_signed_2C_to_SM(nb, nd, d); 161312854Sgabeblack@google.com return CLASS_TYPE(s, nb, nd, d); 161412854Sgabeblack@google.com} 161512854Sgabeblack@google.com 161612854Sgabeblack@google.com 161712854Sgabeblack@google.comconst CLASS_TYPE & 161812854Sgabeblack@google.comCLASS_TYPE::operator >>= (long v) 161912854Sgabeblack@google.com{ 162012854Sgabeblack@google.com if (v <= 0) 162112854Sgabeblack@google.com return *this; 162212854Sgabeblack@google.com return operator >>= ((unsigned long)v); 162312854Sgabeblack@google.com} 162412854Sgabeblack@google.com 162512854Sgabeblack@google.com 162612854Sgabeblack@google.comconst CLASS_TYPE & 162712854Sgabeblack@google.comCLASS_TYPE::operator >>= (unsigned long v) 162812854Sgabeblack@google.com{ 162912854Sgabeblack@google.com if (v == 0) 163012854Sgabeblack@google.com return *this; 163112854Sgabeblack@google.com if (sgn == SC_ZERO) 163212854Sgabeblack@google.com return *this; 163312854Sgabeblack@google.com 163412854Sgabeblack@google.com convert_SM_to_2C(); 163512854Sgabeblack@google.com 163612854Sgabeblack@google.com if (sgn == SC_NEG) 163712854Sgabeblack@google.com vec_shift_right(ndigits, digit, v, DIGIT_MASK); 163812854Sgabeblack@google.com else 163912854Sgabeblack@google.com vec_shift_right(ndigits, digit, v, 0); 164012854Sgabeblack@google.com convert_2C_to_SM(); 164112854Sgabeblack@google.com return *this; 164212854Sgabeblack@google.com} 164312854Sgabeblack@google.com 164412854Sgabeblack@google.com 164512854Sgabeblack@google.com// ---------------------------------------------------------------------------- 164612854Sgabeblack@google.com// SECTION: EQUAL TO operator: == 164712854Sgabeblack@google.com// ---------------------------------------------------------------------------- 164812854Sgabeblack@google.com 164912854Sgabeblack@google.com// Defined in the sc_signed.cpp and sc_unsigned.cpp. 165012854Sgabeblack@google.com 165112854Sgabeblack@google.com 165212854Sgabeblack@google.com// ---------------------------------------------------------------------------- 165312854Sgabeblack@google.com// SECTION: NOT_EQUAL operator: != 165412854Sgabeblack@google.com// ---------------------------------------------------------------------------- 165512854Sgabeblack@google.com 165612854Sgabeblack@google.combool 165712854Sgabeblack@google.comoperator != (const CLASS_TYPE &u, const CLASS_TYPE &v) 165812854Sgabeblack@google.com{ 165912854Sgabeblack@google.com return (!operator == (u, v)); 166012854Sgabeblack@google.com} 166112854Sgabeblack@google.com 166212854Sgabeblack@google.com 166312854Sgabeblack@google.combool 166412854Sgabeblack@google.comoperator != (const CLASS_TYPE &u, int64 v) 166512854Sgabeblack@google.com{ 166612854Sgabeblack@google.com return (!operator == (u, v)); 166712854Sgabeblack@google.com} 166812854Sgabeblack@google.com 166912854Sgabeblack@google.com 167012854Sgabeblack@google.combool 167112854Sgabeblack@google.comoperator != (int64 u, const CLASS_TYPE &v) 167212854Sgabeblack@google.com{ 167312854Sgabeblack@google.com return (!operator == (u, v)); 167412854Sgabeblack@google.com} 167512854Sgabeblack@google.com 167612854Sgabeblack@google.com 167712854Sgabeblack@google.combool 167812854Sgabeblack@google.comoperator != (const CLASS_TYPE &u, uint64 v) 167912854Sgabeblack@google.com{ 168012854Sgabeblack@google.com return (!operator == (u, v)); 168112854Sgabeblack@google.com} 168212854Sgabeblack@google.com 168312854Sgabeblack@google.com 168412854Sgabeblack@google.combool 168512854Sgabeblack@google.comoperator != (uint64 u, const CLASS_TYPE &v) 168612854Sgabeblack@google.com{ 168712854Sgabeblack@google.com return (!operator == (u, v)); 168812854Sgabeblack@google.com} 168912854Sgabeblack@google.com 169012854Sgabeblack@google.com 169112854Sgabeblack@google.combool 169212854Sgabeblack@google.comoperator != (const CLASS_TYPE &u, long v) 169312854Sgabeblack@google.com{ 169412854Sgabeblack@google.com return (!operator == (u, v)); 169512854Sgabeblack@google.com} 169612854Sgabeblack@google.com 169712854Sgabeblack@google.com 169812854Sgabeblack@google.combool 169912854Sgabeblack@google.comoperator != (long u, const CLASS_TYPE &v) 170012854Sgabeblack@google.com{ 170112854Sgabeblack@google.com return (!operator == (u, v)); 170212854Sgabeblack@google.com} 170312854Sgabeblack@google.com 170412854Sgabeblack@google.com 170512854Sgabeblack@google.combool 170612854Sgabeblack@google.comoperator != (const CLASS_TYPE &u, unsigned long v) 170712854Sgabeblack@google.com{ 170812854Sgabeblack@google.com return (!operator == (u, v)); 170912854Sgabeblack@google.com} 171012854Sgabeblack@google.com 171112854Sgabeblack@google.com 171212854Sgabeblack@google.combool 171312854Sgabeblack@google.comoperator != (unsigned long u, const CLASS_TYPE &v) 171412854Sgabeblack@google.com{ 171512854Sgabeblack@google.com return (!operator == (u, v)); 171612854Sgabeblack@google.com} 171712854Sgabeblack@google.com 171812854Sgabeblack@google.com 171912854Sgabeblack@google.com// ---------------------------------------------------------------------------- 172012854Sgabeblack@google.com// SECTION: LESS THAN operator: < 172112854Sgabeblack@google.com// ---------------------------------------------------------------------------- 172212854Sgabeblack@google.com 172312854Sgabeblack@google.com// Defined in the sc_signed.cpp and sc_unsigned.cpp. 172412854Sgabeblack@google.com 172512854Sgabeblack@google.com 172612854Sgabeblack@google.com// ---------------------------------------------------------------------------- 172712854Sgabeblack@google.com// SECTION: LESS THAN or EQUAL operator: <= 172812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 172912854Sgabeblack@google.com 173012854Sgabeblack@google.combool 173112854Sgabeblack@google.comoperator <= (const CLASS_TYPE &u, const CLASS_TYPE &v) 173212854Sgabeblack@google.com{ 173312854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 173412854Sgabeblack@google.com} 173512854Sgabeblack@google.com 173612854Sgabeblack@google.com 173712854Sgabeblack@google.combool 173812854Sgabeblack@google.comoperator <= (const CLASS_TYPE &u, int64 v) 173912854Sgabeblack@google.com{ 174012854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 174112854Sgabeblack@google.com} 174212854Sgabeblack@google.com 174312854Sgabeblack@google.com 174412854Sgabeblack@google.combool 174512854Sgabeblack@google.comoperator <= (int64 u, const CLASS_TYPE &v) 174612854Sgabeblack@google.com{ 174712854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 174812854Sgabeblack@google.com} 174912854Sgabeblack@google.com 175012854Sgabeblack@google.com 175112854Sgabeblack@google.combool 175212854Sgabeblack@google.comoperator <= (const CLASS_TYPE &u, uint64 v) 175312854Sgabeblack@google.com{ 175412854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 175512854Sgabeblack@google.com} 175612854Sgabeblack@google.com 175712854Sgabeblack@google.com 175812854Sgabeblack@google.combool 175912854Sgabeblack@google.comoperator <= (uint64 u, const CLASS_TYPE &v) 176012854Sgabeblack@google.com{ 176112854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 176212854Sgabeblack@google.com} 176312854Sgabeblack@google.com 176412854Sgabeblack@google.com 176512854Sgabeblack@google.combool 176612854Sgabeblack@google.comoperator <= (const CLASS_TYPE &u, long v) 176712854Sgabeblack@google.com{ 176812854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 176912854Sgabeblack@google.com} 177012854Sgabeblack@google.com 177112854Sgabeblack@google.com 177212854Sgabeblack@google.combool 177312854Sgabeblack@google.comoperator <= (long u, const CLASS_TYPE &v) 177412854Sgabeblack@google.com{ 177512854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 177612854Sgabeblack@google.com} 177712854Sgabeblack@google.com 177812854Sgabeblack@google.com 177912854Sgabeblack@google.combool 178012854Sgabeblack@google.comoperator <= (const CLASS_TYPE &u, unsigned long v) 178112854Sgabeblack@google.com{ 178212854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 178312854Sgabeblack@google.com} 178412854Sgabeblack@google.com 178512854Sgabeblack@google.com 178612854Sgabeblack@google.combool 178712854Sgabeblack@google.comoperator <= (unsigned long u, const CLASS_TYPE &v) 178812854Sgabeblack@google.com{ 178912854Sgabeblack@google.com return (operator < (u, v) || operator == (u, v)); 179012854Sgabeblack@google.com} 179112854Sgabeblack@google.com 179212854Sgabeblack@google.com 179312854Sgabeblack@google.com// ---------------------------------------------------------------------------- 179412854Sgabeblack@google.com// SECTION: GREATER THAN operator: > 179512854Sgabeblack@google.com// ---------------------------------------------------------------------------- 179612854Sgabeblack@google.com 179712854Sgabeblack@google.combool 179812854Sgabeblack@google.comoperator > (const CLASS_TYPE &u, const CLASS_TYPE &v) 179912854Sgabeblack@google.com{ 180012854Sgabeblack@google.com return (!(operator <= (u, v))); 180112854Sgabeblack@google.com} 180212854Sgabeblack@google.com 180312854Sgabeblack@google.com 180412854Sgabeblack@google.combool 180512854Sgabeblack@google.comoperator > (const CLASS_TYPE &u, int64 v) 180612854Sgabeblack@google.com{ 180712854Sgabeblack@google.com return (!(operator <= (u, v))); 180812854Sgabeblack@google.com} 180912854Sgabeblack@google.com 181012854Sgabeblack@google.com 181112854Sgabeblack@google.combool 181212854Sgabeblack@google.comoperator > (int64 u, const CLASS_TYPE &v) 181312854Sgabeblack@google.com{ 181412854Sgabeblack@google.com return (!(operator <= (u, v))); 181512854Sgabeblack@google.com} 181612854Sgabeblack@google.com 181712854Sgabeblack@google.com 181812854Sgabeblack@google.combool 181912854Sgabeblack@google.comoperator > (const CLASS_TYPE &u, uint64 v) 182012854Sgabeblack@google.com{ 182112854Sgabeblack@google.com return (!(operator <= (u, v))); 182212854Sgabeblack@google.com} 182312854Sgabeblack@google.com 182412854Sgabeblack@google.com 182512854Sgabeblack@google.combool 182612854Sgabeblack@google.comoperator > (uint64 u, const CLASS_TYPE &v) 182712854Sgabeblack@google.com{ 182812854Sgabeblack@google.com return (!(operator <= (u, v))); 182912854Sgabeblack@google.com} 183012854Sgabeblack@google.com 183112854Sgabeblack@google.com 183212854Sgabeblack@google.combool 183312854Sgabeblack@google.comoperator > (const CLASS_TYPE &u, long v) 183412854Sgabeblack@google.com{ 183512854Sgabeblack@google.com return (!(operator <= (u, v))); 183612854Sgabeblack@google.com} 183712854Sgabeblack@google.com 183812854Sgabeblack@google.com 183912854Sgabeblack@google.combool 184012854Sgabeblack@google.comoperator > (long u, const CLASS_TYPE &v) 184112854Sgabeblack@google.com{ 184212854Sgabeblack@google.com return (!(operator <= (u, v))); 184312854Sgabeblack@google.com} 184412854Sgabeblack@google.com 184512854Sgabeblack@google.com 184612854Sgabeblack@google.combool 184712854Sgabeblack@google.comoperator > (const CLASS_TYPE &u, unsigned long v) 184812854Sgabeblack@google.com{ 184912854Sgabeblack@google.com return (!(operator <= (u, v))); 185012854Sgabeblack@google.com} 185112854Sgabeblack@google.com 185212854Sgabeblack@google.com 185312854Sgabeblack@google.combool 185412854Sgabeblack@google.comoperator > (unsigned long u, const CLASS_TYPE &v) 185512854Sgabeblack@google.com{ 185612854Sgabeblack@google.com return (!(operator <= (u, v))); 185712854Sgabeblack@google.com} 185812854Sgabeblack@google.com 185912854Sgabeblack@google.com 186012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 186112854Sgabeblack@google.com// SECTION: GREATER THAN or EQUAL operator: >= 186212854Sgabeblack@google.com// ---------------------------------------------------------------------------- 186312854Sgabeblack@google.com 186412854Sgabeblack@google.combool 186512854Sgabeblack@google.comoperator >= (const CLASS_TYPE &u, const CLASS_TYPE &v) 186612854Sgabeblack@google.com{ 186712854Sgabeblack@google.com return (!(operator < (u, v))); 186812854Sgabeblack@google.com} 186912854Sgabeblack@google.com 187012854Sgabeblack@google.com 187112854Sgabeblack@google.combool 187212854Sgabeblack@google.comoperator >= (const CLASS_TYPE &u, int64 v) 187312854Sgabeblack@google.com{ 187412854Sgabeblack@google.com return (!(operator < (u, v))); 187512854Sgabeblack@google.com} 187612854Sgabeblack@google.com 187712854Sgabeblack@google.com 187812854Sgabeblack@google.combool 187912854Sgabeblack@google.comoperator >= (int64 u, const CLASS_TYPE &v) 188012854Sgabeblack@google.com{ 188112854Sgabeblack@google.com return (!(operator < (u, v))); 188212854Sgabeblack@google.com} 188312854Sgabeblack@google.com 188412854Sgabeblack@google.com 188512854Sgabeblack@google.combool 188612854Sgabeblack@google.comoperator >= (const CLASS_TYPE &u, uint64 v) 188712854Sgabeblack@google.com{ 188812854Sgabeblack@google.com return (!(operator < (u, v))); 188912854Sgabeblack@google.com} 189012854Sgabeblack@google.com 189112854Sgabeblack@google.com 189212854Sgabeblack@google.combool 189312854Sgabeblack@google.comoperator >= (uint64 u, const CLASS_TYPE &v) 189412854Sgabeblack@google.com{ 189512854Sgabeblack@google.com return (!(operator < (u, v))); 189612854Sgabeblack@google.com} 189712854Sgabeblack@google.com 189812854Sgabeblack@google.com 189912854Sgabeblack@google.combool 190012854Sgabeblack@google.comoperator >= (const CLASS_TYPE &u, long v) 190112854Sgabeblack@google.com{ 190212854Sgabeblack@google.com return (!(operator < (u, v))); 190312854Sgabeblack@google.com} 190412854Sgabeblack@google.com 190512854Sgabeblack@google.com 190612854Sgabeblack@google.combool 190712854Sgabeblack@google.comoperator >= (long u, const CLASS_TYPE &v) 190812854Sgabeblack@google.com{ 190912854Sgabeblack@google.com return (!(operator < (u, v))); 191012854Sgabeblack@google.com} 191112854Sgabeblack@google.com 191212854Sgabeblack@google.com 191312854Sgabeblack@google.combool 191412854Sgabeblack@google.comoperator >= (const CLASS_TYPE &u, unsigned long v) 191512854Sgabeblack@google.com{ 191612854Sgabeblack@google.com return (!(operator < (u, v))); 191712854Sgabeblack@google.com} 191812854Sgabeblack@google.com 191912854Sgabeblack@google.com 192012854Sgabeblack@google.combool 192112854Sgabeblack@google.comoperator >= (unsigned long u, const CLASS_TYPE &v) 192212854Sgabeblack@google.com{ 192312854Sgabeblack@google.com return (!(operator < (u, v))); 192412854Sgabeblack@google.com} 192512854Sgabeblack@google.com 192612854Sgabeblack@google.com 192712854Sgabeblack@google.com// ---------------------------------------------------------------------------- 192812854Sgabeblack@google.com// SECTION: Public members - Other utils. 192912854Sgabeblack@google.com// ---------------------------------------------------------------------------- 193012854Sgabeblack@google.com 193112854Sgabeblack@google.com// Convert to int64, long, or int. 193212854Sgabeblack@google.com#define TO_INTX(RET_TYPE, UP_RET_TYPE) \ 193312854Sgabeblack@google.comif (sgn == SC_ZERO) \ 193412854Sgabeblack@google.com return 0; \ 193512854Sgabeblack@google.comint vnd = sc_min((int)DIGITS_PER_ ## UP_RET_TYPE, ndigits); \ 193612854Sgabeblack@google.comRET_TYPE v = 0; \ 193712854Sgabeblack@google.comwhile (--vnd >= 0) \ 193812854Sgabeblack@google.com v = (v << BITS_PER_DIGIT) + digit[vnd]; \ 193912854Sgabeblack@google.comif (sgn == SC_NEG) \ 194012854Sgabeblack@google.com return -v; \ 194112854Sgabeblack@google.comelse \ 194212854Sgabeblack@google.com return v; 194312854Sgabeblack@google.com 194412854Sgabeblack@google.com 194512854Sgabeblack@google.comint64 194612854Sgabeblack@google.comCLASS_TYPE::to_int64() const 194712854Sgabeblack@google.com{ 194812854Sgabeblack@google.com TO_INTX(int64, INT64); 194912854Sgabeblack@google.com} 195012854Sgabeblack@google.com 195112854Sgabeblack@google.com 195212854Sgabeblack@google.comlong 195312854Sgabeblack@google.comCLASS_TYPE::to_long() const 195412854Sgabeblack@google.com{ 195512854Sgabeblack@google.com TO_INTX(long, LONG); 195612854Sgabeblack@google.com} 195712854Sgabeblack@google.com 195812854Sgabeblack@google.com 195912854Sgabeblack@google.comint 196012854Sgabeblack@google.comCLASS_TYPE::to_int() const 196112854Sgabeblack@google.com{ 196212854Sgabeblack@google.com TO_INTX(int, INT); 196312854Sgabeblack@google.com} 196412854Sgabeblack@google.com 196512854Sgabeblack@google.com 196612854Sgabeblack@google.com// Convert to unsigned int64, unsigned long or unsigned 196712854Sgabeblack@google.com// int. to_uint64, to_ulong, and to_uint have the same body except for 196812854Sgabeblack@google.com// the type of v defined inside. 196912854Sgabeblack@google.comuint64 197012854Sgabeblack@google.comCLASS_TYPE::to_uint64() const 197112854Sgabeblack@google.com{ 197212854Sgabeblack@google.com if (sgn == SC_ZERO) 197312854Sgabeblack@google.com return 0; 197412854Sgabeblack@google.com 197512854Sgabeblack@google.com int vnd = sc_min((int)DIGITS_PER_INT64, ndigits); 197612854Sgabeblack@google.com 197712854Sgabeblack@google.com uint64 v = 0; 197812854Sgabeblack@google.com 197912854Sgabeblack@google.com if (sgn == SC_NEG) { 198012854Sgabeblack@google.com#ifdef SC_MAX_NBITS 198112854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 198212854Sgabeblack@google.com#else 198312854Sgabeblack@google.com sc_digit *d = new sc_digit[ndigits]; 198412854Sgabeblack@google.com#endif 198512854Sgabeblack@google.com vec_copy(ndigits, d, digit); 198612854Sgabeblack@google.com convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); 198712854Sgabeblack@google.com while (--vnd >= 0) 198812854Sgabeblack@google.com v = (v << BITS_PER_DIGIT) + d[vnd]; 198912854Sgabeblack@google.com#ifndef SC_MAX_NBITS 199012854Sgabeblack@google.com delete [] d; 199112854Sgabeblack@google.com#endif 199212854Sgabeblack@google.com } else { 199312854Sgabeblack@google.com while (--vnd >= 0) 199412854Sgabeblack@google.com v = (v << BITS_PER_DIGIT) + digit[vnd]; 199512854Sgabeblack@google.com } 199612854Sgabeblack@google.com return v; 199712854Sgabeblack@google.com} 199812854Sgabeblack@google.com 199912854Sgabeblack@google.com 200012854Sgabeblack@google.comunsigned long 200112854Sgabeblack@google.comCLASS_TYPE::to_ulong() const 200212854Sgabeblack@google.com{ 200312854Sgabeblack@google.com if (sgn == SC_ZERO) 200412854Sgabeblack@google.com return 0; 200512854Sgabeblack@google.com 200612854Sgabeblack@google.com int vnd = sc_min((int)DIGITS_PER_LONG, ndigits); 200712854Sgabeblack@google.com unsigned long v = 0; 200812854Sgabeblack@google.com 200912854Sgabeblack@google.com if (sgn == SC_NEG) { 201012854Sgabeblack@google.com#ifdef SC_MAX_NBITS 201112854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 201212854Sgabeblack@google.com#else 201312854Sgabeblack@google.com sc_digit *d = new sc_digit[ndigits]; 201412854Sgabeblack@google.com#endif 201512854Sgabeblack@google.com vec_copy(ndigits, d, digit); 201612854Sgabeblack@google.com convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); 201712854Sgabeblack@google.com while (--vnd >= 0) 201812854Sgabeblack@google.com v = (v << BITS_PER_DIGIT) + d[vnd]; 201912854Sgabeblack@google.com#ifndef SC_MAX_NBITS 202012854Sgabeblack@google.com delete [] d; 202112854Sgabeblack@google.com#endif 202212854Sgabeblack@google.com } else { 202312854Sgabeblack@google.com while (--vnd >= 0) 202412854Sgabeblack@google.com v = (v << BITS_PER_DIGIT) + digit[vnd]; 202512854Sgabeblack@google.com } 202612854Sgabeblack@google.com return v; 202712854Sgabeblack@google.com} 202812854Sgabeblack@google.com 202912854Sgabeblack@google.com 203012854Sgabeblack@google.comunsigned int 203112854Sgabeblack@google.comCLASS_TYPE::to_uint() const 203212854Sgabeblack@google.com{ 203312854Sgabeblack@google.com if (sgn == SC_ZERO) 203412854Sgabeblack@google.com return 0; 203512854Sgabeblack@google.com 203612854Sgabeblack@google.com int vnd = sc_min((int)DIGITS_PER_INT, ndigits); 203712854Sgabeblack@google.com unsigned int v = 0; 203812854Sgabeblack@google.com if (sgn == SC_NEG) { 203912854Sgabeblack@google.com#ifdef SC_MAX_NBITS 204012854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 204112854Sgabeblack@google.com#else 204212854Sgabeblack@google.com sc_digit *d = new sc_digit[ndigits]; 204312854Sgabeblack@google.com#endif 204412854Sgabeblack@google.com vec_copy(ndigits, d, digit); 204512854Sgabeblack@google.com convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); 204612854Sgabeblack@google.com while (--vnd >= 0) 204712854Sgabeblack@google.com v = (v << BITS_PER_DIGIT) + d[vnd]; 204812854Sgabeblack@google.com#ifndef SC_MAX_NBITS 204912854Sgabeblack@google.com delete [] d; 205012854Sgabeblack@google.com#endif 205112854Sgabeblack@google.com } else { 205212854Sgabeblack@google.com while (--vnd >= 0) 205312854Sgabeblack@google.com v = (v << BITS_PER_DIGIT) + digit[vnd]; 205412854Sgabeblack@google.com } 205512854Sgabeblack@google.com return v; 205612854Sgabeblack@google.com} 205712854Sgabeblack@google.com 205812854Sgabeblack@google.com 205912854Sgabeblack@google.com// Convert to double. 206012854Sgabeblack@google.comdouble 206112854Sgabeblack@google.comCLASS_TYPE::to_double() const 206212854Sgabeblack@google.com{ 206312854Sgabeblack@google.com if (sgn == SC_ZERO) 206412854Sgabeblack@google.com return (double) 0.0; 206512854Sgabeblack@google.com 206612854Sgabeblack@google.com int vnd = ndigits; 206712854Sgabeblack@google.com double v = 0.0; 206812854Sgabeblack@google.com while (--vnd >= 0) 206912854Sgabeblack@google.com v = v * DIGIT_RADIX + digit[vnd]; 207012854Sgabeblack@google.com if (sgn == SC_NEG) 207112854Sgabeblack@google.com return -v; 207212854Sgabeblack@google.com else 207312854Sgabeblack@google.com return v; 207412854Sgabeblack@google.com} 207512854Sgabeblack@google.com 207612854Sgabeblack@google.com 207712854Sgabeblack@google.com// Return true if the bit i is 1, false otherwise. If i is outside the 207812854Sgabeblack@google.com// bounds, return 1/0 according to the sign of the number by assuming 207912854Sgabeblack@google.com// that the number has infinite length. 208012854Sgabeblack@google.com 208112854Sgabeblack@google.combool 208212854Sgabeblack@google.comCLASS_TYPE::test(int i) const 208312854Sgabeblack@google.com{ 208412854Sgabeblack@google.com#ifdef SC_SIGNED 208512854Sgabeblack@google.com if (check_if_outside(i)) { 208612854Sgabeblack@google.com if (sgn == SC_NEG) 208712854Sgabeblack@google.com return 1; 208812854Sgabeblack@google.com else 208912854Sgabeblack@google.com return 0; 209012854Sgabeblack@google.com } 209112854Sgabeblack@google.com#else 209212854Sgabeblack@google.com if (check_if_outside(i)) 209312854Sgabeblack@google.com return 0; 209412854Sgabeblack@google.com#endif 209512854Sgabeblack@google.com 209612854Sgabeblack@google.com int bit_num = bit_ord(i); 209712854Sgabeblack@google.com int digit_num = digit_ord(i); 209812854Sgabeblack@google.com 209912854Sgabeblack@google.com if (sgn == SC_NEG) { 210012854Sgabeblack@google.com#ifdef SC_MAX_NBITS 210112854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 210212854Sgabeblack@google.com#else 210312854Sgabeblack@google.com sc_digit *d = new sc_digit[ndigits]; 210412854Sgabeblack@google.com#endif 210512854Sgabeblack@google.com vec_copy(ndigits, d, digit); 210612854Sgabeblack@google.com vec_complement(ndigits, d); 210712854Sgabeblack@google.com bool val = ((d[digit_num] & one_and_zeros(bit_num)) != 0); 210812854Sgabeblack@google.com#ifndef SC_MAX_NBITS 210912854Sgabeblack@google.com delete [] d; 211012854Sgabeblack@google.com#endif 211112854Sgabeblack@google.com return val; 211212854Sgabeblack@google.com } else { 211312854Sgabeblack@google.com return ((digit[digit_num] & one_and_zeros(bit_num)) != 0); 211412854Sgabeblack@google.com } 211512854Sgabeblack@google.com} 211612854Sgabeblack@google.com 211712854Sgabeblack@google.com 211812854Sgabeblack@google.com// Set the ith bit with 1. 211912854Sgabeblack@google.comvoid 212012854Sgabeblack@google.comCLASS_TYPE::set(int i) 212112854Sgabeblack@google.com{ 212212854Sgabeblack@google.com if (check_if_outside(i)) 212312854Sgabeblack@google.com return; 212412854Sgabeblack@google.com 212512854Sgabeblack@google.com int bit_num = bit_ord(i); 212612854Sgabeblack@google.com int digit_num = digit_ord(i); 212712854Sgabeblack@google.com 212812854Sgabeblack@google.com convert_SM_to_2C(); 212912854Sgabeblack@google.com digit[digit_num] |= one_and_zeros(bit_num); 213012854Sgabeblack@google.com digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits. 213112854Sgabeblack@google.com convert_2C_to_SM(); 213212854Sgabeblack@google.com} 213312854Sgabeblack@google.com 213412854Sgabeblack@google.com 213512854Sgabeblack@google.com// Set the ith bit with 0, i.e., clear the ith bit. 213612854Sgabeblack@google.comvoid 213712854Sgabeblack@google.comCLASS_TYPE::clear(int i) 213812854Sgabeblack@google.com{ 213912854Sgabeblack@google.com if (check_if_outside(i)) 214012854Sgabeblack@google.com return; 214112854Sgabeblack@google.com 214212854Sgabeblack@google.com int bit_num = bit_ord(i); 214312854Sgabeblack@google.com int digit_num = digit_ord(i); 214412854Sgabeblack@google.com 214512854Sgabeblack@google.com convert_SM_to_2C(); 214612854Sgabeblack@google.com digit[digit_num] &= ~(one_and_zeros(bit_num)); 214712854Sgabeblack@google.com digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits. 214812854Sgabeblack@google.com convert_2C_to_SM(); 214912854Sgabeblack@google.com} 215012854Sgabeblack@google.com 215112854Sgabeblack@google.com 215212854Sgabeblack@google.com// Create a mirror image of the number. 215312854Sgabeblack@google.comvoid 215412854Sgabeblack@google.comCLASS_TYPE::reverse() 215512854Sgabeblack@google.com{ 215612854Sgabeblack@google.com convert_SM_to_2C(); 215712854Sgabeblack@google.com vec_reverse(length(), ndigits, digit, length() - 1); 215812854Sgabeblack@google.com convert_2C_to_SM(); 215912854Sgabeblack@google.com} 216012854Sgabeblack@google.com 216112854Sgabeblack@google.com 216212854Sgabeblack@google.com// Get a packed bit representation of the number. 216312854Sgabeblack@google.comvoid 216412854Sgabeblack@google.comCLASS_TYPE::get_packed_rep(sc_digit *buf) const 216512854Sgabeblack@google.com{ 216612854Sgabeblack@google.com int buf_ndigits = (length() - 1) / BITS_PER_DIGIT_TYPE + 1; 216712854Sgabeblack@google.com // Initialize buf to zero. 216812854Sgabeblack@google.com vec_zero(buf_ndigits, buf); 216912854Sgabeblack@google.com 217012854Sgabeblack@google.com if (sgn == SC_ZERO) 217112854Sgabeblack@google.com return; 217212854Sgabeblack@google.com 217312854Sgabeblack@google.com const sc_digit *digit_or_d; 217412854Sgabeblack@google.com#ifdef SC_MAX_NBITS 217512854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 217612854Sgabeblack@google.com#else 217712854Sgabeblack@google.com sc_digit *d = new sc_digit[ndigits]; 217812854Sgabeblack@google.com#endif 217912854Sgabeblack@google.com 218012854Sgabeblack@google.com if (sgn == SC_POS) { 218112854Sgabeblack@google.com digit_or_d = digit; 218212854Sgabeblack@google.com } else { 218312854Sgabeblack@google.com // If sgn is negative, we have to convert digit to its 2's 218412854Sgabeblack@google.com // complement. Since this function is const, we can not do it on 218512854Sgabeblack@google.com // digit. Since buf doesn't have overflow bits, we cannot also do 218612854Sgabeblack@google.com // it on buf. Thus, we have to do the complementation on a copy of 218712854Sgabeblack@google.com // digit, i.e., on d. 218812854Sgabeblack@google.com 218912854Sgabeblack@google.com vec_copy(ndigits, d, digit); 219012854Sgabeblack@google.com vec_complement(ndigits, d); 219112854Sgabeblack@google.com buf[buf_ndigits - 1] = ~((sc_digit) 0); 219212854Sgabeblack@google.com digit_or_d = d; 219312854Sgabeblack@google.com } 219412854Sgabeblack@google.com 219512854Sgabeblack@google.com // Copy the bits from digit to buf. The division and mod operations 219612854Sgabeblack@google.com // below can be converted to addition/subtraction and comparison 219712854Sgabeblack@google.com // operations at the expense of complicating the code. We can do it 219812854Sgabeblack@google.com // if we see any performance problems. 219912854Sgabeblack@google.com 220012854Sgabeblack@google.com for (int i = length() - 1; i >= 0; --i) { 220112854Sgabeblack@google.com 220212854Sgabeblack@google.com if ((digit_or_d[digit_ord(i)] & 220312854Sgabeblack@google.com one_and_zeros(bit_ord(i))) != 0) { // Test. 220412854Sgabeblack@google.com buf[i / BITS_PER_DIGIT_TYPE] |= 220512854Sgabeblack@google.com one_and_zeros(i % BITS_PER_DIGIT_TYPE); // Set. 220612854Sgabeblack@google.com } else { 220712854Sgabeblack@google.com buf[i / BITS_PER_DIGIT_TYPE] &= 220812854Sgabeblack@google.com ~(one_and_zeros(i % BITS_PER_DIGIT_TYPE)); // Clear. 220912854Sgabeblack@google.com } 221012854Sgabeblack@google.com } 221112854Sgabeblack@google.com 221212854Sgabeblack@google.com#ifndef SC_MAX_NBITS 221312854Sgabeblack@google.com delete[] d; 221412854Sgabeblack@google.com#endif 221512854Sgabeblack@google.com} 221612854Sgabeblack@google.com 221712854Sgabeblack@google.com 221812854Sgabeblack@google.com// Set a packed bit representation of the number. 221912854Sgabeblack@google.comvoid 222012854Sgabeblack@google.comCLASS_TYPE::set_packed_rep(sc_digit *buf) 222112854Sgabeblack@google.com{ 222212854Sgabeblack@google.com // Initialize digit to zero. 222312854Sgabeblack@google.com vec_zero(ndigits, digit); 222412854Sgabeblack@google.com 222512854Sgabeblack@google.com // Copy the bits from buf to digit. 222612854Sgabeblack@google.com for (int i = length() - 1; i >= 0; --i) { 222712854Sgabeblack@google.com if ((buf[i / BITS_PER_DIGIT_TYPE] & 222812854Sgabeblack@google.com one_and_zeros(i % BITS_PER_DIGIT_TYPE)) != 0) { // Test. 222912854Sgabeblack@google.com digit[digit_ord(i)] |= one_and_zeros(bit_ord(i)); // Set. 223012854Sgabeblack@google.com } else { 223112854Sgabeblack@google.com digit[digit_ord(i)] &= ~(one_and_zeros(bit_ord(i))); // Clear 223212854Sgabeblack@google.com } 223312854Sgabeblack@google.com } 223412854Sgabeblack@google.com convert_2C_to_SM(); 223512854Sgabeblack@google.com} 223612854Sgabeblack@google.com 223712854Sgabeblack@google.com 223812854Sgabeblack@google.com// ---------------------------------------------------------------------------- 223912854Sgabeblack@google.com// SECTION: Private members. 224012854Sgabeblack@google.com// ---------------------------------------------------------------------------- 224112854Sgabeblack@google.com 224212854Sgabeblack@google.com// Create a copy of v with sgn s. 224312854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const CLASS_TYPE &v, small_type s) : 224412854Sgabeblack@google.com sc_value_base(v), sgn(s), nbits(v.nbits), ndigits(v.ndigits), digit() 224512854Sgabeblack@google.com{ 224612854Sgabeblack@google.com#ifndef SC_MAX_NBITS 224712854Sgabeblack@google.com digit = new sc_digit[ndigits]; 224812854Sgabeblack@google.com#endif 224912854Sgabeblack@google.com vec_copy(ndigits, digit, v.digit); 225012854Sgabeblack@google.com} 225112854Sgabeblack@google.com 225212854Sgabeblack@google.com 225312854Sgabeblack@google.com// Create a copy of v where v is of the different type. 225412854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE &v, small_type s) : 225512854Sgabeblack@google.com sc_value_base(v), sgn(s), nbits(num_bits(v.nbits)), ndigits(), digit() 225612854Sgabeblack@google.com{ 225712854Sgabeblack@google.com#if (IF_SC_SIGNED == 1) 225812854Sgabeblack@google.com ndigits = v.ndigits; 225912854Sgabeblack@google.com#else 226012854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 226112854Sgabeblack@google.com#endif 226212854Sgabeblack@google.com 226312854Sgabeblack@google.com#ifndef SC_MAX_NBITS 226412854Sgabeblack@google.com digit = new sc_digit[ndigits]; 226512854Sgabeblack@google.com#endif 226612854Sgabeblack@google.com 226712854Sgabeblack@google.com copy_digits(v.nbits, v.ndigits, v.digit); 226812854Sgabeblack@google.com} 226912854Sgabeblack@google.com 227012854Sgabeblack@google.com 227112854Sgabeblack@google.com// Create a signed number with (s, nb, nd, d) as its attributes (as 227212854Sgabeblack@google.com// defined in class CLASS_TYPE). If alloc is set, delete d. 227312854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE( 227412854Sgabeblack@google.com small_type s, int nb, int nd, sc_digit *d, bool alloc) : 227512854Sgabeblack@google.com sc_value_base(), sgn(s), nbits(num_bits(nb)), ndigits(), digit() 227612854Sgabeblack@google.com{ 227712854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 227812854Sgabeblack@google.com#ifndef SC_MAX_NBITS 227912854Sgabeblack@google.com digit = new sc_digit[ndigits]; 228012854Sgabeblack@google.com#endif 228112854Sgabeblack@google.com 228212854Sgabeblack@google.com if (ndigits <= nd) 228312854Sgabeblack@google.com vec_copy(ndigits, digit, d); 228412854Sgabeblack@google.com else 228512854Sgabeblack@google.com vec_copy_and_zero(ndigits, digit, nd, d); 228612854Sgabeblack@google.com 228712854Sgabeblack@google.com#ifndef SC_MAX_NBITS 228812854Sgabeblack@google.com if (alloc) 228912854Sgabeblack@google.com delete [] d; 229012854Sgabeblack@google.com#endif 229112854Sgabeblack@google.com} 229212854Sgabeblack@google.com 229312854Sgabeblack@google.com// This constructor is mainly used in finding a "range" of bits from a 229412854Sgabeblack@google.com// number of type CLASS_TYPE. The function range(l, r) can have 229512854Sgabeblack@google.com// arbitrary precedence between l and r. If l is smaller than r, then 229612854Sgabeblack@google.com// the output is the reverse of range(r, l). 229712854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const CLASS_TYPE *u, int l, int r) : 229812854Sgabeblack@google.com sc_value_base(), sgn(), nbits(), ndigits(), digit() 229912854Sgabeblack@google.com{ 230012854Sgabeblack@google.com bool reversed = false; 230112854Sgabeblack@google.com 230212854Sgabeblack@google.com if (l < r) { 230312854Sgabeblack@google.com reversed = true; 230412854Sgabeblack@google.com int tmp = l; 230512854Sgabeblack@google.com l = r; 230612854Sgabeblack@google.com r = tmp; 230712854Sgabeblack@google.com } 230812854Sgabeblack@google.com 230912854Sgabeblack@google.com // at this point, l >= r 231012854Sgabeblack@google.com 231112854Sgabeblack@google.com // make sure that l and r point to the bits of u 231212854Sgabeblack@google.com r = sc_max(r, 0); 231312854Sgabeblack@google.com l = sc_min(l, u->nbits - 1); 231412854Sgabeblack@google.com 231512854Sgabeblack@google.com nbits = num_bits(l - r + 1); 231612854Sgabeblack@google.com 231712854Sgabeblack@google.com // nbits can still be <= 0 because l and r have just been updated 231812854Sgabeblack@google.com // with the bounds of u. 231912854Sgabeblack@google.com 232012854Sgabeblack@google.com // if u == 0 or the range is out of bounds, return 0 232112854Sgabeblack@google.com if (u->sgn == SC_ZERO || nbits <= num_bits(0)) { 232212854Sgabeblack@google.com sgn = SC_ZERO; 232312854Sgabeblack@google.com if (nbits <= num_bits(0)) { 232412854Sgabeblack@google.com nbits = 1; 232512854Sgabeblack@google.com } 232612854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 232712854Sgabeblack@google.com#ifndef SC_MAX_NBITS 232812854Sgabeblack@google.com digit = new sc_digit[ndigits]; 232912854Sgabeblack@google.com#endif 233012854Sgabeblack@google.com vec_zero(ndigits, digit); 233112854Sgabeblack@google.com return; 233212854Sgabeblack@google.com } 233312854Sgabeblack@google.com 233412854Sgabeblack@google.com // The rest will be executed if u is not zero. 233512854Sgabeblack@google.com 233612854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 233712854Sgabeblack@google.com 233812854Sgabeblack@google.com // The number of bits up to and including l and r, respectively. 233912854Sgabeblack@google.com int nl = l + 1; 234012854Sgabeblack@google.com int nr = r + 1; 234112854Sgabeblack@google.com 234212854Sgabeblack@google.com // The indices of the digits that have lth and rth bits, respectively. 234312854Sgabeblack@google.com int left_digit = DIV_CEIL(nl) - 1; 234412854Sgabeblack@google.com int right_digit = DIV_CEIL(nr) - 1; 234512854Sgabeblack@google.com 234612854Sgabeblack@google.com int nd; 234712854Sgabeblack@google.com 234812854Sgabeblack@google.com // The range is performed on the 2's complement representation, so 234912854Sgabeblack@google.com // first get the indices for that. 235012854Sgabeblack@google.com if (u->sgn == SC_NEG) 235112854Sgabeblack@google.com nd = left_digit + 1; 235212854Sgabeblack@google.com else 235312854Sgabeblack@google.com nd = left_digit - right_digit + 1; 235412854Sgabeblack@google.com 235512854Sgabeblack@google.com // Allocate memory for the range. 235612854Sgabeblack@google.com#ifdef SC_MAX_NBITS 235712854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 235812854Sgabeblack@google.com#else 235912854Sgabeblack@google.com digit = new sc_digit[ndigits]; 236012854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 236112854Sgabeblack@google.com#endif 236212854Sgabeblack@google.com 236312854Sgabeblack@google.com // Getting the range on the 2's complement representation. 236412854Sgabeblack@google.com if (u->sgn == SC_NEG) { 236512854Sgabeblack@google.com vec_copy(nd, d, u->digit); 236612854Sgabeblack@google.com vec_complement(nd, d); // d = -d; 236712854Sgabeblack@google.com vec_shift_right(nd, d, r, DIGIT_MASK); 236812854Sgabeblack@google.com } else { 236912854Sgabeblack@google.com for (int i = right_digit; i <= left_digit; ++i) 237012854Sgabeblack@google.com d[i - right_digit] = u->digit[i]; 237112854Sgabeblack@google.com vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0); 237212854Sgabeblack@google.com } 237312854Sgabeblack@google.com 237412854Sgabeblack@google.com vec_zero(ndigits, digit); 237512854Sgabeblack@google.com 237612854Sgabeblack@google.com if (!reversed) { 237712854Sgabeblack@google.com vec_copy(sc_min(nd, ndigits), digit, d); 237812854Sgabeblack@google.com } else { 237912854Sgabeblack@google.com // If l < r, i.e., reversed is set, reverse the bits of digit. d 238012854Sgabeblack@google.com // will be used as a temporary store. The following code tries to 238112854Sgabeblack@google.com // minimize the use of bit_ord and digit_ord, which use mod and 238212854Sgabeblack@google.com // div operators. Since these operators are function calls to 238312854Sgabeblack@google.com // standard library routines, they are slow. The main idea in 238412854Sgabeblack@google.com // reversing is "read bits out of d from left to right and push 238512854Sgabeblack@google.com // them into digit using right shifting." 238612854Sgabeblack@google.com 238712854Sgabeblack@google.com // Take care of the last digit. 238812854Sgabeblack@google.com int nd_less_1 = nd - 1; 238912854Sgabeblack@google.com 239012854Sgabeblack@google.com // Deletions will start from the left end and move one position 239112854Sgabeblack@google.com // after each deletion. 239212854Sgabeblack@google.com sc_digit del_mask = one_and_zeros(bit_ord(l - r)); 239312854Sgabeblack@google.com 239412854Sgabeblack@google.com while (del_mask) { 239512854Sgabeblack@google.com vec_shift_right(ndigits, digit, 1, 239612854Sgabeblack@google.com ((d[nd_less_1] & del_mask) != 0)); 239712854Sgabeblack@google.com del_mask >>= 1; 239812854Sgabeblack@google.com } 239912854Sgabeblack@google.com 240012854Sgabeblack@google.com // Take care of the other digits if any. 240112854Sgabeblack@google.com 240212854Sgabeblack@google.com // Insertion to digit will always occur at the left end. 240312854Sgabeblack@google.com sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1); 240412854Sgabeblack@google.com 240512854Sgabeblack@google.com for (int j = nd - 2; j >= 0; --j) { // j = nd - 2 240612854Sgabeblack@google.com // Deletions will start from the left end and move one position 240712854Sgabeblack@google.com // after each deletion. 240812854Sgabeblack@google.com del_mask = ins_mask; 240912854Sgabeblack@google.com while (del_mask) { 241012854Sgabeblack@google.com vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0)); 241112854Sgabeblack@google.com del_mask >>= 1; 241212854Sgabeblack@google.com } 241312854Sgabeblack@google.com } 241412854Sgabeblack@google.com 241512854Sgabeblack@google.com if (u->sgn == SC_NEG) 241612854Sgabeblack@google.com vec_shift_right(ndigits, digit, 241712854Sgabeblack@google.com ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK); 241812854Sgabeblack@google.com else 241912854Sgabeblack@google.com vec_shift_right(ndigits, digit, 242012854Sgabeblack@google.com ndigits * BITS_PER_DIGIT - length(), 0); 242112854Sgabeblack@google.com 242212854Sgabeblack@google.com 242312854Sgabeblack@google.com } // if reversed. 242412854Sgabeblack@google.com 242512854Sgabeblack@google.com convert_2C_to_SM(); 242612854Sgabeblack@google.com 242712854Sgabeblack@google.com#ifndef SC_MAX_NBITS 242812854Sgabeblack@google.com delete [] d; 242912854Sgabeblack@google.com#endif 243012854Sgabeblack@google.com} 243112854Sgabeblack@google.com 243212854Sgabeblack@google.com// This constructor is mainly used in finding a "range" of bits from a 243312854Sgabeblack@google.com// number of type OTHER_CLASS_TYPE. The function range(l, r) can have 243412854Sgabeblack@google.com// arbitrary precedence between l and r. If l is smaller than r, then 243512854Sgabeblack@google.com// the output is the reverse of range(r, l). 243612854Sgabeblack@google.comCLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE *u, int l, int r) : 243712854Sgabeblack@google.com sc_value_base(), sgn(), nbits(), ndigits(), digit() 243812854Sgabeblack@google.com{ 243912854Sgabeblack@google.com bool reversed = false; 244012854Sgabeblack@google.com 244112854Sgabeblack@google.com if (l < r) { 244212854Sgabeblack@google.com reversed = true; 244312854Sgabeblack@google.com int tmp = l; 244412854Sgabeblack@google.com l = r; 244512854Sgabeblack@google.com r = tmp; 244612854Sgabeblack@google.com } 244712854Sgabeblack@google.com 244812854Sgabeblack@google.com // at this point, l >= r 244912854Sgabeblack@google.com 245012854Sgabeblack@google.com // make sure that l and r point to the bits of u 245112854Sgabeblack@google.com r = sc_max(r, 0); 245212854Sgabeblack@google.com l = sc_min(l, u->nbits - 1); 245312854Sgabeblack@google.com 245412854Sgabeblack@google.com nbits = num_bits(l - r + 1); 245512854Sgabeblack@google.com 245612854Sgabeblack@google.com // nbits can still be <= 0 because l and r have just been updated 245712854Sgabeblack@google.com // with the bounds of u. 245812854Sgabeblack@google.com 245912854Sgabeblack@google.com // if u == 0 or the range is out of bounds, return 0 246012854Sgabeblack@google.com if (u->sgn == SC_ZERO || nbits <= num_bits(0)) { 246112854Sgabeblack@google.com sgn = SC_ZERO; 246212854Sgabeblack@google.com if (nbits <= num_bits(0)) { 246312854Sgabeblack@google.com nbits = 1; 246412854Sgabeblack@google.com } 246512854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 246612854Sgabeblack@google.com#ifndef SC_MAX_NBITS 246712854Sgabeblack@google.com digit = new sc_digit[ndigits]; 246812854Sgabeblack@google.com#endif 246912854Sgabeblack@google.com vec_zero(ndigits, digit); 247012854Sgabeblack@google.com return; 247112854Sgabeblack@google.com } 247212854Sgabeblack@google.com 247312854Sgabeblack@google.com // The rest will be executed if u is not zero. 247412854Sgabeblack@google.com 247512854Sgabeblack@google.com ndigits = DIV_CEIL(nbits); 247612854Sgabeblack@google.com 247712854Sgabeblack@google.com // The number of bits up to and including l and r, respectively. 247812854Sgabeblack@google.com int nl = l + 1; 247912854Sgabeblack@google.com int nr = r + 1; 248012854Sgabeblack@google.com 248112854Sgabeblack@google.com // The indices of the digits that have lth and rth bits, respectively. 248212854Sgabeblack@google.com int left_digit = DIV_CEIL(nl) - 1; 248312854Sgabeblack@google.com int right_digit = DIV_CEIL(nr) - 1; 248412854Sgabeblack@google.com 248512854Sgabeblack@google.com int nd; 248612854Sgabeblack@google.com 248712854Sgabeblack@google.com // The range is performed on the 2's complement representation, so 248812854Sgabeblack@google.com // first get the indices for that. 248912854Sgabeblack@google.com if (u->sgn == SC_NEG) 249012854Sgabeblack@google.com nd = left_digit + 1; 249112854Sgabeblack@google.com else 249212854Sgabeblack@google.com nd = left_digit - right_digit + 1; 249312854Sgabeblack@google.com 249412854Sgabeblack@google.com // Allocate memory for the range. 249512854Sgabeblack@google.com#ifdef SC_MAX_NBITS 249612854Sgabeblack@google.com sc_digit d[MAX_NDIGITS]; 249712854Sgabeblack@google.com#else 249812854Sgabeblack@google.com digit = new sc_digit[ndigits]; 249912854Sgabeblack@google.com sc_digit *d = new sc_digit[nd]; 250012854Sgabeblack@google.com#endif 250112854Sgabeblack@google.com 250212854Sgabeblack@google.com // Getting the range on the 2's complement representation. 250312854Sgabeblack@google.com if (u->sgn == SC_NEG) { 250412854Sgabeblack@google.com vec_copy(nd, d, u->digit); 250512854Sgabeblack@google.com vec_complement(nd, d); // d = -d; 250612854Sgabeblack@google.com vec_shift_right(nd, d, r, DIGIT_MASK); 250712854Sgabeblack@google.com } else { 250812854Sgabeblack@google.com for (int i = right_digit; i <= left_digit; ++i) 250912854Sgabeblack@google.com d[i - right_digit] = u->digit[i]; 251012854Sgabeblack@google.com vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0); 251112854Sgabeblack@google.com } 251212854Sgabeblack@google.com 251312854Sgabeblack@google.com vec_zero(ndigits, digit); 251412854Sgabeblack@google.com 251512854Sgabeblack@google.com if (!reversed) { 251612854Sgabeblack@google.com vec_copy(sc_min(nd, ndigits), digit, d); 251712854Sgabeblack@google.com } else { 251812854Sgabeblack@google.com // If l < r, i.e., reversed is set, reverse the bits of digit. d 251912854Sgabeblack@google.com // will be used as a temporary store. The following code tries to 252012854Sgabeblack@google.com // minimize the use of bit_ord and digit_ord, which use mod and 252112854Sgabeblack@google.com // div operators. Since these operators are function calls to 252212854Sgabeblack@google.com // standard library routines, they are slow. The main idea in 252312854Sgabeblack@google.com // reversing is "read bits out of d from left to right and push 252412854Sgabeblack@google.com // them into digit using right shifting." 252512854Sgabeblack@google.com 252612854Sgabeblack@google.com // Take care of the last digit. 252712854Sgabeblack@google.com int nd_less_1 = nd - 1; 252812854Sgabeblack@google.com 252912854Sgabeblack@google.com // Deletions will start from the left end and move one position 253012854Sgabeblack@google.com // after each deletion. 253112854Sgabeblack@google.com sc_digit del_mask = one_and_zeros(bit_ord(l - r)); 253212854Sgabeblack@google.com 253312854Sgabeblack@google.com while (del_mask) { 253412854Sgabeblack@google.com vec_shift_right(ndigits, digit, 1, 253512854Sgabeblack@google.com ((d[nd_less_1] & del_mask) != 0)); 253612854Sgabeblack@google.com del_mask >>= 1; 253712854Sgabeblack@google.com } 253812854Sgabeblack@google.com 253912854Sgabeblack@google.com // Take care of the other digits if any. 254012854Sgabeblack@google.com 254112854Sgabeblack@google.com // Insertion to digit will always occur at the left end. 254212854Sgabeblack@google.com sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1); 254312854Sgabeblack@google.com 254412854Sgabeblack@google.com for (int j = nd - 2; j >= 0; --j) { // j = nd - 2 254512854Sgabeblack@google.com // Deletions will start from the left end and move one position 254612854Sgabeblack@google.com // after each deletion. 254712854Sgabeblack@google.com del_mask = ins_mask; 254812854Sgabeblack@google.com 254912854Sgabeblack@google.com while (del_mask) { 255012854Sgabeblack@google.com vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0)); 255112854Sgabeblack@google.com del_mask >>= 1; 255212854Sgabeblack@google.com } 255312854Sgabeblack@google.com } 255412854Sgabeblack@google.com 255512854Sgabeblack@google.com if (u->sgn == SC_NEG) 255612854Sgabeblack@google.com vec_shift_right(ndigits, digit, 255712854Sgabeblack@google.com ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK); 255812854Sgabeblack@google.com else 255912854Sgabeblack@google.com vec_shift_right(ndigits, digit, 256012854Sgabeblack@google.com ndigits * BITS_PER_DIGIT - length(), 0); 256112854Sgabeblack@google.com 256212854Sgabeblack@google.com 256312854Sgabeblack@google.com } // if reversed. 256412854Sgabeblack@google.com 256512854Sgabeblack@google.com convert_2C_to_SM(); 256612854Sgabeblack@google.com 256712854Sgabeblack@google.com#ifndef SC_MAX_NBITS 256812854Sgabeblack@google.com delete [] d; 256912854Sgabeblack@google.com#endif 257012854Sgabeblack@google.com} 257112854Sgabeblack@google.com 257212854Sgabeblack@google.com 257312854Sgabeblack@google.com// Print out all the physical attributes. 257412854Sgabeblack@google.comvoid 257512854Sgabeblack@google.comCLASS_TYPE::dump(::std::ostream &os) const 257612854Sgabeblack@google.com{ 257712854Sgabeblack@google.com // Save the current setting, and set the base to decimal. 257812854Sgabeblack@google.com ::std::ios::fmtflags old_flags = 257912854Sgabeblack@google.com os.setf(::std::ios::dec, ::std::ios::basefield); 258012854Sgabeblack@google.com 258112854Sgabeblack@google.com os << "width = " << length() << ::std::endl; 258212854Sgabeblack@google.com os << "value = " << *this << ::std::endl; 258312854Sgabeblack@google.com os << "bits = "; 258412854Sgabeblack@google.com 258512854Sgabeblack@google.com int len = length(); 258612854Sgabeblack@google.com 258712854Sgabeblack@google.com for (int i = len - 1; i >= 0; --i) { 258812854Sgabeblack@google.com os << "01"[test(i)]; 258912854Sgabeblack@google.com if (--len % 4 == 0) 259012854Sgabeblack@google.com os << " "; 259112854Sgabeblack@google.com } 259212854Sgabeblack@google.com 259312854Sgabeblack@google.com os << ::std::endl; 259412854Sgabeblack@google.com 259512854Sgabeblack@google.com // Restore old_flags. 259612854Sgabeblack@google.com os.setf(old_flags, ::std::ios::basefield); 259712854Sgabeblack@google.com} 259812854Sgabeblack@google.com 259912854Sgabeblack@google.com 260012854Sgabeblack@google.com// Checks to see if bit_num is out of bounds. 260112854Sgabeblack@google.combool 260212854Sgabeblack@google.comCLASS_TYPE::check_if_outside(int bit_num) const 260312854Sgabeblack@google.com{ 260412854Sgabeblack@google.com if ((bit_num < 0) || (num_bits(bit_num) >= nbits)) { 260512854Sgabeblack@google.com#ifdef DEBUG_SYSTEMC 260612854Sgabeblack@google.com if (bit_num < 0 || bit_num >= nbits) { 260712854Sgabeblack@google.com std::stringstream msg; 260812854Sgabeblack@google.com msg << CLASS_TYPE_STR "::check_if_outside(int bit_num) : " 260912854Sgabeblack@google.com "bit_num = " << bit_num << " is out of bounds"; 261012854Sgabeblack@google.com SC_REPORT_WARNING(sc_core::SC_ID_OUT_OF_BOUNDS_, 261112854Sgabeblack@google.com msg.str().c_str()); 261212854Sgabeblack@google.com } 261312854Sgabeblack@google.com#endif 261412854Sgabeblack@google.com return true; 261512854Sgabeblack@google.com } 261612854Sgabeblack@google.com return false; 261712854Sgabeblack@google.com} 2618