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 ttmathint.h Source File

ttmathint.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 headerfilettmathint
00041 #define headerfilettmathint
00042 
00043 /*!
00044     \file ttmathint.h
00045     \brief template class Int<uint>
00046 */
00047 
00048 #include "ttmathuint.h"
00049 
00050 namespace ttmath
00051 {
00052 
00053 
00054 /*!
00055     \brief Int implements a big integer value with a sign
00056 
00057     value_size - how many bytes specify our value
00058         on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
00059         on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
00060     value_size = 1,2,3,4,5,6....
00061 */
00062 template<uint value_size>
00063 class Int : public UInt<value_size>
00064 {
00065 public:
00066 
00067     /*!
00068         this method sets the max value which this class can hold
00069         (all bits will be one besides the last one)
00070     */
00071     void SetMax ()
00072     {
00073         UInt<value_size>::SetMax ();
00074         UInt<value_size>::table[value_size-1] = ~ TTMATH_UINT_HIGHEST_BIT;
00075     }
00076 
00077 
00078     /*!
00079         this method sets the min value which this class can hold
00080         (all bits will be zero besides the last one which is one)
00081     */
00082     void SetMin ()
00083     {
00084         UInt<value_size>::SetZero ();
00085         UInt<value_size>::table[value_size-1] = TTMATH_UINT_HIGHEST_BIT;
00086     }
00087 
00088 
00089     /*!
00090         this method sets -1 as the value
00091         (-1 is equal the max value in an unsigned type)
00092     */
00093     void SetSignOne ()
00094     {
00095         UInt<value_size>::SetMax ();
00096     }
00097 
00098 
00099     /*!
00100         we change the sign of the value
00101 
00102         if it isn't possible to change the sign this method returns 1
00103         else return 0 and changing the sign
00104     */
00105     uint  ChangeSign ()
00106     {
00107         /*
00108             if the value is equal that one which has been returned from SetMin
00109             (only the highest bit is set) that means we can't change sign
00110             because the value is too big (bigger about one)
00111 
00112             e.g. when value_size = 1 and value is -2147483648 we can't change it to the
00113             2147483648 because the max value which can be held is 2147483647
00114 
00115             we don't change the value and we're using this fact somewhere in some methods
00116             (if we look on our value without the sign we get the correct value 
00117             eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
00118         */
00119         if( UInt<value_size>::IsOnlyTheHighestBitSet() )
00120             return 1;
00121 
00122         UInt<value_size> temp(*this);
00123         UInt<value_size>::SetZero ();
00124         UInt<value_size>::Sub (temp);
00125 
00126     return 0;
00127     }
00128 
00129 
00130 
00131     /*!    
00132         this method sets the sign
00133 
00134         e.g. 1  -> -1
00135              -2 -> -2
00136         
00137         from a positive value we make a negative value,
00138         if the value is negative we do nothing
00139     */
00140     void SetSign ()
00141     {
00142         if( IsSign () )
00143             return;
00144 
00145         ChangeSign ();
00146     }
00147 
00148 
00149 
00150     /*!
00151         this method returns true if there's the sign
00152 
00153         (the highest bit will be converted to the bool)
00154     */
00155     bool IsSign () const
00156     {
00157         return UInt<value_size>::IsTheHighestBitSet ();
00158     }
00159 
00160 
00161 
00162     /*!
00163         it sets an absolute value
00164 
00165         it can return carry (1) (look on ChangeSign() for details)
00166     */
00167     uint  Abs ()
00168     {
00169         if( !IsSign () )
00170             return 0;
00171 
00172     return ChangeSign ();
00173     }
00174 
00175 
00176 
00177 
00178     /*!
00179     *
00180     *    basic mathematic functions
00181     *
00182     */
00183 
00184 private:
00185 
00186     uint  CorrectCarryAfterAdding(bool p1_is_sign, bool p2_is_sign)
00187     {
00188         if( !p1_is_sign && !p2_is_sign )
00189         {
00190             if( UInt<value_size>::IsTheHighestBitSet() )
00191                 return 1;
00192         }
00193 
00194         if( p1_is_sign && p2_is_sign )
00195         {    
00196             if( ! UInt<value_size>::IsTheHighestBitSet() )
00197                 return 1;
00198         }
00199 
00200     return 0;
00201     }
00202 
00203 
00204 public:
00205 
00206     /*!
00207         this method adds two value with a sign and returns a carry
00208 
00209         we're using methods from the base class because values are stored with U2
00210         we must only make the carry correction
00211 
00212         this = p1(=this) + p2
00213 
00214         when p1>=0 i p2>=0 carry is set when the highest bit of value is set
00215         when p1<0  i p2<0  carry is set when the highest bit of value is clear
00216         when p1>=0 i p2<0  carry will never be set
00217         when p1<0  i p2>=0 carry will never be set
00218     */
00219     uint  Add (const Int<value_size> & ss2)
00220     {
00221         bool p1_is_sign = IsSign ();
00222         bool p2_is_sign = ss2.IsSign ();
00223 
00224         UInt<value_size>::Add (ss2);        
00225 
00226     return CorrectCarryAfterAdding(p1_is_sign, p2_is_sign);
00227     }
00228 
00229 
00230     /*!
00231         this method adds one *unsigned* word (at a specific position)
00232         and returns a carry (if it was)
00233 
00234         look at a description in UInt<>::AddInt(...)
00235     */
00236     uint  AddInt (uint  value, uint  index = 0)
00237     {
00238         bool p1_is_sign = IsSign ();
00239 
00240         UInt<value_size>::AddInt (value, index);        
00241 
00242     return CorrectCarryAfterAdding(p1_is_sign, false);
00243     }
00244 
00245 
00246     /*!
00247         this method adds two *unsigned* words to the existing value
00248         and these words begin on the 'index' position
00249 
00250         index should be equal or smaller than value_size-2 (index <= value_size-2)
00251         x1 - lower word, x2 - higher word
00252 
00253         look at a description in UInt<>::AddTwoInts(...)
00254     */
00255     uint  AddTwoInts (uint  x2, uint  x1, uint  index)
00256     {
00257         bool p1_is_sign = IsSign ();
00258 
00259         UInt<value_size>::AddTwoInts (x2, x1, index);        
00260 
00261     return CorrectCarryAfterAdding(p1_is_sign, false);
00262     }
00263 
00264 private:
00265 
00266     uint  CorrectCarryAfterSubtracting(bool p1_is_sign, bool p2_is_sign)
00267     {
00268         if( !p1_is_sign && p2_is_sign )
00269         {
00270             if( UInt<value_size>::IsTheHighestBitSet() )
00271                 return 1;
00272         }
00273 
00274         if( p1_is_sign && !p2_is_sign )
00275         {    
00276             if( ! UInt<value_size>::IsTheHighestBitSet() )
00277                 return 1;
00278         }
00279 
00280     return 0;
00281     }
00282 
00283 public:
00284 
00285     /*!    
00286         this method subtracts two values with a sign
00287 
00288         we don't use the previous Add because the method ChangeSign can
00289         sometimes return carry 
00290 
00291         this = p1(=this) - p2
00292 
00293         when p1>=0 i p2>=0 carry will never be set
00294         when p1<0  i p2<0  carry will never be set
00295         when p1>=0 i p2<0  carry is set when the highest bit of value is set
00296         when p1<0  i p2>=0 carry is set when the highest bit of value is clear
00297     */
00298     uint  Sub (const Int<value_size> & ss2)
00299     {
00300         bool p1_is_sign = IsSign ();
00301         bool p2_is_sign = ss2.IsSign ();
00302 
00303         UInt<value_size>::Sub (ss2);        
00304 
00305     return CorrectCarryAfterSubtracting(p1_is_sign, p2_is_sign);
00306     }
00307 
00308 
00309     /*!
00310         this method subtracts one *unsigned* word (at a specific position)
00311         and returns a carry (if it was)
00312     */
00313     uint  SubInt (uint  value, uint  index = 0)
00314     {
00315         bool p1_is_sign = IsSign ();
00316 
00317         UInt<value_size>::SubInt (value, index);        
00318 
00319     return CorrectCarryAfterSubtracting(p1_is_sign, false);
00320     }
00321 
00322 
00323     /*!
00324         this method adds one to the value and returns carry
00325     */
00326     uint  AddOne ()
00327     {
00328         bool p1_is_sign = IsSign ();
00329 
00330         UInt<value_size>::AddOne ();        
00331 
00332     return CorrectCarryAfterAdding(p1_is_sign, false);
00333     }
00334 
00335 
00336     /*!
00337         this method subtracts one from the value and returns carry
00338     */
00339     uint  SubOne ()
00340     {
00341         bool p1_is_sign = IsSign ();
00342 
00343         UInt<value_size>::SubOne ();        
00344 
00345     return CorrectCarryAfterSubtracting(p1_is_sign, false);
00346     }
00347 
00348 
00349 private:
00350 
00351 
00352     uint  CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign)
00353     {
00354         /*
00355             we have to examine the sign of the result now
00356             but if the result is with the sign then:
00357                 1. if the signs were the same that means the result is too big
00358                 (the result must be without a sign)
00359                 2. if the signs were different that means if the result
00360                 is different from that one which has been returned from SetMin()
00361                 that is carry (result too big) but if the result is equal SetMin()
00362                 there'll be ok (and the next SetSign will has no effect because
00363                 the value is actually negative -- look at description of that case
00364                 in ChangeSign())
00365         */
00366         if( IsSign () )
00367         {
00368             if( ss1_is_sign != ss2_is_sign )
00369             {
00370                 /*
00371                     there can be one case where signs are different and
00372                     the result will be equal the value from SetMin() (only the highest bit is set)
00373                     (this situation is ok)
00374                 */
00375                 if( !UInt<value_size>::IsOnlyTheHighestBitSet() )
00376                     return 1;
00377             }
00378             else
00379             {
00380                 // signs were the same
00381                 return 1;
00382             }
00383         }
00384 
00385     return 0;
00386     }
00387 
00388 
00389 public:
00390 
00391 
00392     /*!
00393         multiplication: this = this * ss2
00394 
00395         it can return a carry
00396     */
00397     uint  MulInt (sint ss2)
00398     {
00399     bool ss1_is_sign, ss2_is_sign;
00400     uint  c;
00401 
00402         ss1_is_sign = IsSign ();
00403 
00404         /*
00405             we don't have to check the carry from Abs (values will be correct
00406             because next we're using the method MulInt from the base class UInt
00407             which is without a sign)
00408         */
00409         Abs ();
00410 
00411         if( ss2 < 0 )
00412         {
00413             ss2 = -ss2;
00414             ss2_is_sign = true;
00415         }
00416         else
00417         {
00418             ss2_is_sign = false;
00419         }
00420 
00421         c  = UInt<value_size>::MulInt ((uint )ss2);
00422         c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
00423 
00424         if( ss1_is_sign != ss2_is_sign )
00425             SetSign ();
00426 
00427     return c;
00428     }
00429 
00430 
00431 
00432     /*!
00433         multiplication this = this * ss2
00434 
00435         it returns carry if the result is too big
00436         (we're using the method from the base class but we have to make
00437         one correction in account of signs)
00438     */
00439     uint  Mul (Int<value_size> ss2)
00440     {
00441     bool ss1_is_sign, ss2_is_sign;
00442     uint  c;
00443 
00444         ss1_is_sign = IsSign ();
00445         ss2_is_sign = ss2.IsSign ();
00446 
00447         /*
00448             we don't have to check the carry from Abs (values will be correct
00449             because next we're using the method Mul from the base class UInt
00450             which is without a sign)
00451         */
00452         Abs ();
00453         ss2.Abs ();
00454 
00455         c  = UInt<value_size>::Mul (ss2);
00456         c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
00457 
00458         if( ss1_is_sign != ss2_is_sign )
00459             SetSign ();
00460 
00461     return c;
00462     }
00463 
00464 
00465     /*!
00466         division this = this / ss2
00467         returned values:
00468             0 - ok
00469             1 - division by zero
00470 
00471         for example: (result means 'this')
00472              20 /  3 --> result:  6   remainder:  2
00473             -20 /  3 --> result: -6   remainder: -2
00474              20 / -3 --> result: -6   remainder:  2
00475             -20 / -3 --> result:  6   remainder: -2
00476 
00477         in other words: this(old) = ss2 * this(new)(result) + remainder
00478     */
00479     uint  Div (Int<value_size> ss2, Int<value_size> * remainder = 0)
00480     {
00481     bool ss1_is_sign, ss2_is_sign;
00482 
00483         ss1_is_sign = IsSign ();
00484         ss2_is_sign = ss2.IsSign ();
00485 
00486         /*
00487             we don't have to test the carry from Abs as well as in Mul
00488         */
00489         Abs ();
00490         ss2.Abs ();
00491 
00492         uint  c = UInt<value_size>::Div (ss2, remainder);
00493 
00494         if( ss1_is_sign != ss2_is_sign )
00495             SetSign ();
00496 
00497         if( ss1_is_sign && remainder )
00498             remainder->SetSign();
00499 
00500     return c;
00501     }
00502     
00503     uint  Div (const Int<value_size> & ss2, Int<value_size> & remainder)
00504     {
00505         return Div (ss2, &remainder);
00506     }
00507 
00508 
00509     /*!
00510         division this = this / ss2  (ss2 is int)
00511         returned values:
00512             0 - ok
00513             1 - division by zero
00514 
00515         for example: (result means 'this')
00516              20 /  3 --> result:  6   remainder:  2
00517             -20 /  3 --> result: -6   remainder: -2
00518              20 / -3 --> result: -6   remainder:  2
00519             -20 / -3 --> result:  6   remainder: -2
00520 
00521         in other words: this(old) = ss2 * this(new)(result) + remainder
00522     */
00523     uint  DivInt (sint ss2, sint * remainder = 0)
00524     {
00525     bool ss1_is_sign, ss2_is_sign;
00526 
00527         ss1_is_sign = IsSign ();
00528 
00529         /*
00530             we don't have to test the carry from Abs as well as in Mul
00531         */
00532         Abs ();
00533 
00534         if( ss2 < 0 )
00535         {
00536             ss2 = -ss2;
00537             ss2_is_sign = true;
00538         }
00539         else
00540         {
00541             ss2_is_sign = false;
00542         }
00543 
00544         uint  rem;
00545         uint  c = UInt<value_size>::DivInt ((uint )ss2, &rem);
00546 
00547         if( ss1_is_sign != ss2_is_sign )
00548             SetSign ();
00549 
00550         if( remainder )
00551         {
00552             if( ss1_is_sign )
00553                 *remainder = -sint(rem);
00554             else
00555                 *remainder = sint(rem);
00556         }
00557 
00558     return c;
00559     }
00560 
00561 
00562     uint  DivInt (sint ss2, sint & remainder)
00563     {
00564         return DivInt (ss2, &remainder);
00565     }
00566 
00567 
00568 private:
00569 
00570 
00571     /*!
00572         power this = this ^ pow
00573         this can be negative
00574         pow is >= 0
00575     */
00576     uint  Pow2(const Int<value_size> & pow)
00577     {
00578         bool was_sign = IsSign ();
00579         uint  c = 0;
00580 
00581         if( was_sign )
00582             c += Abs ();
00583 
00584         uint  c_temp = UInt<value_size>::Pow (pow);
00585         if( c_temp > 0 )
00586             return c_temp; // c_temp can be: 0, 1 or 2
00587         
00588         if( was_sign && (pow.table[0] & 1) == 1 )
00589             // negative value to the power of odd number is negative
00590             c += ChangeSign ();
00591 
00592     return (c==0)? 0 : 1;
00593     }
00594 
00595 
00596 public:
00597 
00598 
00599     /*!
00600         power this = this ^ pow
00601 
00602         return values:
00603         0 - ok
00604         1 - carry
00605         2 - incorrect arguments 0^0 or 0^(-something)
00606     */
00607     uint  Pow (Int<value_size> pow)
00608     {
00609         if( !pow.IsSign () )
00610             return Pow2(pow);
00611 
00612         if( UInt<value_size>::IsZero() )
00613             // if 'pow' is negative then
00614             // 'this' must be different from zero
00615             return 2;
00616 
00617         if( pow.ChangeSign () )
00618             return 1;
00619 
00620         Int<value_size> t(*this);
00621         uint  c_temp = t.Pow2(pow);
00622         if( c_temp > 0 )
00623             return c_temp;
00624 
00625         UInt<value_size>::SetOne ();
00626         if( Div (t) )
00627             return 1;
00628 
00629     return 0;
00630     }
00631 
00632 
00633 
00634     /*!
00635     *
00636     *    convertion methods
00637     *
00638     */
00639 private:
00640 
00641 
00642     /*!
00643         an auxiliary method for converting both from UInt and Int
00644     */
00645     template<uint argument_size>
00646     uint  FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
00647     {
00648         uint  min_size = (value_size < argument_size)? value_size : argument_size;
00649         uint  i;
00650 
00651         for(i=0 ; i<min_size ; ++i)
00652             UInt<value_size>::table[i] = p.table [i];
00653 
00654 
00655         if( value_size > argument_size )
00656         {    
00657             uint  fill;
00658 
00659             if( UInt_type )
00660                 fill = 0;
00661             else
00662                 fill = (p.table [argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
00663                                                         TTMATH_UINT_MAX_VALUE : 0;
00664 
00665             // 'this' is longer than 'p'
00666             for( ; i<value_size ; ++i)
00667                 UInt<value_size>::table[i] = fill;
00668         }
00669         else
00670         {
00671             uint  test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
00672                                                                 TTMATH_UINT_MAX_VALUE : 0;
00673 
00674             if( UInt_type && test!=0 )
00675                 return 1;
00676 
00677             for( ; i<argument_size ; ++i)
00678                 if( p.table [i] != test )
00679                     return 1;
00680         }
00681 
00682     return 0;
00683     }
00684 
00685 public:
00686 
00687     /*!
00688         this method converts an Int<another_size> type into this class
00689 
00690         this operation has mainly sense if the value from p
00691         can be held in this type
00692 
00693         it returns a carry if the value 'p' is too big
00694     */
00695     template<uint argument_size>
00696     uint  FromInt (const Int<argument_size> & p)
00697     {
00698         return FromUIntOrInt(p, false);
00699     }
00700 
00701 
00702     /*!
00703         this method converts the sint type into this class
00704     */
00705     uint  FromInt (sint value)
00706     {
00707     uint  fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
00708 
00709         for(uint  i=1 ; i<value_size ; ++i)
00710             UInt<value_size>::table[i] = fill;
00711 
00712         UInt<value_size>::table[0] = uint (value);
00713     
00714         // there'll never be a carry here
00715     return 0;
00716     }
00717 
00718 
00719     /*!
00720         this method converts UInt<another_size> into this class
00721     */
00722     template<uint argument_size>
00723     uint  FromUInt (const UInt<argument_size> & p)
00724     {
00725         return FromUIntOrInt(p, true);
00726     }
00727 
00728 
00729     /*!
00730         this method converts UInt<another_size> into this class
00731     */
00732     template<uint argument_size>
00733     uint  FromInt (const UInt<argument_size> & p)
00734     {
00735         return FromUIntOrInt(p, true);
00736     }
00737 
00738 
00739     /*!
00740         this method converts the uint type into this class
00741     */
00742     uint  FromUInt (uint  value)
00743     {
00744         for(uint  i=1 ; i<value_size ; ++i)
00745             UInt<value_size>::table[i] = 0;
00746 
00747         UInt<value_size>::table[0] = value;
00748 
00749         // there can be a carry here when the size of this value is equal one word
00750         // and the 'value' has the highest bit set
00751         if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
00752             return 1;
00753 
00754     return 0;
00755     }
00756 
00757 
00758     /*!
00759         this method converts the uint type into this class
00760     */
00761     uint  FromInt (uint  value)
00762     {
00763         return FromUInt (value);
00764     }
00765 
00766 
00767     /*!
00768         the default assignment operator
00769     */
00770     Int<value_size> & operator= (const Int<value_size> & p)
00771     {
00772         FromInt (p);
00773 
00774     return *this;
00775     }
00776 
00777 
00778     /*!
00779         this operator converts an Int<another_size> type to this class
00780 
00781         it doesn't return a carry
00782     */
00783     template<uint argument_size>
00784     Int<value_size> & operator= (const Int<argument_size> & p)
00785     {
00786         FromInt (p);
00787 
00788     return *this;
00789     }
00790 
00791 
00792     /*!
00793         this method converts the sint type to this class
00794     */
00795     Int<value_size> & operator= (sint i)
00796     {
00797         FromInt (i);
00798 
00799     return *this;
00800     }
00801 
00802 
00803     /*!
00804         a constructor for converting the uint to this class
00805     */
00806     Int (sint i)
00807     {
00808         FromInt (i);
00809     }
00810 
00811 
00812     /*!
00813         a copy constructor
00814     */
00815     Int (const Int<value_size> & u)
00816     {
00817         FromInt (u);
00818     }
00819 
00820 
00821     /*!
00822         a constructor for copying from another types
00823     */
00824     template<uint argument_size>
00825     Int (const Int<argument_size> & u)
00826     {
00827         // look that 'size' we still set as 'value_size' and not as u.value_size
00828         FromInt (u);
00829     }
00830 
00831 
00832 
00833     /*!
00834         this operator converts an UInt<another_size> type to this class
00835 
00836         it doesn't return a carry
00837     */
00838     template<uint argument_size>
00839     Int<value_size> & operator= (const UInt<argument_size> & p)
00840     {
00841         FromUInt (p);
00842 
00843     return *this;
00844     }
00845 
00846 
00847     /*!
00848         this method converts the Uint type to this class
00849     */
00850     Int<value_size> & operator= (uint  i)
00851     {
00852         FromUInt (i);
00853 
00854     return *this;
00855     }
00856 
00857 
00858     /*!
00859         a constructor for converting the uint to this class
00860     */
00861     Int (uint  i)
00862     {
00863         FromUInt (i);
00864     }
00865 
00866 
00867     /*!
00868         a constructor for copying from another types
00869     */
00870     template<uint argument_size>
00871     Int (const UInt<argument_size> & u)
00872     {
00873         // look that 'size' we still set as 'value_size' and not as u.value_size
00874         FromUInt (u);
00875     }
00876  
00877 
00878 
00879 #ifdef TTMATH_PLATFORM32
00880 
00881 
00882     /*!
00883         this method converts unsigned 64 bit int type to this class
00884         ***this method is created only on a 32bit platform***
00885     */
00886     uint  FromUInt (ulint  n)
00887     {
00888         uint  c = UInt<value_size>::FromUInt (n);
00889 
00890         if( c )
00891             return 1;
00892 
00893         if( value_size == 1 )
00894             return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
00895         
00896         if( value_size == 2 )
00897             return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
00898 
00899     return 0;
00900     }
00901 
00902 
00903     /*!
00904         this method converts unsigned 64 bit int type to this class
00905         ***this method is created only on a 32bit platform***
00906     */
00907     uint  FromInt (ulint  n)
00908     {
00909         return FromUInt (n);
00910     }
00911 
00912         
00913     /*!
00914         this method converts signed 64 bit int type to this class
00915         ***this method is created only on a 32bit platform***
00916     */
00917     uint  FromInt (slint n)
00918     {
00919     uint  mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0;
00920 
00921         UInt<value_size>::table[0] = (uint )(ulint )n;
00922 
00923         if( value_size == 1 )
00924         {
00925             if( uint (ulint (n) >> 32) != mask )
00926                 return 1;
00927 
00928             return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
00929         }
00930 
00931         UInt<value_size>::table[1] = (uint )(ulint (n) >> 32);
00932 
00933         for(uint  i=2 ; i<value_size ; ++i)
00934             UInt<value_size>::table[i] = mask;
00935 
00936     return 0;
00937     }
00938 
00939 
00940     /*!
00941         this operator converts unsigned 64 bit int type to this class
00942         ***this operator is created only on a 32bit platform***
00943     */
00944     Int<value_size> & operator= (ulint  n)
00945     {
00946         FromUInt (n);
00947 
00948     return *this;
00949     }
00950 
00951 
00952     /*!
00953         a constructor for converting unsigned 64 bit int to this class
00954         ***this constructor is created only on a 32bit platform***
00955     */
00956     Int (ulint  n)
00957     {
00958         FromUInt (n);
00959     }
00960 
00961 
00962     /*!
00963         this operator converts signed 64 bit int type to this class
00964         ***this operator is created only on a 32bit platform***
00965     */
00966     Int<value_size> & operator= (slint n)
00967     {
00968         FromInt (n);
00969 
00970     return *this;
00971     }
00972 
00973 
00974     /*!
00975         a constructor for converting signed 64 bit int to this class
00976         ***this constructor is created only on a 32bit platform***
00977     */
00978     Int (slint n)
00979     {
00980         FromInt (n);
00981     }
00982 
00983 #endif
00984 
00985 
00986 
00987 
00988 #ifdef TTMATH_PLATFORM64
00989 
00990     /*!
00991         this method converts 32 bit unsigned int type to this class
00992         ***this operator is created only on a 64bit platform***
00993     */
00994     uint  FromUInt (unsigned int i)
00995     {
00996         return FromUInt (uint (i));
00997     }
00998 
00999 
01000     /*!
01001         this method converts 32 bit unsigned int type to this class
01002         ***this operator is created only on a 64bit platform***
01003     */
01004     uint  FromInt (unsigned int i)
01005     {
01006         return FromUInt (i);
01007     }
01008 
01009 
01010     /*!
01011         this method converts 32 bit signed int type to this class
01012         ***this operator is created only on a 64bit platform***
01013     */
01014     uint  FromInt (signed int i)
01015     {
01016         return FromInt (sint(i));
01017     }
01018 
01019 
01020     /*!
01021         this method converts 32 bit unsigned int type to this class
01022         ***this operator is created only on a 64bit platform***
01023     */
01024     Int<value_size> & operator= (unsigned int i)
01025     {
01026         FromUInt (i);
01027 
01028     return *this;
01029     }
01030 
01031 
01032     /*!
01033         a constructor for converting 32 bit unsigned int to this class
01034         ***this constructor is created only on a 64bit platform***
01035     */
01036     Int (unsigned int i)
01037     {
01038         FromUInt (i);
01039     }
01040 
01041 
01042     /*!
01043         this operator converts 32 bit signed int type to this class
01044         ***this operator is created only on a 64bit platform***
01045     */
01046     Int<value_size> & operator= (signed int i)
01047     {
01048         FromInt (i);
01049 
01050     return *this;
01051     }
01052 
01053 
01054     /*!
01055         a constructor for converting 32 bit signed int to this class
01056         ***this constructor is created only on a 64bit platform***
01057     */
01058     Int (signed int i)
01059     {
01060         FromInt (i);
01061     }
01062 
01063 #endif
01064 
01065 
01066 
01067     /*!
01068         a constructor for converting string to this class (with the base=10)
01069     */
01070     Int (const char * s)
01071     {
01072         FromString (s);
01073     }
01074 
01075 
01076     /*!
01077         a constructor for converting a string to this class (with the base=10)
01078     */
01079     Int (const std::string & s)
01080     {
01081         FromString ( s.c_str() );
01082     }
01083 
01084 
01085 #ifndef TTMATH_DONT_USE_WCHAR
01086 
01087     /*!
01088         a constructor for converting string to this class (with the base=10)
01089     */
01090     Int (const wchar_t * s)
01091     {
01092         FromString (s);
01093     }
01094 
01095 
01096     /*!
01097         a constructor for converting a string to this class (with the base=10)
01098     */
01099     Int (const std::wstring & s)
01100     {
01101         FromString ( s.c_str() );
01102     }
01103 
01104 #endif
01105 
01106 
01107     /*!
01108         a default constructor
01109 
01110         we don't clear table etc.
01111     */
01112     Int ()
01113     {
01114     }
01115 
01116 
01117     /*!
01118         the destructor
01119     */
01120     ~Int ()
01121     {
01122     }
01123 
01124 
01125     /*!
01126         this method returns the lowest value from table with a sign
01127 
01128         we must be sure when we using this method whether the value
01129         will hold in an sint type or not (the rest value from table must be zero or -1)
01130     */
01131     sint ToInt () const
01132     {
01133         return sint( UInt<value_size>::table[0] );
01134     }
01135 
01136 
01137     /*!
01138         this method converts the value to uint type
01139         can return a carry if the value is too long to store it in uint type
01140     */
01141     uint  ToUInt (uint  & result) const
01142     {
01143         uint  c = UInt<value_size>::ToUInt (result);
01144 
01145         if( value_size == 1 )
01146             return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
01147 
01148     return c;
01149     }
01150 
01151 
01152     /*!
01153         this method converts the value to uint type
01154         can return a carry if the value is too long to store it in uint type
01155     */
01156     uint  ToInt (uint  & result) const
01157     {
01158         return ToUInt (result);
01159     }
01160 
01161 
01162     /*!
01163         this method converts the value to sint type
01164         can return a carry if the value is too long to store it in sint type
01165     */
01166     uint  ToInt (sint & result) const
01167     {
01168         result = sint( UInt<value_size>::table[0] );
01169         uint  mask = IsSign () ? TTMATH_UINT_MAX_VALUE : 0;
01170 
01171         if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
01172             return 1;
01173 
01174         for(uint  i=1 ; i<value_size ; ++i)
01175             if( UInt<value_size>::table[i] != mask )
01176                 return 1;
01177 
01178     return 0;
01179     }
01180 
01181 
01182 #ifdef TTMATH_PLATFORM32
01183 
01184     /*!
01185         this method converts the value to ulint type (64 bit unsigned integer)
01186         can return a carry if the value is too long to store it in ulint type
01187         *** this method is created only on a 32 bit platform ***
01188     */
01189     uint  ToUInt (ulint  & result) const
01190     {
01191         uint  c = UInt<value_size>::ToUInt (result);
01192 
01193         if( value_size == 1 )
01194             return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
01195 
01196         if( value_size == 2 )
01197             return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
01198 
01199     return c;
01200     }
01201 
01202 
01203     /*!
01204         this method converts the value to ulint type (64 bit unsigned integer)
01205         can return a carry if the value is too long to store it in ulint type
01206         *** this method is created only on a 32 bit platform ***
01207     */
01208     uint  ToInt (ulint  & result) const
01209     {
01210         return ToUInt (result);
01211     }
01212 
01213 
01214     /*!
01215         this method converts the value to slint type (64 bit signed integer)
01216         can return a carry if the value is too long to store it in slint type
01217         *** this method is created only on a 32 bit platform ***
01218     */
01219     uint  ToInt (slint & result) const
01220     {
01221         if( value_size == 1 )
01222         {
01223             result = slint(sint(UInt<value_size>::table[0]));
01224         }
01225         else
01226         {
01227             uint  low  = UInt<value_size>::table[0];
01228             uint  high = UInt<value_size>::table[1];
01229 
01230             result = low;
01231             result |= (ulint (high) << TTMATH_BITS_PER_UINT);
01232 
01233             uint  mask = IsSign () ? TTMATH_UINT_MAX_VALUE : 0;
01234 
01235             if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
01236                 return 1;
01237 
01238             for(uint  i=2 ; i<value_size ; ++i)
01239                 if( UInt<value_size>::table[i] != mask )
01240                     return 1;
01241         }
01242 
01243     return 0;
01244     }
01245 
01246 #endif
01247 
01248 
01249 
01250 #ifdef TTMATH_PLATFORM64
01251 
01252     /*!
01253         this method converts the value to a 32 bit unsigned integer
01254         can return a carry if the value is too long to store it in this type
01255         *** this method is created only on a 64 bit platform ***
01256     */
01257     uint  ToUInt (unsigned int & result) const
01258     {
01259         uint  c = UInt<value_size>::ToUInt (result);
01260 
01261         if( c || IsSign () )
01262             return 1;
01263 
01264     return 0;
01265     }
01266 
01267 
01268     /*!
01269         this method converts the value to a 32 bit unsigned integer
01270         can return a carry if the value is too long to store it in this type
01271         *** this method is created only on a 64 bit platform ***
01272     */
01273     uint  ToInt (unsigned int & result) const
01274     {
01275         return ToUInt (result);
01276     }
01277 
01278 
01279     /*!
01280         this method converts the value to a 32 bit signed integer
01281         can return a carry if the value is too long to store it in this type
01282         *** this method is created only on a 64 bit platform ***
01283     */
01284     uint  ToInt (int & result) const
01285     {
01286         uint  first = UInt<value_size>::table[0];
01287 
01288         result = int(first);
01289         uint  mask = IsSign () ? TTMATH_UINT_MAX_VALUE : 0;
01290     
01291         if( (first >> 31) != (mask >> 31) )
01292             return 1;
01293 
01294         for(uint  i=1 ; i<value_size ; ++i)
01295             if( UInt<value_size>::table[i] != mask )
01296                 return 1;
01297 
01298     return 0;
01299     }
01300 
01301 #endif
01302 
01303 
01304 
01305 
01306 private:
01307 
01308     /*!    
01309         an auxiliary method for converting to a string
01310     */
01311     template<class string_type>
01312     void ToStringBase(string_type & result, uint  b = 10) const
01313     {
01314         if( IsSign () )
01315         {
01316             Int<value_size> temp(*this);
01317             temp.Abs();
01318             temp.UInt<value_size>::ToStringBase(result, b, true);
01319         }
01320         else
01321         {
01322             UInt<value_size>::ToStringBase(result, b, false);
01323         }
01324     }
01325 
01326 public:
01327 
01328     /*!    
01329         this method converts the value to a string with a base equal 'b'
01330     */
01331     void ToString (std::string & result, uint  b = 10) const
01332     {
01333         return ToStringBase(result, b);
01334     }
01335 
01336 
01337     /*!    
01338         this method converts the value to a string with a base equal 'b'
01339     */
01340     std::string ToString (uint  b = 10) const
01341     {
01342         std::string result;
01343         ToStringBase(result, b);
01344 
01345     return result;
01346     }
01347 
01348 
01349 #ifndef TTMATH_DONT_USE_WCHAR
01350 
01351     /*!    
01352         this method converts the value to a string with a base equal 'b'
01353     */
01354     void ToString (std::wstring & result, uint  b = 10) const
01355     {
01356         return ToStringBase(result, b);
01357     }
01358 
01359 
01360     /*!    
01361         this method converts the value to a string with a base equal 'b'
01362     */
01363     std::wstring ToWString (uint  b = 10) const
01364     {
01365         std::wstring result;
01366         ToStringBase(result, b);
01367 
01368     return result;
01369     }
01370 
01371 #endif
01372 
01373 
01374 
01375 private:
01376 
01377     /*!
01378         an auxiliary method for converting from a string
01379     */
01380     template<class char_type>
01381     uint  FromStringBase(const char_type * s, uint  b = 10, const char_type ** after_source = 0, bool * value_read = 0)
01382     {
01383     bool is_sign = false;
01384     
01385         Misc::SkipWhiteCharacters(s);
01386 
01387         if( *s == '-' )
01388         {
01389             is_sign = true;
01390             Misc::SkipWhiteCharacters(++s);
01391         }
01392         else
01393         if( *s == '+' )
01394         {
01395             Misc::SkipWhiteCharacters(++s);
01396         }
01397 
01398         if( UInt<value_size>::FromString(s,b,after_source,value_read) )
01399             return 1;
01400 
01401         if( is_sign )
01402         {
01403         Int<value_size> mmin;
01404 
01405             mmin.SetMin();
01406 
01407             /*
01408                 the reference to mmin will be automatically converted to the reference
01409                 to UInt type
01410                 (this value can be equal mmin -- look at a description in ChangeSign())
01411             */
01412             if( UInt<value_size>::operator>( mmin ) )
01413                 return 1;
01414 
01415             /*
01416                 if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
01417             */
01418             ChangeSign ();
01419         }
01420         else
01421         {
01422         Int<value_size> mmax;
01423 
01424             mmax.SetMax();
01425 
01426             if( UInt<value_size>::operator>( mmax ) )
01427                     return 1;
01428         }
01429 
01430     return 0;
01431     }
01432 
01433 
01434 public:
01435 
01436     /*!
01437         this method converts a string into its value
01438         it returns carry=1 if the value will be too big or an incorrect base 'b' is given
01439 
01440         string is ended with a non-digit value, for example:
01441             "-12" will be translated to -12
01442             as well as:
01443             "- 12foo" will be translated to -12 too
01444 
01445         existing first white characters will be ommited
01446         (between '-' and a first digit can be white characters too)
01447 
01448         after_source (if exists) is pointing at the end of the parsed string
01449 
01450         value_read (if exists) tells whether something has actually been read (at least one digit)
01451     */
01452     uint  FromString (const char * s, uint  b = 10, const char ** after_source = 0, bool * value_read = 0)
01453     {
01454         return FromStringBase(s, b, after_source, value_read);
01455     }
01456 
01457 
01458     /*!
01459         this method converts a string into its value
01460     */
01461     uint  FromString (const wchar_t * s, uint  b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
01462     {
01463         return FromStringBase(s, b, after_source, value_read);
01464     }
01465 
01466 
01467     /*!
01468         this method converts a string into its value
01469         it returns carry=1 if the value will be too big or an incorrect base 'b' is given
01470     */
01471     uint  FromString (const std::string & s, uint  b = 10)
01472     {
01473         return FromString ( s.c_str(), b );
01474     }
01475 
01476 
01477     /*!
01478         this operator converts a string into its value (with base = 10)
01479     */
01480     Int<value_size> & operator= (const char * s)
01481     {
01482         FromString (s);
01483 
01484     return *this;
01485     }
01486 
01487 
01488 #ifndef TTMATH_DONT_USE_WCHAR
01489 
01490 
01491     /*!
01492         this method converts a string into its value
01493         it returns carry=1 if the value will be too big or an incorrect base 'b' is given
01494     */
01495     uint  FromString (const std::wstring & s, uint  b = 10)
01496     {
01497         return FromString ( s.c_str(), b );
01498     }
01499 
01500 
01501     /*!
01502         this operator converts a string into its value (with base = 10)
01503     */
01504     Int<value_size> & operator= (const wchar_t * s)
01505     {
01506         FromString (s);
01507 
01508     return *this;
01509     }
01510 
01511 
01512     /*!
01513         this operator converts a string into its value (with base = 10)
01514     */
01515     Int<value_size> & operator= (const std::wstring & s)
01516     {
01517         FromString ( s.c_str() );
01518 
01519     return *this;
01520     }
01521 
01522 #endif
01523 
01524 
01525     /*!
01526         this operator converts a string into its value (with base = 10)
01527     */
01528     Int<value_size> & operator= (const std::string & s)
01529     {
01530         FromString ( s.c_str() );
01531 
01532     return *this;
01533     }
01534 
01535 
01536 
01537     /*!
01538     *
01539     *    methods for comparing
01540     *
01541     *
01542     */
01543 
01544     bool operator== (const Int<value_size> & l) const
01545     {
01546         return UInt<value_size>::operator== (l);
01547     }
01548 
01549     bool operator!=(const Int<value_size> & l) const
01550     {
01551         return UInt<value_size>::operator!=(l);
01552     }
01553 
01554     bool operator<(const Int<value_size> & l) const
01555     {
01556         sint i=value_size-1;
01557 
01558         sint a1 = sint(UInt<value_size>::table[i]);
01559         sint a2 = sint(l.table[i]);
01560 
01561         if( a1 != a2 )
01562             return a1 < a2;
01563 
01564 
01565         for(--i ; i>=0 ; --i)
01566         {
01567             if( UInt<value_size>::table[i] != l.table[i] )
01568                 // comparison as unsigned int
01569                 return UInt<value_size>::table[i] < l.table[i];
01570         }
01571 
01572     // they're equal
01573     return false;
01574     }
01575 
01576 
01577     bool operator>(const Int<value_size> & l) const
01578     {
01579         sint i=value_size-1;
01580 
01581         sint a1 = sint(UInt<value_size>::table[i]);
01582         sint a2 = sint(l.table[i]);
01583 
01584         if( a1 != a2 )
01585             return a1 > a2;
01586 
01587 
01588         for(--i ; i>=0 ; --i)
01589         {
01590             if( UInt<value_size>::table[i] != l.table[i] )
01591                 // comparison as unsigned int
01592                 return UInt<value_size>::table[i] > l.table[i];
01593         }
01594 
01595     // they're equal
01596     return false;
01597     }
01598 
01599 
01600     bool operator<=(const Int<value_size> & l) const
01601     {
01602         sint i=value_size-1;
01603 
01604         sint a1 = sint(UInt<value_size>::table[i]);
01605         sint a2 = sint(l.table[i]);
01606 
01607         if( a1 != a2 )
01608             return a1 < a2;
01609 
01610 
01611         for(--i ; i>=0 ; --i)
01612         {
01613             if( UInt<value_size>::table[i] != l.table[i] )
01614                 // comparison as unsigned int
01615                 return UInt<value_size>::table[i] < l.table[i];
01616         }
01617 
01618     // they're equal
01619     return true;
01620     }
01621 
01622 
01623     bool operator>=(const Int<value_size> & l) const
01624     {
01625         sint i=value_size-1;
01626 
01627         sint a1 = sint(UInt<value_size>::table[i]);
01628         sint a2 = sint(l.table[i]);
01629 
01630         if( a1 != a2 )
01631             return a1 > a2;
01632 
01633 
01634         for(--i ; i>=0 ; --i)
01635         {
01636             if( UInt<value_size>::table[i] != l.table[i] )
01637                 // comparison as unsigned int
01638                 return UInt<value_size>::table[i] > l.table[i];
01639         }
01640 
01641     // they're equal
01642     return true;
01643     }
01644 
01645 
01646 
01647     /*!
01648     *
01649     *    standard mathematical operators 
01650     *
01651     */
01652 
01653 
01654     /*!
01655         an operator for changing the sign
01656 
01657         it's not changing 'this' but the changed value will be returned
01658     */
01659     Int<value_size> operator- () const
01660     {
01661     Int<value_size> temp(*this);
01662 
01663         temp.ChangeSign ();
01664         
01665     return temp;
01666     }
01667 
01668 
01669     Int<value_size> operator- (const Int<value_size> & p2) const
01670     {
01671     Int<value_size> temp(*this);
01672 
01673         temp.Sub(p2);
01674 
01675     return temp;
01676     }
01677 
01678 
01679     Int<value_size> & operator-=(const Int<value_size> & p2)
01680     {
01681         Sub (p2);
01682 
01683     return *this;
01684     }
01685 
01686 
01687     Int<value_size> operator+(const Int<value_size> & p2) const
01688     {
01689     Int<value_size> temp(*this);
01690 
01691         temp.Add(p2);
01692 
01693     return temp;
01694     }
01695 
01696 
01697     Int<value_size> & operator+=(const Int<value_size> & p2)
01698     {
01699         Add (p2);
01700 
01701     return *this;
01702     }
01703 
01704 
01705     Int<value_size> operator*(const Int<value_size> & p2) const
01706     {
01707     Int<value_size> temp(*this);
01708 
01709         temp.Mul(p2);
01710 
01711     return temp;
01712     }
01713 
01714 
01715     Int<value_size> & operator*=(const Int<value_size> & p2)
01716     {
01717         Mul (p2);
01718 
01719     return *this;
01720     }
01721 
01722 
01723     Int<value_size> operator/(const Int<value_size> & p2) const
01724     {
01725     Int<value_size> temp(*this);
01726 
01727         temp.Div(p2);
01728 
01729     return temp;
01730     }
01731 
01732 
01733     Int<value_size> & operator/=(const Int<value_size> & p2)
01734     {
01735         Div (p2);
01736 
01737     return *this;
01738     }
01739 
01740 
01741     Int<value_size> operator%(const Int<value_size> & p2) const
01742     {
01743     Int<value_size> temp(*this);
01744     Int<value_size> remainder;
01745     
01746         temp.Div(p2, remainder);
01747 
01748     return remainder;
01749     }
01750 
01751 
01752     Int<value_size> & operator%=(const Int<value_size> & p2)
01753     {
01754     Int<value_size> remainder;
01755     
01756         Div (p2, remainder);
01757         operator= (remainder);
01758 
01759     return *this;
01760     }
01761 
01762 
01763     /*!
01764         Prefix operator e.g. ++variable
01765     */
01766     UInt<value_size> & operator++ ()
01767     {
01768         AddOne ();
01769 
01770     return *this;
01771     }
01772 
01773 
01774     /*!
01775         Postfix operator e.g. variable++
01776     */
01777     UInt<value_size> operator++ (int)
01778     {
01779     UInt<value_size> temp( *this );
01780 
01781         AddOne ();
01782 
01783     return temp;
01784     }
01785 
01786 
01787     UInt<value_size> & operator--()
01788     {
01789         SubOne ();
01790 
01791     return *this;
01792     }
01793 
01794 
01795     UInt<value_size> operator--(int)
01796     {
01797     UInt<value_size> temp( *this );
01798 
01799         SubOne ();
01800 
01801     return temp;
01802     }
01803 
01804 
01805 
01806     /*!
01807     *
01808     *    input/output operators for standard streams
01809     *
01810     */
01811 
01812 private:
01813 
01814     /*!
01815         an auxiliary method for outputing to standard streams
01816     */
01817     template<class ostream_type, class string_type>
01818     static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l)
01819     {
01820     string_type ss;
01821 
01822         l.ToString(ss);
01823         s << ss;
01824 
01825     return s;
01826     }
01827 
01828 
01829 
01830 public:
01831 
01832 
01833     /*!
01834         output to standard streams
01835     */
01836     friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
01837     {
01838         return OutputToStream<std::ostream, std::string>(s, l);
01839     }
01840 
01841 
01842 #ifndef TTMATH_DONT_USE_WCHAR
01843 
01844     /*!
01845         output to standard streams
01846     */
01847     friend std::wostream & operator<<(std::wostream & s, const Int<value_size> & l)
01848     {
01849         return OutputToStream<std::wostream, std::wstring>(s, l);
01850     }
01851 
01852 #endif
01853 
01854 
01855 
01856 private:
01857 
01858     /*!
01859         an auxiliary method for converting from a string
01860     */
01861     template<class istream_type, class string_type, class char_type>
01862     static istream_type & InputFromStream(istream_type & s, Int<value_size> & l)
01863     {
01864     string_type ss;
01865     
01866     // char or wchar_t for operator>>
01867     char_type z;
01868     
01869         // operator>> omits white characters if they're set for ommiting
01870         s >> z;
01871 
01872         if( z=='-' || z=='+' )
01873         {
01874             ss += z;
01875             s >> z; // we're reading a next character (white characters can be ommited)
01876         }
01877 
01878         // we're reading only digits (base=10)
01879         while( s.good() && Misc::CharToDigit (z, 10)>=0 )
01880         {
01881             ss += z;
01882             z = static_cast<char_type>(s.get());
01883         }
01884 
01885         // we're leaving the last readed character
01886         // (it's not belonging to the value)
01887         s.unget();
01888 
01889         l.FromString (ss);
01890 
01891     return s;
01892     }
01893 
01894 
01895 public:
01896 
01897     /*!
01898         input from standard streams
01899     */
01900     friend std::istream & operator>> (std::istream & s, Int<value_size> & l)
01901     {
01902         return InputFromStream<std::istream, std::string, char>(s, l);
01903     }
01904 
01905 
01906 #ifndef TTMATH_DONT_USE_WCHAR
01907 
01908     /*!
01909         input from standard streams
01910     */
01911     friend std::wistream & operator>> (std::wistream & s, Int<value_size> & l)
01912     {
01913         return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
01914     }
01915 #endif
01916 
01917 
01918 };
01919 
01920 } // namespace
01921 
01922 #endif
01923