Library for big numbers from http://www.ttmath.org/

Dependents:   PIDHeater82 Conceptcontroller_v_1_0 AlarmClockApp COG4050_adxl355_tilt ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ttmathuint.h Source File

ttmathuint.h

Go to the documentation of this file.
00001 /*
00002  * This file is a part of TTMath Bignum Library
00003  * and is distributed under the (new) BSD licence.
00004  * Author: Tomasz Sowa <t.sowa@ttmath.org>
00005  */
00006 
00007 /* 
00008  * Copyright (c) 2006-2011, Tomasz Sowa
00009  * All rights reserved.
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are met:
00013  * 
00014  *  * Redistributions of source code must retain the above copyright notice,
00015  *    this list of conditions and the following disclaimer.
00016  *    
00017  *  * Redistributions in binary form must reproduce the above copyright
00018  *    notice, this list of conditions and the following disclaimer in the
00019  *    documentation and/or other materials provided with the distribution.
00020  *    
00021  *  * Neither the name Tomasz Sowa nor the names of contributors to this
00022  *    project may be used to endorse or promote products derived
00023  *    from this software without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00035  * THE POSSIBILITY OF SUCH DAMAGE.
00036  */
00037 
00038 
00039 
00040 #ifndef headerfilettmathuint
00041 #define headerfilettmathuint
00042 
00043 
00044 /*!
00045     \file ttmathuint.h
00046     \brief template class UInt<uint>
00047 */
00048 
00049 #include <iostream>
00050 #include <iomanip>
00051 
00052 
00053 #include "ttmathtypes.h"
00054 #include "ttmathmisc.h"
00055 
00056 
00057 
00058 /*!
00059     \brief a namespace for the TTMath library
00060 */
00061 namespace ttmath
00062 {
00063 
00064 /*! 
00065     \brief UInt implements a big integer value without a sign
00066 
00067     value_size - how many bytes specify our value
00068         on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
00069         on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
00070     value_size = 1,2,3,4,5,6....
00071 */
00072 template<uint value_size>
00073 class UInt
00074 {
00075 public:
00076 
00077     /*!
00078         buffer for the integer value
00079           table[0] - the lowest word of the value
00080     */
00081     uint  table [value_size];
00082 
00083 
00084 
00085     /*!
00086         some methods used for debugging purposes
00087     */
00088 
00089 
00090     /*!
00091         this method is only for debugging purposes or when we want to make
00092         a table of a variable (constant) in ttmathbig.h
00093 
00094         it prints the table in a nice form of several columns
00095     */
00096     template<class ostream_type>
00097     void PrintTable (ostream_type & output) const
00098     {
00099         // how many columns there'll be
00100         const int columns = 8;
00101 
00102         int c = 1;
00103         for(int i=value_size-1 ; i>=0 ; --i)
00104         {
00105             output << "0x" << std::setfill('0');
00106             
00107             #ifdef TTMATH_PLATFORM32
00108                 output << std::setw(8);
00109             #else
00110                 output << std::setw(16);
00111             #endif
00112                 
00113             output << std::hex << table [i];
00114             
00115             if( i>0 )
00116             {
00117                 output << ", ";        
00118             
00119                 if( ++c > columns )
00120                 {
00121                     output << std::endl;
00122                     c = 1;
00123                 }
00124             }
00125         }
00126         
00127         output << std::dec << std::endl;
00128     }
00129 
00130 
00131     /*!
00132         this method is used when macro TTMATH_DEBUG_LOG is defined
00133     */
00134     template<class char_type, class ostream_type>
00135     static void PrintVectorLog (const char_type * msg, ostream_type & output, const uint  * vector, uint  vector_len)
00136     {
00137         output << msg << std::endl;
00138 
00139         for(uint  i=0 ; i<vector_len ; ++i)
00140             output << " table[" << i << "]: " << vector[i] << std::endl;
00141     }
00142 
00143 
00144     /*!
00145         this method is used when macro TTMATH_DEBUG_LOG is defined
00146     */
00147     template<class char_type, class ostream_type>
00148     static void PrintVectorLog (const char_type * msg, uint  carry, ostream_type & output, const uint  * vector, uint  vector_len)
00149     {
00150         PrintVectorLog (msg, output, vector, vector_len);
00151         output << " carry: " << carry << std::endl;
00152     }
00153 
00154 
00155     /*!
00156         this method is used when macro TTMATH_DEBUG_LOG is defined
00157     */
00158     template<class char_type, class ostream_type>
00159     void PrintLog (const char_type * msg, ostream_type & output) const
00160     {
00161         PrintVectorLog (msg, output, table , value_size);
00162     }
00163 
00164 
00165     /*!
00166         this method is used when macro TTMATH_DEBUG_LOG is defined
00167     */
00168     template<class char_type, class ostream_type>
00169     void PrintLog (const char_type * msg, uint  carry, ostream_type & output) const
00170     {
00171         PrintVectorLog (msg, output, table , value_size);
00172         output << " carry: " << carry << std::endl;
00173     }
00174 
00175 
00176     /*!
00177         this method returns the size of the table
00178     */
00179     uint  Size () const
00180     {
00181         return value_size;
00182     }
00183 
00184 
00185     /*!
00186         this method sets zero
00187     */
00188     void SetZero ()
00189     {
00190         // in the future here can be 'memset'
00191 
00192         for(uint  i=0 ; i<value_size ; ++i)
00193             table [i] = 0;
00194 
00195         TTMATH_LOG("UInt::SetZero")
00196     }
00197 
00198 
00199     /*!
00200         this method sets one
00201     */
00202     void SetOne ()
00203     {
00204         SetZero ();
00205         table [0] = 1;
00206 
00207         TTMATH_LOG("UInt::SetOne")
00208     }
00209 
00210 
00211     /*!
00212         this method sets the max value which this class can hold
00213         (all bits will be one)
00214     */
00215     void SetMax ()
00216     {
00217         for(uint  i=0 ; i<value_size ; ++i)
00218             table [i] = TTMATH_UINT_MAX_VALUE;
00219 
00220         TTMATH_LOG("UInt::SetMax")
00221     }
00222 
00223 
00224     /*!
00225         this method sets the min value which this class can hold
00226         (for an unsigned integer value the zero is the smallest value)
00227     */
00228     void SetMin ()
00229     {
00230         SetZero ();
00231 
00232         TTMATH_LOG("UInt::SetMin")
00233     }
00234 
00235 
00236     /*!
00237         this method swappes this for an argument
00238     */
00239     void Swap (UInt<value_size> & ss2)
00240     {
00241         for(uint  i=0 ; i<value_size ; ++i)
00242         {
00243             uint  temp = table [i];
00244             table [i] = ss2.table [i];
00245             ss2.table [i] = temp;
00246         }
00247     }
00248 
00249 
00250 #ifdef TTMATH_PLATFORM32
00251 
00252     /*!
00253         this method copies the value stored in an another table
00254         (warning: first values in temp_table are the highest words -- it's different
00255         from our table)
00256 
00257         we copy as many words as it is possible
00258         
00259         if temp_table_len is bigger than value_size we'll try to round 
00260         the lowest word from table depending on the last not used bit in temp_table
00261         (this rounding isn't a perfect rounding -- look at the description below)
00262 
00263         and if temp_table_len is smaller than value_size we'll clear the rest words
00264         in the table
00265     */
00266     void SetFromTable (const uint  * temp_table, uint  temp_table_len)
00267     {
00268         uint  temp_table_index = 0;
00269         sint i; // 'i' with a sign
00270 
00271         for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
00272             table [i] = temp_table[ temp_table_index ];
00273 
00274 
00275         // rounding mantissa
00276         if( temp_table_index < temp_table_len )
00277         {
00278             if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
00279             {
00280                 /*
00281                     very simply rounding
00282                     if the bit from not used last word from temp_table is set to one
00283                     we're rouding the lowest word in the table
00284 
00285                     in fact there should be a normal addition but
00286                     we don't use Add() or AddTwoInts() because these methods 
00287                     can set a carry and then there'll be a small problem
00288                     for optimization
00289                 */
00290                 if( table [0] != TTMATH_UINT_MAX_VALUE )
00291                     ++table [0];
00292             }
00293         }
00294 
00295         // cleaning the rest of the mantissa
00296         for( ; i>=0 ; --i)
00297             table [i] = 0;
00298 
00299 
00300         TTMATH_LOG("UInt::SetFromTable")
00301     }
00302 
00303 #endif
00304 
00305 
00306 #ifdef TTMATH_PLATFORM64
00307     /*!
00308         this method copies the value stored in an another table
00309         (warning: first values in temp_table are the highest words -- it's different
00310         from our table)
00311 
00312         ***this method is created only on a 64bit platform***
00313 
00314         we copy as many words as it is possible
00315         
00316         if temp_table_len is bigger than value_size we'll try to round 
00317         the lowest word from table depending on the last not used bit in temp_table
00318         (this rounding isn't a perfect rounding -- look at the description below)
00319 
00320         and if temp_table_len is smaller than value_size we'll clear the rest words
00321         in the table
00322 
00323         warning: we're using 'temp_table' as a pointer at 32bit words
00324     */
00325     void SetFromTable (const unsigned int * temp_table, uint  temp_table_len)
00326     {
00327         uint  temp_table_index = 0;
00328         sint i; // 'i' with a sign
00329 
00330         for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
00331         {
00332             table [i] = uint (temp_table[ temp_table_index ]) << 32;
00333 
00334             ++temp_table_index;
00335 
00336             if( temp_table_index<temp_table_len )
00337                 table [i] |= temp_table[ temp_table_index ];
00338         }
00339 
00340 
00341         // rounding mantissa
00342         if( temp_table_index < temp_table_len )
00343         {
00344             if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
00345             {
00346                 /*
00347                     very simply rounding
00348                     if the bit from not used last word from temp_table is set to one
00349                     we're rouding the lowest word in the table
00350 
00351                     in fact there should be a normal addition but
00352                     we don't use Add() or AddTwoInts() because these methods 
00353                     can set a carry and then there'll be a small problem
00354                     for optimization
00355                 */
00356                 if( table [0] != TTMATH_UINT_MAX_VALUE )
00357                     ++table [0];
00358             }
00359         }
00360 
00361         // cleaning the rest of the mantissa
00362         for( ; i >= 0 ; --i)
00363             table [i] = 0;
00364 
00365         TTMATH_LOG("UInt::SetFromTable")
00366     }
00367 
00368 #endif
00369 
00370 
00371 
00372 
00373 
00374     /*!
00375     *
00376     *    basic mathematic functions
00377     *
00378     */
00379 
00380 
00381 
00382 
00383     /*!
00384         this method adds one to the existing value
00385     */
00386     uint  AddOne ()
00387     {
00388         return AddInt (1);
00389     }
00390 
00391 
00392     /*!
00393         this method subtracts one from the existing value
00394     */
00395     uint  SubOne ()
00396     {
00397         return SubInt (1);
00398     }
00399 
00400 
00401 private:
00402 
00403 
00404     /*!    
00405         an auxiliary method for moving bits into the left hand side
00406 
00407         this method moves only words
00408     */
00409     void RclMoveAllWords(uint  & rest_bits, uint  & last_c, uint  bits, uint  c)
00410     {
00411         rest_bits      = bits % TTMATH_BITS_PER_UINT;
00412         uint  all_words = bits / TTMATH_BITS_PER_UINT;
00413         uint  mask      = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
00414 
00415 
00416         if( all_words >= value_size )
00417         {
00418             if( all_words == value_size && rest_bits == 0 )
00419                 last_c = table [0] & 1;
00420             // else: last_c is default set to 0
00421 
00422             // clearing
00423             for(uint  i = 0 ; i<value_size ; ++i)
00424                 table [i] = mask;
00425 
00426             rest_bits = 0;
00427         }
00428         else
00429         if( all_words > 0 )  
00430         {
00431             // 0 < all_words < value_size
00432     
00433             sint first, second;
00434             last_c = table [value_size - all_words] & 1; // all_words is greater than 0
00435 
00436             // copying the first part of the value
00437             for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
00438                 table [first] = table [second];
00439 
00440             // setting the rest to 'c'
00441             for( ; first>=0 ; --first )
00442                 table [first] = mask;
00443         }
00444 
00445         TTMATH_LOG("UInt::RclMoveAllWords")
00446     }
00447     
00448 public:
00449 
00450     /*!
00451         moving all bits into the left side 'bits' times
00452         return value <- this <- C
00453 
00454         bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
00455         or it can be even bigger then all bits will be set to 'c'
00456 
00457         the value c will be set into the lowest bits
00458         and the method returns state of the last moved bit
00459     */
00460     uint  Rcl (uint  bits, uint  c=0)
00461     {
00462     uint  last_c    = 0;
00463     uint  rest_bits = bits;
00464 
00465         if( bits == 0 )
00466             return 0;
00467 
00468         if( bits >= TTMATH_BITS_PER_UINT )
00469             RclMoveAllWords(rest_bits, last_c, bits, c);
00470 
00471         if( rest_bits == 0 )
00472         {
00473             TTMATH_LOG("UInt::Rcl")
00474             return last_c;
00475         }
00476 
00477         // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
00478         if( rest_bits == 1 )
00479         {
00480             last_c = Rcl2_one(c);
00481         }
00482         else if( rest_bits == 2 )
00483         {
00484             // performance tests showed that for rest_bits==2 it's better to use Rcl2_one twice instead of Rcl2(2,c)
00485             Rcl2_one(c);
00486             last_c = Rcl2_one(c);
00487         }
00488         else
00489         {
00490             last_c = Rcl2(rest_bits, c);
00491         }
00492 
00493         TTMATH_LOGC("UInt::Rcl", last_c)
00494 
00495     return last_c;
00496     }
00497 
00498 private:
00499 
00500     /*!    
00501         an auxiliary method for moving bits into the right hand side
00502 
00503         this method moves only words
00504     */
00505     void RcrMoveAllWords(uint  & rest_bits, uint  & last_c, uint  bits, uint  c)
00506     {
00507         rest_bits      = bits % TTMATH_BITS_PER_UINT;
00508         uint  all_words = bits / TTMATH_BITS_PER_UINT;
00509         uint  mask      = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
00510 
00511 
00512         if( all_words >= value_size )
00513         {
00514             if( all_words == value_size && rest_bits == 0 )
00515                 last_c = (table [value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
00516             // else: last_c is default set to 0
00517 
00518             // clearing
00519             for(uint  i = 0 ; i<value_size ; ++i)
00520                 table [i] = mask;
00521 
00522             rest_bits = 0;
00523         }
00524         else if( all_words > 0 )
00525         {
00526             // 0 < all_words < value_size
00527 
00528             uint  first, second;
00529             last_c = (table [all_words - 1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; // all_words is > 0
00530 
00531             // copying the first part of the value
00532             for(first=0, second=all_words ; second<value_size ; ++first, ++second)
00533                 table [first] = table [second];
00534 
00535             // setting the rest to 'c'
00536             for( ; first<value_size ; ++first )
00537                 table [first] = mask;
00538         }
00539 
00540         TTMATH_LOG("UInt::RcrMoveAllWords")
00541     }
00542 
00543 public:
00544 
00545     /*!
00546         moving all bits into the right side 'bits' times
00547         c -> this -> return value
00548 
00549         bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
00550         or it can be even bigger then all bits will be set to 'c'
00551 
00552         the value c will be set into the highest bits
00553         and the method returns state of the last moved bit
00554     */
00555     uint  Rcr (uint  bits, uint  c=0)
00556     {
00557     uint  last_c    = 0;
00558     uint  rest_bits = bits;
00559     
00560         if( bits == 0 )
00561             return 0;
00562 
00563         if( bits >= TTMATH_BITS_PER_UINT )
00564             RcrMoveAllWords(rest_bits, last_c, bits, c);
00565 
00566         if( rest_bits == 0 )
00567         {
00568             TTMATH_LOG("UInt::Rcr")
00569             return last_c;
00570         }
00571 
00572         // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
00573         if( rest_bits == 1 )
00574         {
00575             last_c = Rcr2_one(c);
00576         }
00577         else if( rest_bits == 2 )
00578         {
00579             // performance tests showed that for rest_bits==2 it's better to use Rcr2_one twice instead of Rcr2(2,c)
00580             Rcr2_one(c);
00581             last_c = Rcr2_one(c);
00582         }
00583         else
00584         {
00585             last_c = Rcr2(rest_bits, c);
00586         }
00587 
00588         TTMATH_LOGC("UInt::Rcr", last_c)
00589 
00590     return last_c;
00591     }
00592 
00593 
00594     /*!
00595         this method moves all bits into the left side
00596         (it returns value how many bits have been moved)
00597     */
00598     uint  CompensationToLeft ()
00599     {
00600         uint  moving = 0;
00601 
00602         // a - index a last word which is different from zero
00603         sint a;
00604         for(a=value_size-1 ; a>=0 && table [a]==0 ; --a);
00605 
00606         if( a < 0 )
00607             return moving; // all words in table have zero
00608 
00609         if( a != value_size-1 )
00610         {
00611             moving += ( value_size-1 - a ) * TTMATH_BITS_PER_UINT;
00612 
00613             // moving all words
00614             sint i;
00615             for(i=value_size-1 ; a>=0 ; --i, --a)
00616                 table [i] = table [a];
00617 
00618             // setting the rest word to zero
00619             for(; i>=0 ; --i)
00620                 table [i] = 0;
00621         }
00622 
00623         uint  moving2 = FindLeadingBitInWord ( table [value_size-1] );
00624         // moving2 is different from -1 because the value table[value_size-1]
00625         // is not zero
00626 
00627         moving2 = TTMATH_BITS_PER_UINT - moving2 - 1;
00628         Rcl (moving2);
00629 
00630         TTMATH_LOG("UInt::CompensationToLeft")
00631 
00632     return moving + moving2;
00633     }
00634 
00635 
00636     /*!
00637         this method looks for the highest set bit
00638         
00639         result:
00640             if 'this' is not zero:
00641                 return value - true
00642                 'table_id'   - the index of a word <0..value_size-1>
00643                 'index'      - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
00644 
00645             if 'this' is zero: 
00646                 return value - false
00647                 both 'table_id' and 'index' are zero
00648     */
00649     bool FindLeadingBit (uint  & table_id, uint  & index) const
00650     {
00651         for(table_id=value_size-1 ; table_id!=0 && table [table_id]==0 ; --table_id);
00652 
00653         if( table_id==0 && table [table_id]==0 )
00654         {
00655             // is zero
00656             index = 0;
00657 
00658         return false;
00659         }
00660         
00661         // table[table_id] is different from 0
00662         index = FindLeadingBitInWord ( table [table_id] );
00663 
00664     return true;
00665     }
00666 
00667 
00668     /*!
00669         this method looks for the smallest set bit
00670         
00671         result:
00672             if 'this' is not zero:
00673                 return value - true
00674                 'table_id'   - the index of a word <0..value_size-1>
00675                 'index'      - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
00676 
00677             if 'this' is zero: 
00678                 return value - false
00679                 both 'table_id' and 'index' are zero
00680     */
00681     bool FindLowestBit (uint  & table_id, uint  & index) const
00682     {
00683         for(table_id=0 ; table_id<value_size && table [table_id]==0 ; ++table_id);
00684 
00685         if( table_id >= value_size )
00686         {
00687             // is zero
00688             index    = 0;
00689             table_id = 0;
00690 
00691         return false;
00692         }
00693         
00694         // table[table_id] is different from 0
00695         index = FindLowestBitInWord ( table[table_id] );
00696 
00697     return true;
00698     }
00699 
00700 
00701     /*!
00702         getting the 'bit_index' bit
00703 
00704         bit_index bigger or equal zero
00705     */
00706     uint  GetBit (uint  bit_index) const
00707     {
00708         TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
00709 
00710         uint  index = bit_index / TTMATH_BITS_PER_UINT;
00711         uint  bit   = bit_index % TTMATH_BITS_PER_UINT;
00712 
00713         uint  temp = table [index];
00714         uint  res  = SetBitInWord (temp, bit);
00715 
00716     return res;
00717     }
00718 
00719 
00720     /*!
00721         setting the 'bit_index' bit
00722         and returning the last state of the bit
00723 
00724         bit_index bigger or equal zero
00725     */
00726     uint  SetBit (uint  bit_index)
00727     {
00728         TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
00729 
00730         uint  index = bit_index / TTMATH_BITS_PER_UINT;
00731         uint  bit   = bit_index % TTMATH_BITS_PER_UINT;
00732         uint  res   = SetBitInWord (table [index], bit);
00733 
00734         TTMATH_LOG("UInt::SetBit")
00735 
00736     return res;
00737     }
00738 
00739 
00740     /*!
00741         this method performs a bitwise operation AND 
00742     */
00743     void BitAnd (const UInt<value_size> & ss2)
00744     {
00745         for(uint  x=0 ; x<value_size ; ++x)
00746             table [x] &= ss2.table [x];
00747 
00748         TTMATH_LOG("UInt::BitAnd")
00749     }
00750 
00751 
00752     /*!
00753         this method performs a bitwise operation OR 
00754     */
00755     void BitOr (const UInt<value_size> & ss2)
00756     {
00757         for(uint  x=0 ; x<value_size ; ++x)
00758             table [x] |= ss2.table [x];
00759 
00760         TTMATH_LOG("UInt::BitOr")
00761     }
00762 
00763 
00764     /*!
00765         this method performs a bitwise operation XOR 
00766     */
00767     void BitXor (const UInt<value_size> & ss2)
00768     {
00769         for(uint  x=0 ; x<value_size ; ++x)
00770             table [x] ^= ss2.table [x];
00771 
00772         TTMATH_LOG("UInt::BitXor")
00773     }
00774 
00775 
00776     /*!
00777         this method performs a bitwise operation NOT
00778     */
00779     void BitNot ()
00780     {
00781         for(uint  x=0 ; x<value_size ; ++x)
00782             table [x] = ~table [x];
00783 
00784         TTMATH_LOG("UInt::BitNot")
00785     }
00786 
00787 
00788     /*!
00789         this method performs a bitwise operation NOT but only
00790         on the range of <0, leading_bit>
00791 
00792         for example:
00793             BitNot2(8) = BitNot2( 1000(bin) ) = 111(bin) = 7
00794     */
00795     void BitNot2 ()
00796     {
00797     uint  table_id, index;
00798 
00799         if( FindLeadingBit (table_id, index) )
00800         {
00801             for(uint  x=0 ; x<table_id ; ++x)
00802                 table [x] = ~table [x];
00803 
00804             uint  mask  = TTMATH_UINT_MAX_VALUE;
00805             uint  shift = TTMATH_BITS_PER_UINT - index - 1;
00806 
00807             if(shift)
00808                 mask >>= shift;
00809 
00810             table [table_id] ^= mask;
00811         }
00812         else
00813             table [0] = 1;
00814 
00815 
00816         TTMATH_LOG("UInt::BitNot2")
00817     }
00818 
00819 
00820 
00821     /*!
00822      *
00823      * Multiplication
00824      *
00825      *
00826     */
00827 
00828 public:
00829 
00830     /*!
00831         multiplication: this = this * ss2
00832 
00833         it can return a carry
00834     */
00835     uint  MulInt (uint  ss2)
00836     {
00837     uint  r1, r2, x1;
00838     uint  c = 0;
00839 
00840         UInt<value_size> u(*this);
00841         SetZero ();
00842 
00843         if( ss2 == 0 )
00844         {
00845             TTMATH_LOGC("UInt::MulInt(uint)", 0)
00846             return 0;
00847         }
00848 
00849         for(x1=0 ; x1<value_size-1 ; ++x1)
00850         {
00851             MulTwoWords (u.table [x1], ss2, &r2, &r1);
00852             c += AddTwoInts (r2,r1,x1);
00853         }
00854 
00855         // x1 = value_size-1  (last word)
00856         MulTwoWords (u.table [x1], ss2, &r2, &r1);
00857         c += (r2!=0) ? 1 : 0;
00858         c += AddInt (r1, x1);
00859 
00860         TTMATH_LOGC("UInt::MulInt(uint)", c)
00861 
00862     return (c==0)? 0 : 1;
00863     }
00864 
00865 
00866     /*!
00867         multiplication: result = this * ss2
00868 
00869         we're using this method only when result_size is greater than value_size
00870         if so there will not be a carry
00871     */
00872     template<uint result_size>
00873     void MulInt (uint  ss2, UInt<result_size> & result) const
00874     {
00875     TTMATH_ASSERT( result_size > value_size )
00876 
00877     uint  r2,r1;
00878     uint  x1size=value_size;
00879     uint  x1start=0;
00880 
00881         result.SetZero ();
00882 
00883         if( ss2 == 0 )
00884         {
00885             TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table , result_size)
00886             return;
00887         }
00888 
00889         if( value_size > 2 )
00890         {    
00891             // if the value_size is smaller than or equal to 2
00892             // there is no sense to set x1size and x1start to another values
00893 
00894             for(x1size=value_size ; x1size>0 && table [x1size-1]==0 ; --x1size);
00895 
00896             if( x1size == 0 )
00897             {
00898                 TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table , result_size)
00899                 return;
00900             }
00901 
00902             for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
00903         }
00904 
00905         for(uint  x1=x1start ; x1<x1size ; ++x1)
00906         {
00907             MulTwoWords (table [x1], ss2, &r2, &r1 );
00908             result.AddTwoInts (r2,r1,x1);
00909         }
00910 
00911         TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table , result_size)
00912 
00913     return;
00914     }
00915 
00916 
00917 
00918     /*!
00919         the multiplication 'this' = 'this' * ss2
00920 
00921         algorithm: 100 - means automatically choose the fastest algorithm
00922     */
00923     uint  Mul (const UInt<value_size> & ss2, uint  algorithm = 100)
00924     {
00925         switch( algorithm )
00926         {
00927         case 1:
00928             return Mul1 (ss2);
00929 
00930         case 2:
00931             return Mul2 (ss2);
00932 
00933         case 3:
00934             return Mul3 (ss2);
00935 
00936         case 100:
00937         default:
00938             return MulFastest (ss2);
00939         }
00940     }
00941 
00942 
00943     /*!
00944         the multiplication 'result' = 'this' * ss2
00945 
00946         since the 'result' is twice bigger than 'this' and 'ss2' 
00947         this method never returns a carry
00948 
00949         algorithm: 100 - means automatically choose the fastest algorithm
00950     */
00951     void MulBig (const UInt<value_size> & ss2,
00952                 UInt<value_size*2> & result, 
00953                 uint  algorithm = 100)
00954     {
00955         switch( algorithm )
00956         {
00957         case 1:
00958             return Mul1Big (ss2, result);
00959 
00960         case 2:
00961             return Mul2Big (ss2, result);
00962 
00963         case 3:
00964             return Mul3Big (ss2, result);
00965 
00966         case 100:
00967         default:
00968             return MulFastestBig (ss2, result);
00969         }
00970     }
00971 
00972 
00973 
00974     /*!
00975         the first version of the multiplication algorithm
00976     */
00977 
00978 private:
00979 
00980     /*!
00981         multiplication: this = this * ss2
00982 
00983         it returns carry if it has been
00984     */
00985     uint  Mul1Ref(const UInt<value_size> & ss2)
00986     {
00987     TTMATH_REFERENCE_ASSERT( ss2 )
00988 
00989     UInt<value_size> ss1( *this );
00990     SetZero ();    
00991 
00992         for(uint  i=0; i < value_size*TTMATH_BITS_PER_UINT ; ++i)
00993         {
00994             if( Add (*this) )
00995             {
00996                 TTMATH_LOGC("UInt::Mul1", 1)
00997                 return 1;
00998             }
00999 
01000             if( ss1.Rcl (1) )
01001                 if( Add (ss2) )
01002                 {
01003                     TTMATH_LOGC("UInt::Mul1", 1)
01004                     return 1;
01005                 }
01006         }
01007 
01008         TTMATH_LOGC("UInt::Mul1 ", 0)
01009 
01010     return 0;
01011     }
01012 
01013 
01014 public:
01015 
01016     /*!
01017         multiplication: this = this * ss2
01018         can return carry
01019     */
01020     uint  Mul1(const UInt<value_size> & ss2)
01021     {
01022         if( this == &ss2 )
01023         {
01024             UInt<value_size> copy_ss2(ss2);
01025             return Mul1Ref(copy_ss2);
01026         }
01027         else
01028         {
01029             return Mul1Ref(ss2);
01030         }
01031     }
01032 
01033     
01034     /*!
01035         multiplication: result = this * ss2
01036 
01037         result is twice bigger than 'this' and 'ss2'
01038         this method never returns carry            
01039     */
01040     void Mul1Big (const UInt<value_size> & ss2_, UInt<value_size*2> & result)
01041     {
01042     UInt<value_size*2> ss2;
01043     uint  i;
01044 
01045         // copying *this into result and ss2_ into ss2
01046         for(i=0 ; i<value_size ; ++i)
01047         {
01048             result.table [i] = table [i];
01049             ss2.table [i]    = ss2_.table [i];
01050         }
01051 
01052         // cleaning the highest bytes in result and ss2
01053         for( ; i < value_size*2 ; ++i)
01054         {
01055             result.table [i] = 0;
01056             ss2.table [i]    = 0;
01057         }
01058 
01059         // multiply
01060         // (there will not be a carry)
01061         result.Mul1 ( ss2 );
01062 
01063         TTMATH_LOG("UInt::Mul1Big")
01064     }
01065 
01066 
01067 
01068     /*!
01069         the second version of the multiplication algorithm
01070 
01071         this algorithm is similar to the 'schoolbook method' which is done by hand
01072     */
01073 
01074     /*!
01075         multiplication: this = this * ss2
01076 
01077         it returns carry if it has been
01078     */
01079     uint  Mul2 (const UInt<value_size> & ss2)
01080     {
01081     UInt<value_size*2> result;
01082     uint  i, c = 0;
01083 
01084         Mul2Big (ss2, result);
01085     
01086         // copying result
01087         for(i=0 ; i<value_size ; ++i)
01088             table [i] = result.table [i];
01089 
01090         // testing carry
01091         for( ; i<value_size*2 ; ++i)
01092             if( result.table [i] != 0 )
01093             {
01094                 c = 1;
01095                 break;
01096             }
01097 
01098         TTMATH_LOGC("UInt::Mul2", c)
01099 
01100     return c;
01101     }
01102 
01103 
01104     /*!
01105         multiplication: result = this * ss2
01106 
01107         result is twice bigger than this and ss2
01108         this method never returns carry            
01109     */
01110     void Mul2Big (const UInt<value_size> & ss2, UInt<value_size*2> & result)
01111     {
01112         Mul2Big2<value_size>(table , ss2.table , result);
01113 
01114         TTMATH_LOG("UInt::Mul2Big")
01115     }
01116 
01117 
01118 private:
01119 
01120     /*!
01121         an auxiliary method for calculating the multiplication 
01122 
01123         arguments we're taking as pointers (this is to improve the Mul3Big2()- avoiding
01124         unnecessary copying objects), the result should be taken as a pointer too,
01125         but at the moment there is no method AddTwoInts() which can operate on pointers
01126     */
01127     template<uint ss_size>
01128     void Mul2Big2(const uint  * ss1, const uint  * ss2, UInt<ss_size*2> & result)
01129     {
01130     uint  x1size  = ss_size, x2size  = ss_size;
01131     uint  x1start = 0,       x2start = 0;
01132 
01133         if( ss_size > 2 )
01134         {    
01135             // if the ss_size is smaller than or equal to 2
01136             // there is no sense to set x1size (and others) to another values
01137 
01138             for(x1size=ss_size ; x1size>0 && ss1[x1size-1]==0 ; --x1size);
01139             for(x2size=ss_size ; x2size>0 && ss2[x2size-1]==0 ; --x2size);
01140 
01141             for(x1start=0 ; x1start<x1size && ss1[x1start]==0 ; ++x1start);
01142             for(x2start=0 ; x2start<x2size && ss2[x2start]==0 ; ++x2start);
01143         }
01144 
01145         Mul2Big3<ss_size>(ss1, ss2, result, x1start, x1size, x2start, x2size);
01146     }
01147 
01148 
01149 
01150     /*!
01151         an auxiliary method for calculating the multiplication 
01152     */
01153     template<uint ss_size>
01154     void Mul2Big3(const uint  * ss1, const uint  * ss2, UInt<ss_size*2> & result, uint  x1start, uint  x1size, uint  x2start, uint  x2size)
01155     {
01156     uint  r2, r1;
01157 
01158         result.SetZero();
01159 
01160         if( x1size==0 || x2size==0 )
01161             return;
01162 
01163         for(uint  x1=x1start ; x1<x1size ; ++x1)
01164         {
01165             for(uint  x2=x2start ; x2<x2size ; ++x2)
01166             {
01167                 MulTwoWords (ss1[x1], ss2[x2], &r2, &r1);
01168                 result.AddTwoInts(r2, r1, x2+x1);
01169                 // here will never be a carry
01170             }
01171         }
01172     }
01173 
01174 
01175 public:
01176 
01177 
01178     /*!
01179         multiplication: this = this * ss2
01180 
01181         This is Karatsuba Multiplication algorithm, we're using it when value_size is greater than
01182         or equal to TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE macro (defined in ttmathuint.h).
01183         If value_size is smaller then we're using Mul2Big() instead.
01184 
01185         Karatsuba multiplication:
01186         Assume we have:
01187             this = x = x1*B^m + x0
01188             ss2  = y = y1*B^m + y0
01189         where x0 and y0 are less than B^m
01190         the product from multiplication we can show as:
01191         x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
01192         where
01193             z2 = x1*y1
01194             z1 = x1*y0 + x0*y1
01195             z0 = x0*y0 
01196         this is standard schoolbook algorithm with O(n^2), Karatsuba observed that z1 can be given in other form:
01197             z1 = (x1 + x0)*(y1 + y0) - z2 - z0    / z1 = (x1*y1 + x1*y0 + x0*y1 + x0*y0) - x1*y1 - x0*y0 = x1*y0 + x0*y1 /
01198         and to calculate the multiplication we need only three multiplications (with some additions and subtractions)            
01199 
01200         Our objects 'this' and 'ss2' we divide into two parts and by using recurrence we calculate the multiplication.
01201         Karatsuba multiplication has O( n^(ln(3)/ln(2)) )
01202     */
01203     uint  Mul3 (const UInt<value_size> & ss2)
01204     {
01205     UInt<value_size*2> result;
01206     uint  i, c = 0;
01207 
01208         Mul3Big (ss2, result);
01209     
01210         // copying result
01211         for(i=0 ; i<value_size ; ++i)
01212             table [i] = result.table [i];
01213 
01214         // testing carry
01215         for( ; i<value_size*2 ; ++i)
01216             if( result.table [i] != 0 )
01217             {
01218                 c = 1;
01219                 break;
01220             }
01221 
01222         TTMATH_LOGC("UInt::Mul3", c)
01223 
01224     return c;
01225     }
01226 
01227 
01228 
01229     /*!
01230         multiplication: result = this * ss2
01231 
01232         result is twice bigger than this and ss2,
01233         this method never returns carry,
01234         (Karatsuba multiplication)
01235     */
01236     void Mul3Big (const UInt<value_size> & ss2, UInt<value_size*2> & result)
01237     {
01238         Mul3Big2<value_size>(table , ss2.table , result.table );
01239 
01240         TTMATH_LOG("UInt::Mul3Big")
01241     }
01242 
01243 
01244 
01245 private:
01246 
01247     /*!
01248         an auxiliary method for calculating the Karatsuba multiplication
01249 
01250         result_size is equal ss_size*2
01251     */
01252     template<uint ss_size>
01253     void Mul3Big2(const uint  * ss1, const uint  * ss2, uint  * result)
01254     {
01255     const uint  * x1, * x0, * y1, * y0;
01256 
01257 
01258         if( ss_size>1 && ss_size<TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
01259         {
01260             UInt<ss_size*2> res;
01261             Mul2Big2<ss_size>(ss1, ss2, res);
01262 
01263 #ifdef __clang__
01264 #pragma clang diagnostic push
01265 #pragma clang diagnostic ignored "-Wtautological-compare"
01266 #endif
01267 
01268             for(uint  i=0 ; i<ss_size*2 ; ++i)
01269                 result[i] = res.table [i];
01270 
01271 #ifdef __clang__
01272 #pragma clang diagnostic pop
01273 #endif
01274 
01275         return;
01276         }
01277         else
01278         if( ss_size == 1 )
01279         {
01280             return MulTwoWords (*ss1, *ss2, &result[1], &result[0]);
01281         }
01282 
01283 
01284         if( (ss_size & 1) == 1 )
01285         {
01286             // ss_size is odd
01287             x0 = ss1;
01288             y0 = ss2;
01289             x1 = ss1 + ss_size / 2 + 1;
01290             y1 = ss2 + ss_size / 2 + 1;
01291 
01292             // the second vectors (x1 and y1) are smaller about one from the first ones (x0 and y0)
01293             Mul3Big3<ss_size/2 + 1, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
01294         }
01295         else
01296         {
01297             // ss_size is even
01298             x0 = ss1;
01299             y0 = ss2;
01300             x1 = ss1 + ss_size / 2;
01301             y1 = ss2 + ss_size / 2;
01302             
01303             // all four vectors (x0 x1 y0 y1) are equal in size
01304             Mul3Big3<ss_size/2, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
01305         }
01306     }
01307 
01308 
01309 
01310 #ifdef _MSC_VER
01311 #pragma warning (disable : 4717)
01312 //warning C4717: recursive on all control paths, function will cause runtime stack overflow
01313 //we have the stop point in Mul3Big2() method
01314 #endif
01315 
01316 
01317     /*!
01318         an auxiliary method for calculating the Karatsuba multiplication
01319 
01320             x = x1*B^m + x0
01321             y = y1*B^m + y0
01322 
01323             first_size  - is the size of vectors: x0 and y0
01324             second_size - is the size of vectors: x1 and y1 (can be either equal first_size or smaller about one from first_size)
01325 
01326             x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
01327               where
01328                z0 = x0*y0 
01329                z2 = x1*y1
01330                z1 = (x1 + x0)*(y1 + y0) - z2 - z0
01331     */
01332     template<uint first_size, uint second_size, uint result_size>
01333     void Mul3Big3(const uint  * x1, const uint  * x0, const uint  * y1, const uint  * y0, uint  * result)
01334     {
01335     uint  i, c, xc, yc;
01336 
01337         UInt<first_size>   temp, temp2;
01338         UInt<first_size*3> z1;
01339 
01340         // z0 and z2 we store directly in the result (we don't use any temporary variables)
01341         Mul3Big2<first_size>(x0, y0, result);                  // z0
01342         Mul3Big2<second_size>(x1, y1, result+first_size*2);    // z2
01343 
01344         // now we calculate z1
01345         // temp  = (x0 + x1)
01346         // temp2 = (y0 + y1)
01347         // we're using temp and temp2 with UInt<first_size>, although there can be a carry but 
01348         // we simple remember it in xc and yc (xc and yc can be either 0 or 1),
01349         // and (x0 + x1)*(y0 + y1) we calculate in this way (schoolbook algorithm):
01350         // 
01351         //                 xc     |     temp
01352         //                 yc     |     temp2
01353         //               --------------------
01354         //               (temp    *   temp2)
01355         //               xc*temp2 |
01356         //               yc*temp  |
01357         //       xc*yc |                     
01358         //       ----------     z1     --------
01359         //
01360         // and the result is never larger in size than 3*first_size
01361 
01362         xc = AddVector (x0, x1, first_size, second_size, temp.table);
01363         yc = AddVector (y0, y1, first_size, second_size, temp2.table);
01364 
01365         Mul3Big2<first_size>(temp.table, temp2.table, z1.table);
01366 
01367 #ifdef __clang__
01368 #pragma clang diagnostic push
01369 #pragma clang diagnostic ignored "-Wtautological-compare"
01370 #endif
01371 
01372         // clearing the rest of z1
01373         for(i=first_size*2 ; i<first_size*3 ; ++i)
01374             z1.table[i] = 0;
01375 
01376 #ifdef __clang__
01377 #pragma clang diagnostic pop
01378 #endif
01379         
01380         if( xc )
01381         {
01382             c = AddVector (z1.table+first_size, temp2.table, first_size*3-first_size, first_size, z1.table+first_size);
01383             TTMATH_ASSERT( c==0 )
01384         }
01385 
01386         if( yc )
01387         {
01388             c = AddVector (z1.table+first_size, temp.table, first_size*3-first_size, first_size, z1.table+first_size);
01389             TTMATH_ASSERT( c==0 )
01390         }
01391 
01392 
01393         if( xc && yc )
01394         {
01395 #ifdef __clang__
01396 #pragma clang diagnostic push
01397 #pragma clang diagnostic ignored "-Wtautological-compare"
01398 #endif
01399 
01400             for( i=first_size*2 ; i<first_size*3 ; ++i )
01401                 if( ++z1.table[i] != 0 )
01402                      break;  // break if there was no carry 
01403 
01404 #ifdef __clang__
01405 #pragma clang diagnostic pop
01406 #endif
01407         }
01408 
01409         // z1 = z1 - z2
01410         c = SubVector (z1.table, result+first_size*2, first_size*3, second_size*2, z1.table);
01411         TTMATH_ASSERT(c==0)
01412 
01413         // z1 = z1 - z0
01414         c = SubVector (z1.table , result, first_size*3, first_size*2, z1.table);
01415         TTMATH_ASSERT(c==0)
01416 
01417         // here we've calculated the z1
01418         // now we're adding it to the result
01419 
01420         if( first_size > second_size )
01421         {
01422             uint  z1_size = result_size - first_size;
01423             TTMATH_ASSERT( z1_size <= first_size*3 )
01424 
01425 #ifdef __clang__
01426 #pragma clang diagnostic push
01427 #pragma clang diagnostic ignored "-Wtautological-compare"
01428 #endif
01429 
01430             for(i=z1_size ; i<first_size*3 ; ++i)
01431             {
01432                 TTMATH_ASSERT( z1.table[i] == 0 )
01433             }
01434 
01435 #ifdef __clang__
01436 #pragma clang diagnostic pop
01437 #endif
01438              
01439             c = AddVector (result+first_size, z1.table, result_size-first_size, z1_size, result+first_size);
01440             TTMATH_ASSERT(c==0)
01441         }
01442         else
01443         {
01444             c = AddVector (result+first_size, z1.table, result_size-first_size, first_size*3, result+first_size);
01445             TTMATH_ASSERT(c==0)
01446         }
01447     }
01448 
01449 
01450 
01451 #ifdef _MSC_VER
01452 #pragma warning (default : 4717)
01453 #endif
01454 
01455 
01456 public:
01457 
01458 
01459     /*!
01460         multiplication this = this * ss2
01461     */
01462     uint  MulFastest (const UInt<value_size> & ss2)
01463     {
01464     UInt<value_size*2> result;
01465     uint  i, c = 0;
01466 
01467         MulFastestBig (ss2, result);
01468     
01469         // copying result
01470         for(i=0 ; i<value_size ; ++i)
01471             table[i] = result.table [i];
01472 
01473         // testing carry
01474         for( ; i<value_size*2 ; ++i)
01475             if( result.table [i] != 0 )
01476             {
01477                 c = 1;
01478                 break;
01479             }
01480 
01481         TTMATH_LOGC("UInt::MulFastest", c)
01482 
01483     return c;
01484     }
01485 
01486 
01487     /*!
01488         multiplication result = this * ss2
01489 
01490         this method is trying to select the fastest algorithm
01491         (in the future this method can be improved)
01492     */
01493     void MulFastestBig (const UInt<value_size> & ss2, UInt<value_size*2> & result)
01494     {
01495         if( value_size < TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
01496             return Mul2Big (ss2, result);
01497 
01498         uint  x1size  = value_size, x2size  = value_size;
01499         uint  x1start = 0,          x2start = 0;
01500 
01501         for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
01502         for(x2size=value_size ; x2size>0 && ss2.table [x2size-1]==0 ; --x2size);
01503 
01504         if( x1size==0 || x2size==0 )
01505         {
01506             // either 'this' or 'ss2' is equal zero - the result is zero too
01507             result.SetZero ();
01508             return;
01509         }
01510 
01511         for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
01512         for(x2start=0 ; x2start<x2size && ss2.table [x2start]==0 ; ++x2start);
01513 
01514         uint  distancex1 = x1size - x1start;
01515         uint  distancex2 = x2size - x2start;
01516 
01517         if( distancex1 < 3 || distancex2 < 3 )
01518             // either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
01519             // (this condition in the future can be improved)
01520             return Mul2Big3<value_size>(table , ss2.table , result, x1start, x1size, x2start, x2size);
01521 
01522 
01523         // Karatsuba multiplication
01524         Mul3Big (ss2, result);
01525 
01526         TTMATH_LOG("UInt::MulFastestBig")
01527     }
01528 
01529 
01530     /*!
01531      *
01532      * Division
01533      *
01534      *
01535     */
01536     
01537 public:
01538 
01539 
01540     /*!
01541         division by one unsigned word
01542 
01543         returns 1 when divisor is zero
01544     */
01545     uint  DivInt (uint  divisor, uint  * remainder = 0)
01546     {
01547         if( divisor == 0 )
01548         {
01549             if( remainder )
01550                 *remainder = 0; // this is for convenience, without it the compiler can report that 'remainder' is uninitialized
01551 
01552             TTMATH_LOG("UInt::DivInt")
01553 
01554         return 1;
01555         }
01556 
01557         if( divisor == 1 )
01558         {
01559             if( remainder )
01560                 *remainder = 0;
01561 
01562             TTMATH_LOG("UInt::DivInt")
01563 
01564         return 0;
01565         }
01566 
01567         UInt<value_size> dividend(*this);
01568         SetZero ();
01569         
01570         sint i;  // i must be with a sign
01571         uint  r = 0;
01572 
01573         // we're looking for the last word in ss1
01574         for(i=value_size-1 ; i>0 && dividend.table [i]==0 ; --i);
01575 
01576         for( ; i>=0 ; --i)
01577             DivTwoWords (r, dividend.table [i], divisor, &table[i], &r);
01578 
01579         if( remainder )
01580             *remainder = r;
01581 
01582         TTMATH_LOG("UInt::DivInt")
01583 
01584     return 0;
01585     }
01586 
01587     uint  DivInt (uint  divisor, uint  & remainder)
01588     {
01589         return DivInt (divisor, &remainder);
01590     }
01591 
01592 
01593 
01594     /*!
01595         division this = this / ss2
01596         
01597         return values:
01598              0 - ok
01599              1 - division by zero
01600             'this' will be the quotient
01601             'remainder' - remainder
01602     */
01603     uint  Div (    const UInt<value_size> & divisor,
01604                 UInt<value_size> * remainder = 0,
01605                 uint  algorithm = 3)
01606     {
01607         switch( algorithm )
01608         {
01609         case 1:
01610             return Div1 (divisor, remainder);
01611 
01612         case 2:
01613             return Div2 (divisor, remainder);
01614 
01615         case 3:
01616         default:
01617             return Div3 (divisor, remainder);
01618         }
01619     }
01620 
01621     uint  Div (const UInt<value_size> & divisor, UInt<value_size> & remainder, uint  algorithm = 3)
01622     {
01623         return Div (divisor, &remainder, algorithm);
01624     }
01625 
01626 
01627 
01628 private:
01629 
01630     /*!
01631         return values:
01632         0 - none has to be done
01633         1 - division by zero
01634         2 - division should be made
01635     */
01636     uint  Div_StandardTest(    const UInt<value_size> & v,
01637                             uint  & m, uint  & n,
01638                             UInt<value_size> * remainder = 0)
01639     {
01640         switch( Div_CalculatingSize(v, m, n) )
01641         {
01642         case 4: // 'this' is equal v
01643             if( remainder )
01644                 remainder->SetZero();
01645 
01646             SetOne ();
01647             TTMATH_LOG("UInt::Div_StandardTest")
01648             return 0;
01649 
01650         case 3: // 'this' is smaller than v
01651             if( remainder )
01652                 *remainder = *this;
01653 
01654             SetZero ();
01655             TTMATH_LOG("UInt ::Div_StandardTest")
01656             return 0;
01657 
01658         case 2: // 'this' is zero
01659             if( remainder )
01660                 remainder->SetZero ();
01661 
01662             SetZero();
01663             TTMATH_LOG("UInt ::Div_StandardTest")
01664             return 0;
01665 
01666         case 1: // v is zero
01667             TTMATH_LOG("UInt ::Div_StandardTest")
01668             return 1;
01669         }
01670 
01671         TTMATH_LOG("UInt ::Div_StandardTest")
01672 
01673     return 2;
01674     }
01675 
01676 
01677 
01678     /*!
01679         return values:
01680         0 - ok 
01681             'm' - is the index (from 0) of last non-zero word in table ('this')
01682             'n' - is the index (from 0) of last non-zero word in v.table
01683         1 - v is zero 
01684         2 - 'this' is zero
01685         3 - 'this' is smaller than v
01686         4 - 'this' is equal v
01687 
01688         if the return value is different than zero the 'm' and 'n' are undefined
01689     */
01690     uint  Div_CalculatingSize(const UInt <value_size> & v, uint  & m, uint  & n)
01691     {
01692         m = n = value_size-1;
01693 
01694         for( ; n!=0 && v.table[n]==0 ; --n);
01695 
01696         if( n==0 && v.table[n]==0 )
01697             return 1;
01698 
01699         for( ; m!=0 && table[m]==0 ; --m);
01700 
01701         if( m==0 && table[m]==0 )
01702             return 2;
01703 
01704         if( m < n )
01705             return 3;
01706         else
01707         if( m == n )
01708         {
01709             uint  i;
01710             for(i = n ; i!=0 && table[i]==v.table[i] ; --i);
01711             
01712             if( table[i] < v.table[i] )
01713                 return 3;
01714             else
01715             if (table[i] == v.table[i] )
01716                 return 4;
01717         }
01718 
01719     return 0;
01720     }
01721 
01722 
01723 public:
01724 
01725     /*!
01726         the first division algorithm
01727         radix 2
01728     */
01729     uint  Div1 (const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
01730     {
01731     uint  m,n, test;
01732 
01733         test = Div_StandardTest(divisor, m, n, remainder);
01734         if( test < 2 )
01735             return test;
01736 
01737         if( !remainder )
01738         {
01739             UInt<value_size> rem;
01740     
01741         return Div1_Calculate(divisor, rem);
01742         }
01743 
01744     return Div1_Calculate(divisor, *remainder);
01745     }
01746 
01747 
01748     /*!
01749         the first division algorithm
01750         radix 2
01751     */
01752     uint  Div1 (const UInt<value_size> & divisor, UInt<value_size> & remainder)
01753     {
01754         return Div1 (divisor, &remainder);
01755     }
01756 
01757 
01758 private:
01759 
01760     uint  Div1_Calculate(const UInt<value_size> & divisor, UInt<value_size> & rest)
01761     {
01762         if( this == &divisor )
01763         {
01764             UInt<value_size> divisor_copy(divisor);
01765             return Div1_CalculateRef(divisor_copy, rest);
01766         }
01767         else
01768         {
01769             return Div1_CalculateRef(divisor, rest);
01770         }
01771     }
01772 
01773 
01774     uint  Div1_CalculateRef(const UInt<value_size> & divisor, UInt<value_size> & rest)
01775     {
01776     TTMATH_REFERENCE_ASSERT( divisor )
01777     
01778     sint loop;
01779     sint c;
01780 
01781         rest.SetZero();
01782         loop = value_size * TTMATH_BITS_PER_UINT;
01783         c = 0;
01784 
01785         
01786     div_a:
01787         c = Rcl (1, c);
01788         c = rest.Add (rest,c);
01789         c = rest.Sub (divisor,c);
01790 
01791         c = !c;
01792 
01793         if(!c)
01794             goto div_d;
01795 
01796 
01797     div_b:
01798         --loop;
01799         if(loop)
01800             goto div_a;
01801 
01802         c = Rcl(1, c);
01803         TTMATH_LOG("UInt ::Div1_Calculate")
01804         return 0;
01805 
01806 
01807     div_c:
01808         c = Rcl(1, c);
01809         c = rest.Add (rest,c);
01810         c = rest.Add (divisor);
01811 
01812         if(c)
01813             goto div_b;
01814 
01815 
01816     div_d:
01817         --loop;
01818         if(loop)
01819             goto div_c;
01820 
01821         c = Rcl(1, c);
01822         c = rest.Add (divisor);
01823 
01824         TTMATH_LOG("UInt ::Div1_Calculate")
01825 
01826     return 0;
01827     }
01828     
01829 
01830 public:
01831 
01832     /*!
01833         the second division algorithm
01834 
01835         return values:
01836             0 - ok
01837             1 - division by zero
01838     */
01839     uint  Div2 (const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
01840     {
01841         if( this == &divisor )
01842         {
01843             UInt<value_size> divisor_copy(divisor);
01844             return Div2Ref(divisor_copy, remainder);
01845         }
01846         else
01847         {
01848             return Div2Ref(divisor, remainder);
01849         }
01850     }
01851 
01852 
01853     /*!
01854         the second division algorithm
01855 
01856         return values:
01857             0 - ok
01858             1 - division by zero
01859     */
01860     uint  Div2 (const UInt<value_size> & divisor, UInt<value_size> & remainder)
01861     {
01862         return Div2 (divisor, &remainder);
01863     }
01864 
01865 
01866 private:
01867 
01868     /*!
01869         the second division algorithm
01870 
01871         return values:
01872             0 - ok
01873             1 - division by zero
01874     */
01875     uint  Div2Ref(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
01876     {
01877         uint  bits_diff;
01878         uint  status = Div2_Calculate(divisor, remainder, bits_diff);
01879         if( status < 2 )
01880             return status;
01881 
01882         if( CmpBiggerEqual (divisor) )
01883         {
01884             Div2 (divisor, remainder);
01885             SetBit (bits_diff);
01886         }
01887         else
01888         {
01889             if( remainder )
01890                 *remainder = *this;
01891 
01892             SetZero ();
01893             SetBit (bits_diff);
01894         }
01895 
01896         TTMATH_LOG("UInt::Div2")
01897 
01898     return 0;
01899     }
01900 
01901 
01902     /*!
01903         return values:
01904             0 - we've calculated the division
01905             1 - division by zero
01906             2 - we have to still calculate
01907 
01908     */
01909     uint  Div2_Calculate(const UInt <value_size> & divisor, UInt <value_size> * remainder,
01910                                                             uint  & bits_diff)
01911     {
01912     uint  table_id, index;
01913     uint  divisor_table_id, divisor_index;
01914 
01915         uint  status = Div2_FindLeadingBitsAndCheck(    divisor, remainder,
01916                                                     table_id, index,
01917                                                     divisor_table_id, divisor_index);
01918 
01919         if( status < 2 )
01920         {
01921             TTMATH_LOG("UInt::Div2_Calculate")
01922             return status;
01923         }
01924         
01925         // here we know that 'this' is greater than divisor
01926         // then 'index' is greater or equal 'divisor_index'
01927         bits_diff = index - divisor_index;
01928 
01929         UInt <value_size> divisor_copy(divisor);
01930         divisor_copy.Rcl (bits_diff, 0);
01931 
01932         if( CmpSmaller (divisor_copy, table_id) )
01933         {
01934             divisor_copy.Rcr(1);
01935             --bits_diff;
01936         }
01937 
01938         Sub (divisor_copy, 0);
01939 
01940         TTMATH_LOG("UInt::Div2_Calculate")
01941 
01942     return 2;
01943     }
01944 
01945 
01946     /*!
01947         return values:
01948             0 - we've calculated the division
01949             1 - division by zero
01950             2 - we have to still calculate
01951     */
01952     uint  Div2_FindLeadingBitsAndCheck(    const UInt <value_size> & divisor,
01953                                         UInt <value_size> * remainder,
01954                                         uint  & table_id, uint  & index,
01955                                         uint  & divisor_table_id, uint  & divisor_index)
01956     {
01957         if( !divisor.FindLeadingBit(divisor_table_id, divisor_index) )
01958         {
01959             // division by zero
01960             TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
01961             return 1;
01962         }
01963 
01964         if(    !FindLeadingBit (table_id, index) )
01965         {
01966             // zero is divided by something
01967             
01968             SetZero ();
01969 
01970             if( remainder )
01971                 remainder->SetZero();
01972 
01973             TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
01974 
01975         return 0;
01976         }
01977     
01978         divisor_index += divisor_table_id * TTMATH_BITS_PER_UINT;
01979         index         += table_id         * TTMATH_BITS_PER_UINT;
01980 
01981         if( divisor_table_id == 0 )
01982         {
01983             // dividor has only one 32-bit word
01984 
01985             uint  r;
01986             DivInt (divisor.table[0], &r);
01987 
01988             if( remainder )
01989             {
01990                 remainder->SetZero();
01991                 remainder->table[0] = r;
01992             }
01993 
01994             TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
01995 
01996         return 0;
01997         }
01998     
01999 
02000         if( Div2_DivisorGreaterOrEqual(    divisor, remainder,
02001                                         table_id, index,
02002                                         divisor_index) )
02003         {
02004             TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
02005             return 0;
02006         }
02007 
02008 
02009         TTMATH_LOG("UInt ::Div2_FindLeadingBitsAndCheck")
02010 
02011     return 2;
02012     }
02013 
02014 
02015     /*!
02016         return values:
02017             true if divisor is equal or greater than 'this'
02018     */
02019     bool Div2_DivisorGreaterOrEqual(    const UInt <value_size> & divisor,
02020                                         UInt <value_size> * remainder, 
02021                                         uint  table_id, uint  index,
02022                                         uint  divisor_index  )
02023     {
02024         if( divisor_index > index )
02025         {
02026             // divisor is greater than this
02027 
02028             if( remainder )
02029                 *remainder = *this;
02030 
02031             SetZero ();
02032 
02033             TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
02034 
02035         return true;
02036         }
02037 
02038         if( divisor_index == index )
02039         {
02040             // table_id == divisor_table_id as well
02041 
02042             uint  i;
02043             for(i = table_id ; i!=0 && table[i]==divisor.table[i] ; --i);
02044             
02045             if( table[i] < divisor.table[i] )
02046             {
02047                 // divisor is greater than 'this'
02048 
02049                 if( remainder )
02050                     *remainder = *this;
02051 
02052                 SetZero ();
02053 
02054                 TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
02055 
02056             return true;
02057             }
02058             else
02059             if( table[i] == divisor.table[i] )
02060             {
02061                 // divisor is equal 'this'
02062 
02063                 if( remainder )
02064                     remainder->SetZero();
02065 
02066                 SetOne ();
02067 
02068                 TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
02069 
02070             return true;
02071             }
02072         }
02073 
02074         TTMATH_LOG("UInt ::Div2_DivisorGreaterOrEqual")
02075 
02076     return false;
02077     }
02078 
02079 
02080 public:
02081 
02082     /*!
02083         the third division algorithm
02084     */
02085     uint  Div3 (const UInt<value_size> & ss2, UInt<value_size> * remainder = 0)
02086     {
02087         if( this == &ss2 )
02088         {
02089             UInt<value_size> copy_ss2(ss2);
02090             return Div3Ref(copy_ss2, remainder);
02091         }
02092         else
02093         {
02094             return Div3Ref(ss2, remainder);
02095         }
02096     }
02097 
02098 
02099     /*!
02100         the third division algorithm
02101     */
02102     uint  Div3 (const UInt<value_size> & ss2, UInt<value_size> & remainder)
02103     {
02104         return Div3 (ss2, &remainder);
02105     }
02106 
02107 
02108 private:
02109 
02110     /*!
02111         the third division algorithm
02112 
02113         this algorithm is described in the following book:
02114             "The art of computer programming 2" (4.3.1 page 272)
02115             Donald E. Knuth 
02116         !! give the description here (from the book)
02117     */
02118     uint  Div3Ref(const UInt<value_size> & v, UInt<value_size> * remainder = 0)
02119     {
02120     uint  m,n, test;
02121 
02122         test = Div_StandardTest(v, m, n, remainder);
02123         if( test < 2 )
02124             return test;
02125 
02126         if( n == 0 )
02127         {
02128             uint  r;
02129             DivInt ( v.table [0], &r );
02130 
02131             if( remainder )
02132             {
02133                 remainder->SetZero();
02134                 remainder->table[0] = r;
02135             }
02136 
02137             TTMATH_LOG("UInt::Div3")
02138 
02139         return 0;
02140         }
02141 
02142 
02143         // we can only use the third division algorithm when 
02144         // the divisor is greater or equal 2^32 (has more than one 32-bit word)
02145         ++m;
02146         ++n;
02147         m = m - n; 
02148         Div3_Division(v, remainder, m, n);
02149 
02150         TTMATH_LOG("UInt ::Div3 ")
02151 
02152     return 0;
02153     }
02154 
02155 
02156 
02157 private:
02158 
02159 
02160     void Div3_Division(UInt <value_size> v, UInt <value_size> * remainder, uint  m, uint  n)
02161     {
02162     TTMATH_ASSERT( n>=2 )
02163 
02164     UInt <value_size+1> uu, vv;
02165     UInt <value_size> q;
02166     uint  d, u_value_size, u0, u1, u2, v1, v0, j=m;    
02167     
02168         u_value_size = Div3_Normalize(v, n, d);
02169 
02170         if( j+n == value_size )
02171             u2 = u_value_size;
02172         else
02173             u2 = table[j+n];
02174 
02175         Div3_MakeBiggerV(v, vv);
02176 
02177         for(uint  i = j+1 ; i<value_size ; ++i)
02178             q.table[i] = 0;
02179 
02180         while( true )
02181         {
02182             u1 = table[j+n-1];
02183             u0 = table[j+n-2];
02184             v1 = v.table[n-1];
02185             v0 = v.table[n-2];
02186 
02187             uint  qp = Div3_Calculate(u2,u1,u0, v1,v0);
02188 
02189             Div3_MakeNewU(uu, j, n, u2);
02190             Div3_MultiplySubtract(uu, vv, qp);
02191             Div3_CopyNewU(uu, j, n);
02192 
02193             q.table[j] = qp;
02194 
02195             // the next loop
02196             if( j-- == 0 )
02197                 break;
02198 
02199             u2 = table[j+n];
02200         }
02201 
02202         if( remainder )
02203             Div3_Unnormalize(remainder, n, d);
02204 
02205     *this = q;
02206 
02207     TTMATH_LOG("UInt::Div3_Division")
02208     }
02209 
02210 
02211     void Div3_MakeNewU(UInt<value_size+1> & uu, uint  j, uint  n, uint  u_max)
02212     {
02213     uint  i;
02214 
02215         for(i=0 ; i<n ; ++i, ++j)
02216             uu.table[i] = table[j];
02217 
02218         // 'n' is from <1..value_size> so and 'i' is from <0..value_size>
02219         // then table[i] is always correct (look at the declaration of 'uu')
02220         uu.table[i] = u_max;
02221 
02222         for( ++i ; i<value_size+1 ; ++i)
02223             uu.table[i] = 0;
02224 
02225         TTMATH_LOG("UInt::Div3_MakeNewU")
02226     }
02227 
02228 
02229     void Div3_CopyNewU(const UInt<value_size+1> & uu, uint  j, uint  n)
02230     {
02231     uint  i;
02232 
02233         for(i=0 ; i<n ; ++i)
02234             table[i+j] = uu.table[i];
02235 
02236         if( i+j < value_size )
02237             table[i+j] = uu.table[i];
02238 
02239         TTMATH_LOG("UInt::Div3_CopyNewU")
02240     }
02241 
02242 
02243     /*!
02244         we're making the new 'vv' 
02245         the value is actually the same but the 'table' is bigger (value_size+1)
02246     */
02247     void Div3_MakeBiggerV(const UInt<value_size> & v, UInt<value_size+1> & vv)
02248     {
02249         for(uint  i=0 ; i<value_size ; ++i)
02250             vv.table[i] = v.table[i];
02251 
02252         vv.table[value_size] = 0;
02253 
02254         TTMATH_LOG("UInt::Div3_MakeBiggerV")
02255     }
02256     
02257 
02258     /*!
02259         we're moving all bits from 'v' into the left side of the n-1 word
02260         (the highest bit at v.table[n-1] will be equal one,
02261         the bits from 'this' we're moving the same times as 'v')
02262 
02263         return values:
02264           d - how many times we've moved
02265           return - the next-left value from 'this' (that after table[value_size-1])
02266     */
02267     uint  Div3_Normalize(UInt<value_size> & v, uint  n, uint  & d)
02268     {
02269         // v.table[n-1] is != 0
02270 
02271         uint  bit  = (uint )FindLeadingBitInWord (v.table[n-1]);
02272         uint  move = (TTMATH_BITS_PER_UINT - bit - 1);
02273         uint  res  = table[value_size-1];
02274         d         = move;
02275 
02276         if( move > 0 )
02277         {
02278             v.Rcl (move, 0);
02279             Rcl (move, 0);
02280             res = res >> (bit + 1);
02281         }
02282         else
02283         {
02284             res = 0;
02285         }
02286 
02287         TTMATH_LOG("UInt::Div3_Normalize")
02288 
02289     return res;
02290     }
02291 
02292 
02293     void Div3_Unnormalize(UInt <value_size> * remainder, uint  n, uint  d)
02294     {
02295         for(uint  i=n ; i<value_size ; ++i)
02296             table[i] = 0;
02297 
02298         Rcr (d,0);
02299 
02300         *remainder = *this;
02301 
02302         TTMATH_LOG("UInt::Div3_Unnormalize")
02303     }
02304 
02305 
02306     uint  Div3_Calculate(uint  u2, uint  u1, uint  u0, uint  v1, uint  v0)
02307     {    
02308     UInt<2> u_temp;
02309     uint  rp;
02310     bool next_test;
02311 
02312         TTMATH_ASSERT( v1 != 0 )
02313 
02314         u_temp.table[1] = u2;
02315         u_temp.table[0] = u1;
02316         u_temp.DivInt (v1, &rp);
02317 
02318         TTMATH_ASSERT( u_temp.table[1]==0 || u_temp.table[1]==1 )
02319 
02320         do
02321         {
02322             bool decrease = false;
02323 
02324             if( u_temp.table[1] == 1 )
02325                 decrease = true;
02326             else
02327             {
02328                 UInt<2> temp1, temp2;
02329 
02330                 UInt<2>::MulTwoWords (u_temp.table[0], v0, temp1.table+1, temp1.table);
02331                 temp2.table[1] = rp;
02332                 temp2.table[0] = u0;
02333 
02334                 if( temp1 > temp2 )
02335                     decrease = true;
02336             }
02337 
02338             next_test = false;
02339 
02340             if( decrease )
02341             {
02342                 u_temp.SubOne();
02343 
02344                 rp += v1;
02345 
02346                 if( rp >= v1 ) // it means that there wasn't a carry (r<b from the book)
02347                     next_test = true;
02348             }
02349         }
02350         while( next_test );
02351 
02352         TTMATH_LOG("UInt::Div3_Calculate")
02353 
02354     return u_temp.table[0];
02355     }
02356 
02357 
02358 
02359     void Div3_MultiplySubtract(    UInt <value_size+1> & uu,
02360                                 const UInt <value_size+1> & vv, uint  & qp)
02361     {
02362         // D4 (in the book)
02363 
02364         UInt<value_size+1> vv_temp(vv);
02365         vv_temp.MulInt(qp);
02366 
02367         if( uu.Sub(vv_temp) )  
02368         {
02369             // there was a carry
02370             
02371             //
02372             // !!! this part of code was not tested
02373             //
02374 
02375             --qp;
02376             uu.Add(vv);
02377 
02378             // can be a carry from this additions but it should be ignored 
02379             // because it cancels with the borrow from uu.Sub(vv_temp)
02380         }
02381 
02382         TTMATH_LOG("UInt::Div3_MultiplySubtract")
02383     }
02384 
02385 
02386 
02387 
02388 
02389 
02390 public:
02391 
02392 
02393     /*!
02394         power this = this ^ pow
02395         binary algorithm (r-to-l)
02396 
02397         return values:
02398         0 - ok
02399         1 - carry
02400         2 - incorrect argument (0^0)
02401     */
02402     uint  Pow (UInt<value_size> pow)
02403     {
02404         if(pow.IsZero () && IsZero ())
02405             // we don't define zero^zero
02406             return 2;
02407 
02408         UInt<value_size> start(*this);
02409         UInt<value_size> result;
02410         result.SetOne ();
02411         uint  c = 0;
02412 
02413         while( !c )
02414         {
02415             if( pow.table [0] & 1 )
02416                 c += result.Mul (start);
02417 
02418             pow.Rcr2_one(0);
02419             if( pow.IsZero () )
02420                 break;
02421 
02422             c += start.Mul (start);
02423         }
02424 
02425         *this = result;
02426 
02427         TTMATH_LOGC("UInt::Pow(UInt<>)", c)
02428 
02429     return (c==0)? 0 : 1;
02430     }
02431 
02432 
02433     /*!
02434         square root
02435         e.g. Sqrt(9) = 3
02436         ('digit-by-digit' algorithm)
02437     */
02438     void Sqrt ()
02439     {
02440     UInt<value_size> bit, temp;
02441 
02442         if( IsZero () )
02443             return;
02444 
02445         UInt<value_size> value(*this);
02446 
02447         SetZero ();
02448         bit.SetZero ();
02449         bit.table [value_size-1] = (TTMATH_UINT_HIGHEST_BIT >> 1);
02450         
02451         while( bit > value )
02452             bit.Rcr (2);
02453 
02454         while( !bit.IsZero () )
02455         {
02456             temp = *this;
02457             temp.Add (bit);
02458 
02459             if( value >= temp )
02460             {
02461                 value.Sub (temp);
02462                 Rcr (1);
02463                 Add (bit);
02464             }
02465             else
02466             {
02467                 Rcr (1);
02468             }
02469 
02470             bit.Rcr (2);
02471         }
02472 
02473         TTMATH_LOG("UInt::Sqrt")
02474     }
02475 
02476 
02477 
02478     /*!
02479         this method sets n first bits to value zero
02480 
02481         For example:
02482         let n=2 then if there's a value 111 (bin) there'll be '100' (bin)
02483     */
02484     void ClearFirstBits (uint  n)
02485     {
02486         if( n >= value_size*TTMATH_BITS_PER_UINT )
02487         {
02488             SetZero ();
02489             TTMATH_LOG("UInt::ClearFirstBits")
02490             return;
02491         }
02492 
02493         uint  * p = table ;
02494 
02495         // first we're clearing the whole words
02496         while( n >= TTMATH_BITS_PER_UINT )
02497         {
02498             *p++ = 0;
02499             n   -= TTMATH_BITS_PER_UINT;
02500         }
02501 
02502         if( n == 0 )
02503         {
02504             TTMATH_LOG("UInt::ClearFirstBits")
02505             return;
02506         }
02507 
02508         // and then we're clearing one word which has left
02509         // mask -- all bits are set to one
02510         uint  mask = TTMATH_UINT_MAX_VALUE;
02511 
02512         mask = mask << n;
02513 
02514         (*p) &= mask;
02515 
02516         TTMATH_LOG("UInt::ClearFirstBits")
02517     }
02518 
02519 
02520     /*!
02521         this method returns true if the highest bit of the value is set
02522     */
02523     bool IsTheHighestBitSet () const
02524     {
02525         return (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) != 0;
02526     }
02527 
02528 
02529     /*!
02530         this method returns true if the lowest bit of the value is set
02531     */
02532     bool IsTheLowestBitSet () const
02533     {
02534         return (*table & 1) != 0;
02535     }
02536 
02537 
02538     /*!
02539         returning true if only the highest bit is set
02540     */
02541     bool IsOnlyTheHighestBitSet () const
02542     {
02543 #ifdef __clang__
02544 #pragma clang diagnostic push
02545 #pragma clang diagnostic ignored "-Wtautological-compare"
02546 #endif
02547 
02548         for(uint  i=0 ; i<value_size-1 ; ++i)
02549             if( table[i] != 0 )
02550                 return false;
02551 
02552 #ifdef __clang__
02553 #pragma clang diagnostic pop
02554 #endif
02555         if( table[value_size-1] != TTMATH_UINT_HIGHEST_BIT )
02556             return false;
02557 
02558     return true;
02559     }
02560 
02561 
02562     /*!
02563         returning true if only the lowest bit is set
02564     */
02565     bool IsOnlyTheLowestBitSet () const
02566     {
02567         if( table[0] != 1 )
02568             return false;
02569 
02570         for(uint  i=1 ; i<value_size ; ++i)
02571             if( table[i] != 0 )
02572                 return false;
02573 
02574     return true;
02575     }
02576 
02577 
02578     /*!
02579         this method returns true if the value is equal zero
02580     */
02581     bool IsZero () const
02582     {
02583         for(uint  i=0 ; i<value_size ; ++i)
02584             if(table[i] != 0)
02585                 return false;
02586 
02587     return true;
02588     }
02589 
02590 
02591     /*!
02592         returning true if first 'bits' bits are equal zero
02593     */
02594     bool AreFirstBitsZero (uint  bits) const
02595     {
02596         TTMATH_ASSERT( bits <= value_size * TTMATH_BITS_PER_UINT )
02597 
02598         uint  index = bits / TTMATH_BITS_PER_UINT;
02599         uint  rest  = bits % TTMATH_BITS_PER_UINT;
02600         uint  i;
02601 
02602         for(i=0 ; i<index ; ++i)
02603             if(table[i] != 0 )
02604                 return false;
02605 
02606         if( rest == 0 )
02607             return true;
02608 
02609         uint  mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
02610 
02611     return (table[i] & mask) == 0;
02612     }
02613 
02614 
02615 
02616     /*!
02617     *
02618     *    conversion methods
02619     *
02620     */
02621 
02622 
02623 
02624     /*!
02625         this method converts an UInt<another_size> type to this class
02626 
02627         this operation has mainly sense if the value from p is 
02628         equal or smaller than that one which is returned from UInt<value_size>::SetMax()
02629 
02630         it returns a carry if the value 'p' is too big
02631     */
02632     template<uint argument_size>
02633     uint  FromUInt (const UInt<argument_size> & p)
02634     {
02635         uint  min_size = (value_size < argument_size)? value_size : argument_size;
02636         uint  i;
02637 
02638         for(i=0 ; i<min_size ; ++i)
02639             table[i] = p.table [i];
02640 
02641 
02642         if( value_size > argument_size )
02643         {    
02644             // 'this' is longer than 'p'
02645 
02646             for( ; i<value_size ; ++i)
02647                 table[i] = 0;
02648         }
02649         else
02650         {
02651             for( ; i<argument_size ; ++i)
02652                 if( p.table [i] != 0 )
02653                 {
02654                     TTMATH_LOGC("UInt::FromUInt(UInt<>)", 1)
02655                     return 1;
02656                 }
02657         }
02658 
02659         TTMATH_LOGC("UInt::FromUInt(UInt<>)", 0)
02660 
02661     return 0;
02662     }
02663 
02664 
02665     /*!
02666         this method converts an UInt<another_size> type to this class
02667 
02668         this operation has mainly sense if the value from p is 
02669         equal or smaller than that one which is returned from UInt<value_size>::SetMax()
02670 
02671         it returns a carry if the value 'p' is too big
02672     */
02673     template<uint argument_size>
02674     uint  FromInt (const UInt<argument_size> & p)
02675     {
02676         return FromUInt (p);
02677     }
02678 
02679 
02680     /*!
02681         this method converts the uint type to this class
02682     */
02683     uint  FromUInt (uint  value)
02684     {
02685         for(uint  i=1 ; i<value_size ; ++i)
02686             table[i] = 0;
02687 
02688         table[0] = value;
02689 
02690         TTMATH_LOG("UInt::FromUInt(uint)")
02691 
02692         // there'll never be a carry here
02693     return 0;
02694     }
02695 
02696 
02697     /*!
02698         this method converts the uint type to this class
02699     */
02700     uint  FromInt (uint  value)
02701     {
02702         return FromUInt (value);
02703     }
02704 
02705 
02706     /*!
02707         this method converts the sint type to this class
02708     */
02709     uint  FromInt (sint value)
02710     {
02711         uint  c = FromUInt (uint (value));
02712 
02713         if( c || value < 0 )
02714             return 1;
02715 
02716     return 0;
02717     }
02718 
02719 
02720     /*!
02721         this operator converts an UInt<another_size> type to this class
02722 
02723         it doesn't return a carry
02724     */
02725     template<uint argument_size>
02726     UInt<value_size> & operator= (const UInt<argument_size> & p)
02727     {
02728         FromUInt (p);
02729 
02730     return *this;
02731     }
02732 
02733 
02734     /*!
02735         the assignment operator
02736     */
02737     UInt<value_size> & operator= (const UInt<value_size> & p)
02738     {
02739         for(uint  i=0 ; i<value_size ; ++i)
02740             table[i] = p.table [i];
02741 
02742         TTMATH_LOG("UInt::operator=(UInt<>)")
02743 
02744         return *this;
02745     }
02746 
02747 
02748     /*!
02749         this method converts the uint type to this class
02750     */
02751     UInt<value_size> & operator= (uint  i)
02752     {
02753         FromUInt (i);
02754 
02755     return *this;
02756     }
02757 
02758 
02759     /*!
02760         a constructor for converting the uint to this class
02761     */
02762     UInt (uint  i)
02763     {
02764         FromUInt (i);
02765     }
02766 
02767 
02768     /*!
02769         this method converts the sint type to this class
02770     */
02771     UInt<value_size> & operator= (sint i)
02772     {
02773         FromInt (i);
02774 
02775     return *this;
02776     }
02777 
02778 
02779     /*!
02780         a constructor for converting the sint to this class
02781 
02782         look at the description of UInt::operator=(sint)
02783     */
02784     UInt (sint i)
02785     {
02786         FromInt (i);
02787     }
02788 
02789 
02790 #ifdef TTMATH_PLATFORM32
02791 
02792 
02793     /*!
02794         this method converts unsigned 64 bit int type to this class
02795         ***this method is created only on a 32bit platform***
02796     */
02797     uint  FromUInt (ulint  n)
02798     {
02799         table[0] = (uint )n;
02800 
02801         if( value_size == 1 )
02802         {
02803             uint  c = ((n >> TTMATH_BITS_PER_UINT) == 0) ? 0 : 1;
02804 
02805             TTMATH_LOGC("UInt::FromUInt(ulint)", c)
02806             return c;
02807         }
02808 
02809         table[1] = (uint )(n >> TTMATH_BITS_PER_UINT);
02810 
02811         for(uint  i=2 ; i<value_size ; ++i)
02812             table[i] = 0;
02813 
02814         TTMATH_LOG("UInt::FromUInt(ulint)")
02815 
02816     return 0;
02817     }
02818 
02819 
02820     /*!
02821         this method converts unsigned 64 bit int type to this class
02822         ***this method is created only on a 32bit platform***
02823     */
02824     uint  FromInt (ulint  n)
02825     {
02826         return FromUInt (n);
02827     }
02828 
02829 
02830     /*!
02831         this method converts signed 64 bit int type to this class
02832         ***this method is created only on a 32bit platform***
02833     */
02834     uint  FromInt (slint n)
02835     {
02836         uint  c = FromUInt (ulint (n));
02837 
02838         if( c || n < 0 )
02839             return 1;
02840 
02841     return 0;
02842     }
02843 
02844 
02845     /*!
02846         this operator converts unsigned 64 bit int type to this class
02847         ***this operator is created only on a 32bit platform***
02848     */
02849     UInt<value_size> & operator= (ulint  n)
02850     {
02851         FromUInt (n);
02852 
02853     return *this;
02854     }
02855 
02856 
02857     /*!
02858         a constructor for converting unsigned 64 bit int to this class
02859         ***this constructor is created only on a 32bit platform***
02860     */
02861     UInt (ulint  n)
02862     {
02863         FromUInt (n);
02864     }
02865 
02866 
02867     /*!
02868         this operator converts signed 64 bit int type to this class
02869         ***this operator is created only on a 32bit platform***
02870     */
02871     UInt<value_size> & operator= (slint n)
02872     {
02873         FromInt (n);
02874 
02875     return *this;
02876     }
02877 
02878 
02879     /*!
02880         a constructor for converting signed 64 bit int to this class
02881         ***this constructor is created only on a 32bit platform***
02882     */
02883     UInt (slint n)
02884     {
02885         FromInt (n);
02886     }
02887 
02888 #endif
02889 
02890 
02891 
02892 #ifdef TTMATH_PLATFORM64
02893 
02894 
02895     /*!
02896         this method converts 32 bit unsigned int type to this class
02897         ***this operator is created only on a 64bit platform***
02898     */
02899     uint  FromUInt (unsigned int i)
02900     {
02901         return FromUInt (uint (i));
02902     }
02903 
02904     /*!
02905         this method converts 32 bit unsigned int type to this class
02906         ***this operator is created only on a 64bit platform***
02907     */
02908     uint  FromInt (unsigned int i)
02909     {
02910         return FromUInt (uint (i));
02911     }
02912 
02913 
02914     /*!
02915         this method converts 32 bit signed int type to this class
02916         ***this operator is created only on a 64bit platform***
02917     */
02918     uint  FromInt (signed int i)
02919     {
02920         return FromInt (sint(i));
02921     }
02922 
02923 
02924     /*!
02925         this operator converts 32 bit unsigned int type to this class
02926         ***this operator is created only on a 64bit platform***
02927     */
02928     UInt<value_size> & operator= (unsigned int i)
02929     {
02930         FromUInt (i);
02931 
02932     return *this;
02933     }
02934 
02935 
02936     /*!
02937         a constructor for converting 32 bit unsigned int to this class
02938         ***this constructor is created only on a 64bit platform***
02939     */
02940     UInt (unsigned int i)
02941     {
02942         FromUInt (i);
02943     }
02944 
02945 
02946     /*!
02947         an operator for converting 32 bit signed int to this class
02948         ***this constructor is created only on a 64bit platform***
02949     */
02950     UInt<value_size> & operator= (signed int i)
02951     {
02952         FromInt (i);
02953 
02954     return *this;
02955     }
02956 
02957 
02958     /*!
02959         a constructor for converting 32 bit signed int to this class
02960         ***this constructor is created only on a 64bit platform***
02961     */
02962     UInt (signed int i)
02963     {
02964         FromInt (i);
02965     }
02966 
02967 
02968 #endif
02969 
02970 
02971 
02972 
02973 
02974     /*!
02975         a constructor for converting a string to this class (with the base=10)
02976     */
02977     UInt (const char * s)
02978     {
02979         FromString (s);
02980     }
02981 
02982 
02983     /*!
02984         a constructor for converting a string to this class (with the base=10)
02985     */
02986     UInt (const std::string & s)
02987     {
02988         FromString ( s.c_str() );
02989     }
02990 
02991 
02992 #ifndef TTMATH_DONT_USE_WCHAR
02993 
02994     /*!
02995         a constructor for converting a string to this class (with the base=10)
02996     */
02997     UInt (const wchar_t * s)
02998     {
02999         FromString (s);
03000     }
03001 
03002 
03003     /*!
03004         a constructor for converting a string to this class (with the base=10)
03005     */
03006     UInt (const std::wstring & s)
03007     {
03008         FromString ( s.c_str() );
03009     }
03010 
03011 #endif
03012 
03013 
03014 
03015 
03016     /*!
03017         a default constructor
03018 
03019         we don't clear the table
03020     */
03021     UInt ()
03022     {
03023     // when macro TTMATH_DEBUG_LOG is defined
03024     // we set special values to the table
03025     // in order to be everywhere the same value of the UInt object
03026     // without this it would be difficult to analyse the log file
03027     #ifdef TTMATH_DEBUG_LOG
03028         #ifdef TTMATH_PLATFORM32
03029                 for(uint  i=0 ; i<value_size ; ++i)
03030                     table[i] = 0xc1c1c1c1;
03031         #else
03032                 for(uint  i=0 ; i<value_size ; ++i)
03033                     table[i] = 0xc1c1c1c1c1c1c1c1;
03034         #endif
03035     #endif
03036     }
03037 
03038 
03039     /*!
03040         a copy constructor
03041     */
03042     UInt (const UInt<value_size> & u)
03043     {
03044         for(uint  i=0 ; i<value_size ; ++i)
03045             table[i] = u.table [i];
03046 
03047         TTMATH_LOG("UInt::UInt(UInt<>)")
03048     }
03049 
03050 
03051 
03052     /*!
03053         a template for producting constructors for copying from another types
03054     */
03055     template<uint argument_size>
03056     UInt (const UInt<argument_size> & u)
03057     {
03058         // look that 'size' we still set as 'value_size' and not as u.value_size
03059         FromUInt (u);
03060     }
03061 
03062 
03063 
03064 
03065     /*!
03066         a destructor
03067     */
03068     ~UInt ()
03069     {
03070     }
03071 
03072 
03073     /*!
03074         this method returns the lowest value from table
03075 
03076         we must be sure when we using this method whether the value
03077         will hold in an uint type or not (the rest value from the table must be zero)
03078     */
03079     uint  ToUInt () const
03080     {
03081         return table[0];
03082     }
03083 
03084 
03085     /*!
03086         this method converts the value to uint type
03087         can return a carry if the value is too long to store it in uint type
03088     */
03089     uint  ToUInt (uint  & result) const
03090     {
03091         result = table[0];
03092 
03093         for(uint  i=1 ; i<value_size ; ++i)
03094             if( table[i] != 0 )
03095                 return 1;
03096 
03097     return 0;
03098     }
03099 
03100 
03101     /*!
03102         this method converts the value to uint type
03103         can return a carry if the value is too long to store it in uint type
03104     */
03105     uint  ToInt (uint  & result) const
03106     {
03107         return ToUInt (result);
03108     }
03109 
03110 
03111     /*!
03112         this method converts the value to sint type (signed integer)
03113         can return a carry if the value is too long to store it in sint type
03114     */
03115     uint  ToInt (sint & result) const
03116     {
03117         result = sint(table[0]);
03118 
03119         if( (result & TTMATH_UINT_HIGHEST_BIT) != 0 )
03120             return 1;
03121 
03122         for(uint  i=1 ; i<value_size ; ++i)
03123             if( table[i] != 0 )
03124                 return 1;
03125 
03126     return 0;
03127     }
03128 
03129 
03130 #ifdef TTMATH_PLATFORM32
03131 
03132     /*!
03133         this method converts the value to ulint type (64 bit unsigned integer)
03134         can return a carry if the value is too long to store it in ulint type
03135         *** this method is created only on a 32 bit platform ***
03136     */
03137     uint  ToUInt (ulint  & result) const
03138     {
03139         if( value_size == 1 )
03140         {
03141             result = table[0];
03142         }
03143         else
03144         {
03145             uint  low  = table[0];
03146             uint  high = table[1];
03147 
03148             result = low;
03149             result |= (ulint (high) << TTMATH_BITS_PER_UINT);
03150 
03151             for(uint  i=2 ; i<value_size ; ++i)
03152                 if( table[i] != 0 )
03153                     return 1;
03154         }
03155 
03156     return 0;
03157     }
03158 
03159 
03160     /*!
03161         this method converts the value to ulint type (64 bit unsigned integer)
03162         can return a carry if the value is too long to store it in ulint type
03163         *** this method is created only on a 32 bit platform ***
03164     */
03165     uint  ToInt (ulint  & result) const
03166     {
03167         return ToUInt (result);
03168     }
03169 
03170 
03171     /*!
03172         this method converts the value to slint type (64 bit signed integer)
03173         can return a carry if the value is too long to store it in slint type
03174         *** this method is created only on a 32 bit platform ***
03175     */
03176     uint  ToInt (slint & result) const
03177     {
03178     ulint  temp;
03179 
03180         uint  c = ToUInt (temp);
03181         result = slint(temp);
03182 
03183         if( c || result < 0 )
03184             return 1;
03185 
03186     return 0;
03187     }
03188 
03189 #endif
03190 
03191 
03192 
03193 #ifdef TTMATH_PLATFORM64
03194 
03195     /*!
03196         this method converts the value to a 32 unsigned integer
03197         can return a carry if the value is too long to store it in this type
03198         *** this method is created only on a 64 bit platform ***
03199     */
03200     uint  ToUInt (unsigned int & result) const
03201     {
03202         result = (unsigned int)table[0];
03203 
03204         if( (table[0] >> 32) != 0 )
03205             return 1;
03206 
03207         for(uint  i=1 ; i<value_size ; ++i)
03208             if( table[i] != 0 )
03209                 return 1;
03210 
03211     return 0;
03212     }
03213 
03214 
03215     /*!
03216         this method converts the value to a 32 unsigned integer
03217         can return a carry if the value is too long to store it in this type
03218         *** this method is created only on a 64 bit platform ***
03219     */
03220     uint  ToInt (unsigned int & result) const
03221     {
03222         return ToUInt (result);
03223     }
03224 
03225 
03226     /*!
03227         this method converts the value to a 32 signed integer
03228         can return a carry if the value is too long to store it in this type
03229         *** this method is created only on a 64 bit platform ***
03230     */
03231     uint  ToInt (int & result) const
03232     {
03233     unsigned int temp;
03234 
03235         uint  c = ToUInt (temp);
03236         result = int(temp);
03237 
03238         if( c || result < 0 )
03239             return 1;
03240 
03241     return 0;
03242     }
03243 
03244 
03245 #endif
03246 
03247 
03248 
03249 
03250 protected:
03251 
03252     /*!
03253         an auxiliary method for converting into the string
03254         it returns the log (with the base 2) from x
03255         where x is in <2;16>
03256     */
03257     double ToStringLog2 (uint  x) const
03258     {
03259         static double log_tab[] = {
03260             1.000000000000000000,
03261             0.630929753571457437,
03262             0.500000000000000000,
03263             0.430676558073393050,
03264             0.386852807234541586,
03265             0.356207187108022176,
03266             0.333333333333333333,
03267             0.315464876785728718,
03268             0.301029995663981195,
03269             0.289064826317887859,
03270             0.278942945651129843,
03271             0.270238154427319741,
03272             0.262649535037193547,
03273             0.255958024809815489,
03274             0.250000000000000000
03275         };
03276 
03277         if( x<2 || x>16 )
03278             return 0;
03279 
03280     return log_tab[x-2];
03281     }
03282 
03283 
03284 public:
03285 
03286 
03287     /*!    
03288         an auxiliary method for converting to a string
03289         it's used from Int::ToString() too (negative is set true then)
03290     */
03291     template<class string_type>
03292     void ToStringBase (string_type & result, uint  b = 10, bool negative = false) const
03293     {
03294     UInt<value_size> temp(*this);
03295     uint  rest, table_id, index, digits;
03296     double digits_d;
03297     char character;
03298 
03299         result.clear();
03300 
03301         if( b<2 || b>16 )
03302             return;
03303 
03304         if( !FindLeadingBit (table_id, index) )
03305         {
03306             result = '0';
03307             return;
03308         }
03309 
03310         if( negative )
03311             result = '-';
03312 
03313         digits_d  = table_id; // for not making an overflow in uint type
03314         digits_d *= TTMATH_BITS_PER_UINT;
03315         digits_d += index + 1;
03316         digits_d *= ToStringLog2 (b);
03317         digits = static_cast<uint >(digits_d) + 3; // plus some epsilon
03318 
03319         if( result.capacity() < digits )
03320             result.reserve(digits);
03321 
03322         do
03323         {
03324             temp.DivInt (b, &rest);
03325             character = static_cast<char>(Misc::DigitToChar (rest));
03326             result.insert(result.end(), character);
03327         }
03328         while( !temp.IsZero () );
03329 
03330         size_t i1 = negative ? 1 : 0; // the first is a hyphen (when negative is true)
03331         size_t i2 = result.size() - 1;
03332 
03333         for( ; i1 < i2 ; ++i1, --i2 )
03334         {
03335             char tempc = static_cast<char>(result[i1]);
03336             result[i1] = result[i2];
03337             result[i2] = tempc;
03338         }
03339     }
03340 
03341 
03342 
03343     /*!    
03344         this method converts the value to a string with a base equal 'b'
03345     */
03346     void ToString (std::string & result, uint  b = 10) const
03347     {
03348         return ToStringBase (result, b);
03349     }
03350 
03351 
03352     std::string ToString (uint  b = 10) const
03353     {
03354         std::string result;
03355         ToStringBase (result, b);
03356     
03357     return result;
03358     }
03359 
03360 
03361 #ifndef TTMATH_DONT_USE_WCHAR
03362 
03363     void ToString (std::wstring & result, uint  b = 10) const
03364     {
03365         return ToStringBase (result, b);
03366     }
03367 
03368     std::wstring ToWString(uint  b = 10) const
03369     {
03370         std::wstring result;
03371         ToStringBase (result, b);
03372     
03373     return result;
03374     }
03375 
03376 #endif
03377 
03378 
03379 
03380 private:
03381 
03382     /*!
03383         an auxiliary method for converting from a string
03384     */
03385     template<class char_type>
03386     uint  FromStringBase(const char_type * s, uint  b = 10, const char_type ** after_source = 0, bool * value_read = 0)
03387     {
03388     UInt<value_size> base( b );
03389     UInt<value_size> temp;
03390     sint z;
03391     uint  c = 0;
03392 
03393         SetZero ();
03394         temp.SetZero();
03395         Misc::SkipWhiteCharacters(s);
03396 
03397         if( after_source )
03398             *after_source = s;
03399 
03400         if( value_read )
03401             *value_read = false;
03402 
03403         if( b<2 || b>16 )
03404             return 1;
03405 
03406 
03407         for( ; (z=Misc::CharToDigit (*s, b)) != -1 ; ++s)
03408         {
03409             if( value_read )
03410                 *value_read = true;
03411 
03412             if( c == 0 )
03413             {
03414                 temp.table[0] = z;
03415 
03416                 c += Mul (base); // !! IMPROVE ME: there can be used MulInt here
03417                 c += Add (temp);
03418             }
03419         }        
03420 
03421         if( after_source )
03422             *after_source = s;
03423 
03424         TTMATH_LOGC("UInt::FromString", c)
03425 
03426     return (c==0)? 0 : 1;
03427     }
03428 
03429 
03430 public:
03431 
03432 
03433     /*!
03434         this method converts a string into its value
03435         it returns carry=1 if the value will be too big or an incorrect base 'b' is given
03436 
03437         string is ended with a non-digit value, for example:
03438             "12" will be translated to 12
03439             as well as:
03440             "12foo" will be translated to 12 too
03441 
03442         existing first white characters will be ommited
03443 
03444         if the value from s is too large the rest digits will be skipped
03445 
03446         after_source (if exists) is pointing at the end of the parsed string
03447 
03448         value_read (if exists) tells whether something has actually been read (at least one digit)
03449     */
03450     uint  FromString (const char * s, uint  b = 10, const char ** after_source = 0, bool * value_read = 0)
03451     {
03452         return FromStringBase(s, b, after_source, value_read);
03453     }
03454 
03455 
03456     /*!
03457         this method converts a string into its value
03458 
03459         (it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
03460     */
03461     uint  FromString (const std::string & s, uint  b = 10)
03462     {
03463         return FromString ( s.c_str(), b );
03464     }
03465 
03466 
03467     /*!
03468         this operator converts a string into its value (with base = 10)
03469     */
03470     UInt<value_size> & operator= (const char * s)
03471     {
03472         FromString (s);
03473 
03474     return *this;
03475     }
03476 
03477 
03478     /*!
03479         this operator converts a string into its value (with base = 10)
03480     */
03481     UInt<value_size> & operator= (const std::string & s)
03482     {
03483         FromString ( s.c_str() );
03484 
03485     return *this;
03486     }
03487 
03488 
03489 
03490 #ifndef TTMATH_DONT_USE_WCHAR
03491 
03492     /*!
03493         this method converts a string into its value
03494     */
03495     uint  FromString (const wchar_t * s, uint  b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
03496     {
03497         return FromStringBase(s, b, after_source, value_read);
03498     }
03499 
03500 
03501     /*!
03502         this method converts a string into its value
03503 
03504         (it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
03505     */
03506     uint  FromString (const std::wstring & s, uint  b = 10)
03507     {
03508         return FromString ( s.c_str(), b );
03509     }
03510 
03511 
03512     /*!
03513         this operator converts a string into its value (with base = 10)
03514     */
03515     UInt<value_size> & operator= (const wchar_t * s)
03516     {
03517         FromString (s);
03518 
03519     return *this;
03520     }
03521 
03522 
03523     /*!
03524         this operator converts a string into its value (with base = 10)
03525     */
03526     UInt<value_size> & operator= (const std::wstring & s)
03527     {
03528         FromString ( s.c_str() );
03529 
03530     return *this;
03531     }
03532 
03533 #endif
03534 
03535 
03536     /*!
03537     *
03538     *    methods for comparing
03539     *
03540     */
03541 
03542 
03543     /*!
03544         this method returns true if 'this' is smaller than 'l'
03545 
03546         'index' is an index of the first word from will be the comparison performed
03547         (note: we start the comparison from back - from the last word, when index is -1 /default/
03548         it is automatically set into the last word)
03549         I introduced it for some kind of optimization made in the second division algorithm (Div2)
03550     */
03551     bool CmpSmaller (const UInt<value_size> & l, sint index = -1) const
03552     {
03553     sint i;
03554 
03555         if( index==-1 || index>=sint(value_size) )
03556             i = value_size - 1;
03557         else
03558             i = index;
03559 
03560 
03561         for( ; i>=0 ; --i)
03562         {
03563             if( table[i] != l.table [i] )
03564                 return table[i] < l.table [i];
03565         }
03566 
03567     // they're equal
03568     return false;
03569     }
03570 
03571 
03572 
03573     /*!
03574         this method returns true if 'this' is bigger than 'l'
03575 
03576         'index' is an index of the first word from will be the comparison performed
03577         (note: we start the comparison from back - from the last word, when index is -1 /default/
03578         it is automatically set into the last word)
03579 
03580         I introduced it for some kind of optimization made in the second division algorithm (Div2)
03581     */
03582     bool CmpBigger (const UInt<value_size> & l, sint index = -1) const
03583     {
03584     sint i;
03585 
03586         if( index==-1 || index>=sint(value_size) )
03587             i = value_size - 1;
03588         else
03589             i = index;
03590 
03591 
03592         for( ; i>=0 ; --i)
03593         {
03594             if( table[i] != l.table [i] )
03595                 return table[i] > l.table [i];
03596         }
03597 
03598     // they're equal
03599     return false;
03600     }
03601 
03602 
03603     /*!
03604         this method returns true if 'this' is equal 'l'
03605 
03606         'index' is an index of the first word from will be the comparison performed
03607         (note: we start the comparison from back - from the last word, when index is -1 /default/
03608         it is automatically set into the last word)
03609     */
03610     bool CmpEqual (const UInt<value_size> & l, sint index = -1) const
03611     {
03612     sint i;
03613 
03614         if( index==-1 || index>=sint(value_size) )
03615             i = value_size - 1;
03616         else
03617             i = index;
03618 
03619 
03620         for( ; i>=0 ; --i)
03621             if( table[i] != l.table [i] )
03622                 return false;
03623 
03624     return true;
03625     }
03626 
03627 
03628 
03629     /*!
03630         this method returns true if 'this' is smaller than or equal 'l'
03631 
03632         'index' is an index of the first word from will be the comparison performed
03633         (note: we start the comparison from back - from the last word, when index is -1 /default/
03634         it is automatically set into the last word)
03635     */
03636     bool CmpSmallerEqual (const UInt<value_size> & l, sint index=-1) const
03637     {
03638     sint i;
03639 
03640         if( index==-1 || index>=sint(value_size) )
03641             i = value_size - 1;
03642         else
03643             i = index;
03644 
03645 
03646         for( ; i>=0 ; --i)
03647         {
03648             if( table[i] != l.table [i] )
03649                 return table[i] < l.table [i];
03650         }
03651 
03652     // they're equal
03653     return true;
03654     }
03655 
03656 
03657 
03658     /*!
03659         this method returns true if 'this' is bigger than or equal 'l'
03660 
03661         'index' is an index of the first word from will be the comparison performed
03662         (note: we start the comparison from back - from the last word, when index is -1 /default/
03663         it is automatically set into the last word)
03664     */
03665     bool CmpBiggerEqual (const UInt<value_size> & l, sint index=-1) const
03666     {
03667     sint i;
03668 
03669         if( index==-1 || index>=sint(value_size) )
03670             i = value_size - 1;
03671         else
03672             i = index;
03673 
03674 
03675         for( ; i>=0 ; --i)
03676         {
03677             if( table[i] != l.table [i] )
03678                 return table[i] > l.table [i];
03679         }
03680 
03681     // they're equal
03682     return true;
03683     }
03684 
03685 
03686     /*
03687         operators for comparising
03688     */
03689 
03690     bool operator<(const UInt<value_size> & l) const
03691     {
03692         return CmpSmaller (l);
03693     }
03694 
03695 
03696     bool operator>(const UInt<value_size> & l) const
03697     {
03698         return CmpBigger (l);
03699     }
03700 
03701 
03702     bool operator==(const UInt<value_size> & l) const
03703     {
03704         return CmpEqual (l);
03705     }
03706 
03707 
03708     bool operator!=(const UInt<value_size> & l) const
03709     {
03710         return !operator==(l);
03711     }
03712 
03713 
03714     bool operator<=(const UInt<value_size> & l) const
03715     {
03716         return CmpSmallerEqual (l);
03717     }
03718 
03719     bool operator>=(const UInt<value_size> & l) const
03720     {
03721         return CmpBiggerEqual (l);
03722     }
03723 
03724 
03725     /*!
03726     *
03727     *    standard mathematical operators 
03728     *
03729     */
03730 
03731     UInt<value_size> operator- (const UInt<value_size> & p2) const
03732     {
03733     UInt<value_size> temp(*this);
03734 
03735         temp.Sub (p2);
03736 
03737     return temp;
03738     }
03739 
03740     UInt<value_size> & operator-=(const UInt<value_size> & p2)
03741     {
03742         Sub (p2);
03743 
03744     return *this;
03745     }
03746 
03747     UInt<value_size> operator+(const UInt<value_size> & p2) const
03748     {
03749     UInt<value_size> temp(*this);
03750 
03751         temp.Add(p2);
03752 
03753     return temp;
03754     }
03755 
03756     UInt<value_size> & operator+=(const UInt<value_size> & p2)
03757     {
03758         Add (p2);
03759 
03760     return *this;
03761     }
03762 
03763 
03764     UInt<value_size> operator*(const UInt<value_size> & p2) const
03765     {
03766     UInt<value_size> temp(*this);
03767 
03768         temp.Mul(p2);
03769 
03770     return temp;
03771     }
03772 
03773 
03774     UInt<value_size> & operator*=(const UInt<value_size> & p2)
03775     {
03776         Mul (p2);
03777 
03778     return *this;
03779     }
03780 
03781 
03782     UInt<value_size> operator/(const UInt<value_size> & p2) const
03783     {
03784     UInt<value_size> temp(*this);
03785 
03786         temp.Div(p2);
03787 
03788     return temp;
03789     }
03790 
03791 
03792     UInt<value_size> & operator/=(const UInt<value_size> & p2)
03793     {
03794         Div (p2);
03795 
03796     return *this;
03797     }
03798 
03799 
03800     UInt<value_size> operator%(const UInt<value_size> & p2) const
03801     {
03802     UInt<value_size> temp(*this);
03803     UInt<value_size> remainder;
03804     
03805         temp.Div( p2, remainder );
03806 
03807     return remainder;
03808     }
03809 
03810 
03811     UInt<value_size> & operator%=(const UInt<value_size> & p2)
03812     {
03813     UInt<value_size> remainder;
03814     
03815         Div ( p2, remainder );
03816         operator= (remainder);
03817 
03818     return *this;
03819     }
03820 
03821 
03822     /*!
03823         Prefix operator e.g ++variable
03824     */
03825     UInt<value_size> & operator++ ()
03826     {
03827         AddOne ();
03828 
03829     return *this;
03830     }
03831 
03832 
03833     /*!
03834         Postfix operator e.g variable++
03835     */
03836     UInt<value_size> operator++ (int)
03837     {
03838     UInt<value_size> temp( *this );
03839 
03840         AddOne ();
03841 
03842     return temp;
03843     }
03844 
03845 
03846     UInt<value_size> & operator--()
03847     {
03848         SubOne ();
03849 
03850     return *this;
03851     }
03852 
03853 
03854     UInt<value_size> operator--(int)
03855     {
03856     UInt<value_size> temp( *this );
03857 
03858         SubOne ();
03859 
03860     return temp;
03861     }
03862 
03863 
03864 
03865     /*!
03866     *
03867     *    bitwise operators
03868     *
03869     */
03870 
03871     UInt<value_size> operator~ () const
03872     {
03873         UInt<value_size> temp( *this );
03874 
03875         temp.BitNot ();
03876 
03877     return temp;
03878     }
03879 
03880 
03881     UInt<value_size> operator&(const UInt<value_size> & p2) const
03882     {
03883         UInt<value_size> temp( *this );
03884 
03885         temp.BitAnd(p2);
03886 
03887     return temp;
03888     }
03889 
03890 
03891     UInt<value_size> & operator&=(const UInt<value_size> & p2)
03892     {
03893         BitAnd (p2);
03894 
03895     return *this;
03896     }
03897 
03898 
03899     UInt<value_size> operator|(const UInt<value_size> & p2) const
03900     {
03901         UInt<value_size> temp( *this );
03902 
03903         temp.BitOr(p2);
03904 
03905     return temp;
03906     }
03907 
03908 
03909     UInt<value_size> & operator|=(const UInt<value_size> & p2)
03910     {
03911         BitOr (p2);
03912 
03913     return *this;
03914     }
03915 
03916 
03917     UInt<value_size> operator^(const UInt<value_size> & p2) const
03918     {
03919         UInt<value_size> temp( *this );
03920 
03921         temp.BitXor(p2);
03922 
03923     return temp;
03924     }
03925 
03926 
03927     UInt<value_size> & operator^=(const UInt<value_size> & p2)
03928     {
03929         BitXor (p2);
03930 
03931     return *this;
03932     }
03933 
03934 
03935     UInt<value_size> operator>>(int move) const
03936     {
03937     UInt<value_size> temp( *this );
03938 
03939         temp.Rcr(move);
03940 
03941     return temp;
03942     }
03943 
03944 
03945     UInt<value_size> & operator>>=(int move)
03946     {
03947         Rcr (move);
03948 
03949     return *this;
03950     }
03951 
03952 
03953     UInt<value_size> operator<<(int move) const
03954     {
03955     UInt<value_size> temp( *this );
03956 
03957         temp.Rcl(move);
03958 
03959     return temp;
03960     }
03961 
03962 
03963     UInt<value_size> & operator<<=(int move)
03964     {
03965         Rcl (move);
03966 
03967     return *this;
03968     }
03969 
03970 
03971     /*!
03972     *
03973     *    input/output operators for standard streams
03974     *    
03975     *    (they are very simple, in the future they should be changed)
03976     *
03977     */
03978 
03979 
03980 private:
03981 
03982 
03983     /*!
03984         an auxiliary method for outputing to standard streams
03985     */
03986     template<class ostream_type, class string_type>
03987     static ostream_type & OutputToStream(ostream_type & s, const UInt<value_size> & l)
03988     {
03989     string_type ss;
03990 
03991         l.ToString(ss);
03992         s << ss;
03993 
03994     return s;
03995     }
03996 
03997 
03998 public:
03999 
04000 
04001     /*!
04002         output to standard streams
04003     */
04004     friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
04005     {
04006         return OutputToStream<std::ostream, std::string>(s, l);
04007     }
04008 
04009 
04010 #ifndef TTMATH_DONT_USE_WCHAR
04011 
04012     /*!
04013         output to standard streams
04014     */
04015     friend std::wostream & operator<<(std::wostream & s, const UInt<value_size> & l)
04016     {
04017         return OutputToStream<std::wostream, std::wstring>(s, l);
04018     }
04019 
04020 #endif
04021 
04022 
04023 
04024 private:
04025 
04026     /*!
04027         an auxiliary method for reading from standard streams
04028     */
04029     template<class istream_type, class string_type, class char_type>
04030     static istream_type & InputFromStream(istream_type & s, UInt<value_size> & l)
04031     {
04032     string_type ss;
04033     
04034     // char or wchar_t for operator>>
04035     char_type z;
04036     
04037         // operator>> omits white characters if they're set for ommiting
04038         s >> z;
04039 
04040         // we're reading only digits (base=10)
04041         while( s.good() && Misc::CharToDigit (z, 10)>=0 )
04042         {
04043             ss += z;
04044             z = static_cast<char_type>(s.get());
04045         }
04046 
04047         // we're leaving the last read character
04048         // (it's not belonging to the value)
04049         s.unget();
04050 
04051         l.FromString (ss);
04052 
04053     return s;
04054     }
04055 
04056 public:
04057 
04058 
04059     /*!
04060         input from standard streams
04061     */
04062     friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
04063     {
04064         return InputFromStream<std::istream, std::string, char>(s, l);
04065     }
04066 
04067 
04068 #ifndef TTMATH_DONT_USE_WCHAR
04069 
04070     /*!
04071         input from standard streams
04072     */
04073     friend std::wistream & operator>>(std::wistream & s, UInt<value_size> & l)
04074     {
04075         return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
04076     }
04077 
04078 #endif
04079 
04080 
04081     /*
04082         Following methods are defined in:
04083             ttmathuint_x86.h
04084             ttmathuint_x86_64.h
04085             ttmathuint_noasm.h
04086     */
04087 
04088 #ifdef TTMATH_NOASM
04089     static uint  AddTwoWords (uint  a, uint  b, uint  carry, uint  * result);
04090     static uint  SubTwoWords (uint  a, uint  b, uint  carry, uint  * result);
04091 
04092 #ifdef TTMATH_PLATFORM64
04093 
04094     union uint_
04095     {
04096         struct 
04097         {
04098             unsigned int low;  // 32 bit 
04099             unsigned int high; // 32 bit
04100         } u_;
04101 
04102         uint  u;                // 64 bit
04103     };
04104 
04105 
04106     static void DivTwoWords2 (uint  a,uint  b, uint  c, uint  * r, uint  * rest);
04107     static uint  DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_);
04108     static uint  DivTwoWordsUnnormalize(uint  u, uint  d);
04109     static unsigned int DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_);
04110     static void MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_);
04111 
04112 #endif // TTMATH_PLATFORM64
04113 #endif // TTMATH_NOASM
04114 
04115 
04116 private:
04117     uint  Rcl2_one(uint  c);
04118     uint  Rcr2_one(uint  c);
04119     uint  Rcl2(uint  bits, uint  c);
04120     uint  Rcr2(uint  bits, uint  c);
04121 
04122 public:
04123     static const char * LibTypeStr ();
04124     static LibTypeCode  LibType ();
04125     uint  Add (const UInt<value_size> & ss2, uint  c=0);
04126     uint  AddInt (uint  value, uint  index = 0);
04127     uint  AddTwoInts (uint  x2, uint  x1, uint  index);
04128     static uint  AddVector (const uint  * ss1, const uint  * ss2, uint  ss1_size, uint  ss2_size, uint  * result);
04129     uint  Sub (const UInt<value_size> & ss2, uint  c=0);
04130     uint  SubInt (uint  value, uint  index = 0);
04131     static uint  SubVector (const uint  * ss1, const uint  * ss2, uint  ss1_size, uint  ss2_size, uint  * result);
04132     static sint FindLeadingBitInWord (uint  x);
04133     static sint FindLowestBitInWord (uint  x);
04134     static uint  SetBitInWord (uint  & value, uint  bit);
04135     static void MulTwoWords (uint  a, uint  b, uint  * result_high, uint  * result_low);
04136     static void DivTwoWords (uint  a,uint  b, uint  c, uint  * r, uint  * rest);
04137 
04138 };
04139 
04140 
04141 
04142 /*!
04143     this specialization is needed in order to not confused the compiler "error: ISO C++ forbids zero-size array"
04144     when compiling Mul3Big2() method
04145 */
04146 template<>
04147 class UInt<0>
04148 {
04149 public:
04150     uint  table[1];
04151 
04152     void Mul2Big (const UInt<0>  &, UInt<0>  &) { TTMATH_ASSERT(false) };
04153     void SetZero () { TTMATH_ASSERT(false) };
04154     uint  AddTwoInts (uint , uint , uint ) { TTMATH_ASSERT(false) return 0; };
04155 };
04156 
04157 
04158 } //namespace
04159 
04160 
04161 #include "ttmathuint_x86.h"
04162 #include "ttmathuint_x86_64.h"
04163 #include "ttmathuint_noasm.h"
04164 
04165 #endif
04166