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

ttmathbig.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-2012, 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 #ifndef headerfilettmathbig
00039 #define headerfilettmathbig
00040 
00041 /*!
00042     \file ttmathbig.h
00043     \brief A Class for representing floating point numbers
00044 */
00045 
00046 #include "ttmathint.h"
00047 #include "ttmaththreads.h"
00048 
00049 #include <iostream>
00050 
00051 #ifdef TTMATH_MULTITHREADS
00052 #include <signal.h>
00053 #endif
00054 
00055 namespace ttmath
00056 {
00057 
00058 
00059 /*!
00060     \brief Big implements the floating point numbers
00061 */
00062 template <uint exp, uint man>
00063 class Big
00064 {
00065 
00066 /*
00067     value = mantissa * 2^exponent    
00068 
00069     exponent - an integer value with a sign
00070     mantissa - an integer value without a sing
00071 
00072     mantissa must be pushed into the left side that is the highest bit from 
00073     mantissa must be one (of course if there's another value than zero) -- this job
00074     (pushing bits into the left side) making Standardizing() method
00075 
00076     for example:
00077     if we want to store value one (1) into our Big object we must:
00078         set mantissa to 1
00079         set exponent to 0
00080         set info to 0
00081         and call method Standardizing()
00082 */
00083 
00084 
00085 public:
00086 
00087 Int<exp>   exponent;
00088 UInt<man>  mantissa;
00089 unsigned char info;
00090 
00091 
00092 /*!
00093     Sign
00094     the mask of a bit from 'info' which means that there is a sign
00095     (when the bit is set)
00096 */
00097 #define TTMATH_BIG_SIGN 128
00098 
00099 
00100 /*!
00101     Not a number
00102     if this bit is set that there is not a valid number
00103 */
00104 #define TTMATH_BIG_NAN  64
00105 
00106 
00107 /*!
00108     Zero
00109     if this bit is set that there is value zero
00110     mantissa should be zero and exponent should be zero too
00111     (the Standardizing() method does this)
00112 */
00113 #define TTMATH_BIG_ZERO  32
00114 
00115 
00116     /*!
00117         this method sets NaN if there was a carry (and returns 1 in such a case)
00118 
00119         c can be 0, 1 or other value different from zero
00120     */
00121     uint  CheckCarry (uint  c)
00122     {
00123         if( c != 0 )
00124         {
00125             SetNan ();
00126             return 1;
00127         }
00128 
00129     return 0;
00130     }
00131 
00132 public:
00133 
00134 
00135     /*!
00136         returning the string represents the currect type of the library
00137         we have following types:
00138           asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
00139           asm_gcc_32  - with asm code designed for GCC (32 bits)
00140           asm_vc_64   - with asm for VC (64 bit)
00141           asm_gcc_64  - with asm for GCC (64 bit)
00142           no_asm_32   - pure C++ version (32 bit) - without any asm code
00143           no_asm_64   - pure C++ version (64 bit) - without any asm code
00144     */
00145     static const char * LibTypeStr ()
00146     {
00147         return UInt<man>::LibTypeStr ();
00148     }
00149 
00150 
00151     /*!
00152         returning the currect type of the library
00153     */
00154     static LibTypeCode  LibType ()
00155     {
00156         return UInt<man>::LibType ();
00157     }
00158 
00159 
00160 
00161     /*!
00162         this method moves all bits from mantissa into its left side
00163         (suitably changes the exponent) or if the mantissa is zero
00164         it sets the exponent to zero as well
00165         (and clears the sign bit and sets the zero bit)
00166 
00167         it can return a carry
00168         the carry will be when we don't have enough space in the exponent
00169 
00170         you don't have to use this method if you don't change the mantissa
00171         and exponent directly
00172     */
00173     uint  Standardizing ()
00174     {
00175         if( mantissa.IsTheHighestBitSet () )
00176         {
00177             ClearInfoBit (TTMATH_BIG_ZERO);
00178             return 0;
00179         }
00180 
00181         if( CorrectZero() )
00182             return 0;
00183 
00184         uint  comp = mantissa.CompensationToLeft ();
00185 
00186     return exponent.Sub ( comp );
00187     }
00188 
00189 
00190 private:
00191 
00192     /*!
00193         if the mantissa is equal zero this method sets exponent to zero and
00194         info without the sign
00195 
00196         it returns true if there was the correction
00197     */
00198     bool CorrectZero()
00199     {
00200         if( mantissa.IsZero () )
00201         {
00202             SetInfoBit (TTMATH_BIG_ZERO);
00203             ClearInfoBit (TTMATH_BIG_SIGN);
00204             exponent.SetZero ();
00205 
00206             return true;
00207         }
00208         else
00209         {
00210             ClearInfoBit (TTMATH_BIG_ZERO);
00211         }
00212 
00213     return false;
00214     }
00215 
00216 
00217 public:
00218 
00219     /*!
00220         this method clears a specific bit in the 'info' variable
00221 
00222         bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
00223     */
00224     void ClearInfoBit (unsigned char bit)
00225     {
00226         info = info & (~bit);
00227     }
00228 
00229 
00230     /*!
00231         this method sets a specific bit in the 'info' variable
00232 
00233         bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
00234 
00235     */
00236     void SetInfoBit (unsigned char bit)
00237     {
00238         info = info | bit;
00239     }
00240 
00241 
00242     /*!
00243         this method returns true if a specific bit in the 'info' variable is set
00244 
00245         bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
00246     */
00247     bool IsInfoBit (unsigned char bit) const
00248     {
00249         return (info & bit) != 0;
00250     }
00251 
00252 
00253     /*!
00254         this method sets zero
00255     */
00256     void SetZero ()
00257     {
00258         info = TTMATH_BIG_ZERO;
00259         exponent.SetZero ();
00260         mantissa.SetZero ();
00261 
00262         /*
00263             we don't have to compensate zero
00264         */
00265     }
00266 
00267     
00268     /*!
00269         this method sets one
00270     */
00271     void SetOne ()
00272     {
00273         info = 0;
00274         mantissa.SetZero ();
00275         mantissa.table [man-1] = TTMATH_UINT_HIGHEST_BIT;
00276         exponent = -sint(man * TTMATH_BITS_PER_UINT - 1);
00277 
00278         // don't have to Standardize() - the last bit from mantissa is set
00279     }
00280 
00281 
00282     /*!
00283         this method sets value 0.5
00284     */
00285     void Set05 ()
00286     {
00287         SetOne ();
00288         exponent.SubOne ();
00289     }
00290 
00291 
00292     /*!
00293         this method sets NaN flag (Not a Number)
00294         when this flag is set that means there is no a valid number
00295     */
00296     void SetNan ()
00297     {
00298         SetInfoBit (TTMATH_BIG_NAN);
00299     }
00300 
00301 
00302     /*!
00303         this method sets NaN flag (Not a Number)
00304         also clears the mantissa and exponent (similarly as it would be a zero value)
00305     */
00306     void SetZeroNan ()
00307     {
00308         SetZero ();
00309         SetNan ();
00310     }
00311 
00312 
00313     /*!
00314         this method swappes this for an argument
00315     */
00316     void Swap (Big<exp, man> & ss2)
00317     {
00318         unsigned char info_temp = info;
00319         info = ss2.info;
00320         ss2.info = info_temp;
00321 
00322         exponent.Swap (ss2.exponent);
00323         mantissa.Swap (ss2.mantissa);
00324     }
00325 
00326 
00327 private:
00328 
00329     /*!
00330         this method sets the mantissa of the value of pi
00331     */
00332     void SetMantissaPi()
00333     {
00334     // this is a static table which represents the value of Pi (mantissa of it)
00335     // (first is the highest word)
00336     // we must define this table as 'unsigned int' because 
00337     // both on 32bit and 64bit platforms this table is 32bit
00338     static const unsigned int temp_table[] = {
00339         0xc90fdaa2, 0x2168c234, 0xc4c6628b, 0x80dc1cd1, 0x29024e08, 0x8a67cc74, 0x020bbea6, 0x3b139b22, 
00340         0x514a0879, 0x8e3404dd, 0xef9519b3, 0xcd3a431b, 0x302b0a6d, 0xf25f1437, 0x4fe1356d, 0x6d51c245, 
00341         0xe485b576, 0x625e7ec6, 0xf44c42e9, 0xa637ed6b, 0x0bff5cb6, 0xf406b7ed, 0xee386bfb, 0x5a899fa5, 
00342         0xae9f2411, 0x7c4b1fe6, 0x49286651, 0xece45b3d, 0xc2007cb8, 0xa163bf05, 0x98da4836, 0x1c55d39a, 
00343         0x69163fa8, 0xfd24cf5f, 0x83655d23, 0xdca3ad96, 0x1c62f356, 0x208552bb, 0x9ed52907, 0x7096966d, 
00344         0x670c354e, 0x4abc9804, 0xf1746c08, 0xca18217c, 0x32905e46, 0x2e36ce3b, 0xe39e772c, 0x180e8603, 
00345         0x9b2783a2, 0xec07a28f, 0xb5c55df0, 0x6f4c52c9, 0xde2bcbf6, 0x95581718, 0x3995497c, 0xea956ae5, 
00346         0x15d22618, 0x98fa0510, 0x15728e5a, 0x8aaac42d, 0xad33170d, 0x04507a33, 0xa85521ab, 0xdf1cba64, 
00347         0xecfb8504, 0x58dbef0a, 0x8aea7157, 0x5d060c7d, 0xb3970f85, 0xa6e1e4c7, 0xabf5ae8c, 0xdb0933d7, 
00348         0x1e8c94e0, 0x4a25619d, 0xcee3d226, 0x1ad2ee6b, 0xf12ffa06, 0xd98a0864, 0xd8760273, 0x3ec86a64, 
00349         0x521f2b18, 0x177b200c, 0xbbe11757, 0x7a615d6c, 0x770988c0, 0xbad946e2, 0x08e24fa0, 0x74e5ab31, 
00350         0x43db5bfc, 0xe0fd108e, 0x4b82d120, 0xa9210801, 0x1a723c12, 0xa787e6d7, 0x88719a10, 0xbdba5b26, 
00351         0x99c32718, 0x6af4e23c, 0x1a946834, 0xb6150bda, 0x2583e9ca, 0x2ad44ce8, 0xdbbbc2db, 0x04de8ef9, 
00352         0x2e8efc14, 0x1fbecaa6, 0x287c5947, 0x4e6bc05d, 0x99b2964f, 0xa090c3a2, 0x233ba186, 0x515be7ed, 
00353         0x1f612970, 0xcee2d7af, 0xb81bdd76, 0x2170481c, 0xd0069127, 0xd5b05aa9, 0x93b4ea98, 0x8d8fddc1, 
00354         0x86ffb7dc, 0x90a6c08f, 0x4df435c9, 0x34028492, 0x36c3fab4, 0xd27c7026, 0xc1d4dcb2, 0x602646de, 
00355         0xc9751e76, 0x3dba37bd, 0xf8ff9406, 0xad9e530e, 0xe5db382f, 0x413001ae, 0xb06a53ed, 0x9027d831, 
00356         0x179727b0, 0x865a8918, 0xda3edbeb, 0xcf9b14ed, 0x44ce6cba, 0xced4bb1b, 0xdb7f1447, 0xe6cc254b, 
00357         0x33205151, 0x2bd7af42, 0x6fb8f401, 0x378cd2bf, 0x5983ca01, 0xc64b92ec, 0xf032ea15, 0xd1721d03, 
00358         0xf482d7ce, 0x6e74fef6, 0xd55e702f, 0x46980c82, 0xb5a84031, 0x900b1c9e, 0x59e7c97f, 0xbec7e8f3, 
00359         0x23a97a7e, 0x36cc88be, 0x0f1d45b7, 0xff585ac5, 0x4bd407b2, 0x2b4154aa, 0xcc8f6d7e, 0xbf48e1d8, 
00360         0x14cc5ed2, 0x0f8037e0, 0xa79715ee, 0xf29be328, 0x06a1d58b, 0xb7c5da76, 0xf550aa3d, 0x8a1fbff0, 
00361         0xeb19ccb1, 0xa313d55c, 0xda56c9ec, 0x2ef29632, 0x387fe8d7, 0x6e3c0468, 0x043e8f66, 0x3f4860ee, 
00362         0x12bf2d5b, 0x0b7474d6, 0xe694f91e, 0x6dbe1159, 0x74a3926f, 0x12fee5e4, 0x38777cb6, 0xa932df8c, 
00363         0xd8bec4d0, 0x73b931ba, 0x3bc832b6, 0x8d9dd300, 0x741fa7bf, 0x8afc47ed, 0x2576f693, 0x6ba42466, 
00364         0x3aab639c, 0x5ae4f568, 0x3423b474, 0x2bf1c978, 0x238f16cb, 0xe39d652d, 0xe3fdb8be, 0xfc848ad9, 
00365         0x22222e04, 0xa4037c07, 0x13eb57a8, 0x1a23f0c7, 0x3473fc64, 0x6cea306b, 0x4bcbc886, 0x2f8385dd, 
00366         0xfa9d4b7f, 0xa2c087e8, 0x79683303, 0xed5bdd3a, 0x062b3cf5, 0xb3a278a6, 0x6d2a13f8, 0x3f44f82d, 
00367         0xdf310ee0, 0x74ab6a36, 0x4597e899, 0xa0255dc1, 0x64f31cc5, 0x0846851d, 0xf9ab4819, 0x5ded7ea1, 
00368         0xb1d510bd, 0x7ee74d73, 0xfaf36bc3, 0x1ecfa268, 0x359046f4, 0xeb879f92, 0x4009438b, 0x481c6cd7, 
00369         0x889a002e, 0xd5ee382b, 0xc9190da6, 0xfc026e47, 0x9558e447, 0x5677e9aa, 0x9e3050e2, 0x765694df, 
00370         0xc81f56e8, 0x80b96e71, 0x60c980dd, 0x98a573ea, 0x4472065a, 0x139cd290, 0x6cd1cb72, 0x9ec52a53 // last one was: 0x9ec52a52
00371         //0x86d44014, ...
00372         // (the last word 0x9ec52a52 was rounded up because the next one is 0x86d44014 -- first bit is one 0x8..)
00373         // 256 32bit words for the mantissa -- about 2464 valid decimal digits
00374         };
00375         // the value of PI is comming from the website http://zenwerx.com/pi.php
00376         // 3101 digits were taken from this website
00377         //  (later the digits were compared with:
00378         //   http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
00379         // and they were set into Big<1,400> type (using operator=(const char*) on a 32bit platform)
00380         // and then the first 256 words were taken into this table
00381         // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
00382         // and on 64bit platform value 128 (256/2=128))
00383     
00384         mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
00385     }
00386 
00387 public:
00388 
00389 
00390     /*!
00391         this method sets the value of pi
00392     */
00393     void SetPi ()
00394     {
00395         SetMantissaPi();
00396         info = 0;
00397         exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
00398     }
00399 
00400 
00401     /*!
00402         this method sets the value of 0.5 * pi
00403     */
00404     void Set05Pi ()
00405     {
00406         SetMantissaPi();
00407         info = 0;
00408         exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
00409     }
00410 
00411 
00412     /*!
00413         this method sets the value of 2 * pi
00414     */
00415     void Set2Pi ()
00416     {
00417         SetMantissaPi();
00418         info = 0;
00419         exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
00420     }
00421 
00422 
00423     /*!
00424         this method sets the value of e
00425         (the base of the natural logarithm)
00426     */
00427     void SetE ()
00428     {
00429     static const unsigned int temp_table[] = {
00430         0xadf85458, 0xa2bb4a9a, 0xafdc5620, 0x273d3cf1, 0xd8b9c583, 0xce2d3695, 0xa9e13641, 0x146433fb, 
00431         0xcc939dce, 0x249b3ef9, 0x7d2fe363, 0x630c75d8, 0xf681b202, 0xaec4617a, 0xd3df1ed5, 0xd5fd6561, 
00432         0x2433f51f, 0x5f066ed0, 0x85636555, 0x3ded1af3, 0xb557135e, 0x7f57c935, 0x984f0c70, 0xe0e68b77, 
00433         0xe2a689da, 0xf3efe872, 0x1df158a1, 0x36ade735, 0x30acca4f, 0x483a797a, 0xbc0ab182, 0xb324fb61, 
00434         0xd108a94b, 0xb2c8e3fb, 0xb96adab7, 0x60d7f468, 0x1d4f42a3, 0xde394df4, 0xae56ede7, 0x6372bb19, 
00435         0x0b07a7c8, 0xee0a6d70, 0x9e02fce1, 0xcdf7e2ec, 0xc03404cd, 0x28342f61, 0x9172fe9c, 0xe98583ff, 
00436         0x8e4f1232, 0xeef28183, 0xc3fe3b1b, 0x4c6fad73, 0x3bb5fcbc, 0x2ec22005, 0xc58ef183, 0x7d1683b2, 
00437         0xc6f34a26, 0xc1b2effa, 0x886b4238, 0x611fcfdc, 0xde355b3b, 0x6519035b, 0xbc34f4de, 0xf99c0238, 
00438         0x61b46fc9, 0xd6e6c907, 0x7ad91d26, 0x91f7f7ee, 0x598cb0fa, 0xc186d91c, 0xaefe1309, 0x85139270, 
00439         0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x64f2e21e, 0x71f54bff, 0x5cae82ab, 0x9c9df69e, 
00440         0xe86d2bc5, 0x22363a0d, 0xabc52197, 0x9b0deada, 0x1dbf9a42, 0xd5c4484e, 0x0abcd06b, 0xfa53ddef, 
00441         0x3c1b20ee, 0x3fd59d7c, 0x25e41d2b, 0x669e1ef1, 0x6e6f52c3, 0x164df4fb, 0x7930e9e4, 0xe58857b6, 
00442         0xac7d5f42, 0xd69f6d18, 0x7763cf1d, 0x55034004, 0x87f55ba5, 0x7e31cc7a, 0x7135c886, 0xefb4318a, 
00443         0xed6a1e01, 0x2d9e6832, 0xa907600a, 0x918130c4, 0x6dc778f9, 0x71ad0038, 0x092999a3, 0x33cb8b7a, 
00444         0x1a1db93d, 0x7140003c, 0x2a4ecea9, 0xf98d0acc, 0x0a8291cd, 0xcec97dcf, 0x8ec9b55a, 0x7f88a46b, 
00445         0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a, 
00446         0x23ba4442, 0xcaf53ea6, 0x3bb45432, 0x9b7624c8, 0x917bdd64, 0xb1c0fd4c, 0xb38e8c33, 0x4c701c3a, 
00447         0xcdad0657, 0xfccfec71, 0x9b1f5c3e, 0x4e46041f, 0x388147fb, 0x4cfdb477, 0xa52471f7, 0xa9a96910, 
00448         0xb855322e, 0xdb6340d8, 0xa00ef092, 0x350511e3, 0x0abec1ff, 0xf9e3a26e, 0x7fb29f8c, 0x183023c3, 
00449         0x587e38da, 0x0077d9b4, 0x763e4e4b, 0x94b2bbc1, 0x94c6651e, 0x77caf992, 0xeeaac023, 0x2a281bf6, 
00450         0xb3a739c1, 0x22611682, 0x0ae8db58, 0x47a67cbe, 0xf9c9091b, 0x462d538c, 0xd72b0374, 0x6ae77f5e, 
00451         0x62292c31, 0x1562a846, 0x505dc82d, 0xb854338a, 0xe49f5235, 0xc95b9117, 0x8ccf2dd5, 0xcacef403, 
00452         0xec9d1810, 0xc6272b04, 0x5b3b71f9, 0xdc6b80d6, 0x3fdd4a8e, 0x9adb1e69, 0x62a69526, 0xd43161c1, 
00453         0xa41d570d, 0x7938dad4, 0xa40e329c, 0xcff46aaa, 0x36ad004c, 0xf600c838, 0x1e425a31, 0xd951ae64, 
00454         0xfdb23fce, 0xc9509d43, 0x687feb69, 0xedd1cc5e, 0x0b8cc3bd, 0xf64b10ef, 0x86b63142, 0xa3ab8829, 
00455         0x555b2f74, 0x7c932665, 0xcb2c0f1c, 0xc01bd702, 0x29388839, 0xd2af05e4, 0x54504ac7, 0x8b758282, 
00456         0x2846c0ba, 0x35c35f5c, 0x59160cc0, 0x46fd8251, 0x541fc68c, 0x9c86b022, 0xbb709987, 0x6a460e74, 
00457         0x51a8a931, 0x09703fee, 0x1c217e6c, 0x3826e52c, 0x51aa691e, 0x0e423cfc, 0x99e9e316, 0x50c1217b, 
00458         0x624816cd, 0xad9a95f9, 0xd5b80194, 0x88d9c0a0, 0xa1fe3075, 0xa577e231, 0x83f81d4a, 0x3f2fa457, 
00459         0x1efc8ce0, 0xba8a4fe8, 0xb6855dfe, 0x72b0a66e, 0xded2fbab, 0xfbe58a30, 0xfafabe1c, 0x5d71a87e, 
00460         0x2f741ef8, 0xc1fe86fe, 0xa6bbfde5, 0x30677f0d, 0x97d11d49, 0xf7a8443d, 0x0822e506, 0xa9f4614e, 
00461         0x011e2a94, 0x838ff88c, 0xd68c8bb7, 0xc51eef6d, 0x49ea8ab4, 0xf2c3df5b, 0xb4e0735a, 0xb0d68749
00462         // 0x2fe26dd4, ...
00463         // 256 32bit words for the mantissa -- about 2464 valid decimal digits
00464         };
00465 
00466         // above value was calculated using Big<1,400> type on a 32bit platform
00467         // and then the first 256 words were taken,
00468         // the calculating was made by using ExpSurrounding0(1) method
00469         // which took 1420 iterations
00470         // (the result was compared with e taken from http://antwrp.gsfc.nasa.gov/htmltest/gifcity/e.2mil)
00471         // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
00472         // and on 64bit platform value 128 (256/2=128))
00473 
00474         mantissa.SetFromTable (temp_table, sizeof(temp_table) / sizeof(int));
00475         exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
00476         info = 0;
00477     }
00478 
00479 
00480     /*!
00481         this method sets the value of ln(2)
00482         the natural logarithm from 2
00483     */
00484     void SetLn2 ()
00485     {
00486     static const unsigned int temp_table[] = {
00487         0xb17217f7, 0xd1cf79ab, 0xc9e3b398, 0x03f2f6af, 0x40f34326, 0x7298b62d, 0x8a0d175b, 0x8baafa2b, 
00488         0xe7b87620, 0x6debac98, 0x559552fb, 0x4afa1b10, 0xed2eae35, 0xc1382144, 0x27573b29, 0x1169b825, 
00489         0x3e96ca16, 0x224ae8c5, 0x1acbda11, 0x317c387e, 0xb9ea9bc3, 0xb136603b, 0x256fa0ec, 0x7657f74b, 
00490         0x72ce87b1, 0x9d6548ca, 0xf5dfa6bd, 0x38303248, 0x655fa187, 0x2f20e3a2, 0xda2d97c5, 0x0f3fd5c6, 
00491         0x07f4ca11, 0xfb5bfb90, 0x610d30f8, 0x8fe551a2, 0xee569d6d, 0xfc1efa15, 0x7d2e23de, 0x1400b396, 
00492         0x17460775, 0xdb8990e5, 0xc943e732, 0xb479cd33, 0xcccc4e65, 0x9393514c, 0x4c1a1e0b, 0xd1d6095d, 
00493         0x25669b33, 0x3564a337, 0x6a9c7f8a, 0x5e148e82, 0x074db601, 0x5cfe7aa3, 0x0c480a54, 0x17350d2c, 
00494         0x955d5179, 0xb1e17b9d, 0xae313cdb, 0x6c606cb1, 0x078f735d, 0x1b2db31b, 0x5f50b518, 0x5064c18b, 
00495         0x4d162db3, 0xb365853d, 0x7598a195, 0x1ae273ee, 0x5570b6c6, 0x8f969834, 0x96d4e6d3, 0x30af889b, 
00496         0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef9, 0x8d6f5177, 0xfbcf0755, 0x268a5c1f, 0x9538b982, 
00497         0x61affd44, 0x6b1ca3cf, 0x5e9222b8, 0x8c66d3c5, 0x422183ed, 0xc9942109, 0x0bbb16fa, 0xf3d949f2, 
00498         0x36e02b20, 0xcee886b9, 0x05c128d5, 0x3d0bd2f9, 0x62136319, 0x6af50302, 0x0060e499, 0x08391a0c, 
00499         0x57339ba2, 0xbeba7d05, 0x2ac5b61c, 0xc4e9207c, 0xef2f0ce2, 0xd7373958, 0xd7622658, 0x901e646a, 
00500         0x95184460, 0xdc4e7487, 0x156e0c29, 0x2413d5e3, 0x61c1696d, 0xd24aaebd, 0x473826fd, 0xa0c238b9, 
00501         0x0ab111bb, 0xbd67c724, 0x972cd18b, 0xfbbd9d42, 0x6c472096, 0xe76115c0, 0x5f6f7ceb, 0xac9f45ae, 
00502         0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd8, 
00503         0x85db6ab0, 0x3a49bd0d, 0xc0b1b31d, 0x8a0e23fa, 0xc5e5767d, 0xf95884e0, 0x6425a415, 0x26fac51c, 
00504         0x3ea8449f, 0xe8f70edd, 0x062b1a63, 0xa6c4c60c, 0x52ab3316, 0x1e238438, 0x897a39ce, 0x78b63c9f, 
00505         0x364f5b8a, 0xef22ec2f, 0xee6e0850, 0xeca42d06, 0xfb0c75df, 0x5497e00c, 0x554b03d7, 0xd2874a00, 
00506         0x0ca8f58d, 0x94f0341c, 0xbe2ec921, 0x56c9f949, 0xdb4a9316, 0xf281501e, 0x53daec3f, 0x64f1b783, 
00507         0x154c6032, 0x0e2ff793, 0x33ce3573, 0xfacc5fdc, 0xf1178590, 0x3155bbd9, 0x0f023b22, 0x0224fcd8, 
00508         0x471bf4f4, 0x45f0a88a, 0x14f0cd97, 0x6ea354bb, 0x20cdb5cc, 0xb3db2392, 0x88d58655, 0x4e2a0e8a, 
00509         0x6fe51a8c, 0xfaa72ef2, 0xad8a43dc, 0x4212b210, 0xb779dfe4, 0x9d7307cc, 0x846532e4, 0xb9694eda, 
00510         0xd162af05, 0x3b1751f3, 0xa3d091f6, 0x56658154, 0x12b5e8c2, 0x02461069, 0xac14b958, 0x784934b8, 
00511         0xd6cce1da, 0xa5053701, 0x1aa4fb42, 0xb9a3def4, 0x1bda1f85, 0xef6fdbf2, 0xf2d89d2a, 0x4b183527, 
00512         0x8fd94057, 0x89f45681, 0x2b552879, 0xa6168695, 0xc12963b0, 0xff01eaab, 0x73e5b5c1, 0x585318e7, 
00513         0x624f14a5, 0x1a4a026b, 0x68082920, 0x57fd99b6, 0x6dc085a9, 0x8ac8d8ca, 0xf9eeeea9, 0x8a2400ca, 
00514         0xc95f260f, 0xd10036f9, 0xf91096ac, 0x3195220a, 0x1a356b2a, 0x73b7eaad, 0xaf6d6058, 0x71ef7afb, 
00515         0x80bc4234, 0x33562e94, 0xb12dfab4, 0x14451579, 0xdf59eae0, 0x51707062, 0x4012a829, 0x62c59cab, 
00516         0x347f8304, 0xd889659e, 0x5a9139db, 0x14efcc30, 0x852be3e8, 0xfc99f14d, 0x1d822dd6, 0xe2f76797, 
00517         0xe30219c8, 0xaa9ce884, 0x8a886eb3, 0xc87b7295, 0x988012e8, 0x314186ed, 0xbaf86856, 0xccd3c3b6, 
00518         0xee94e62f, 0x110a6783, 0xd2aae89c, 0xcc3b76fc, 0x435a0ce1, 0x34c2838f, 0xd571ec6c, 0x1366a993 // last one was: 0x1366a992
00519         //0xcbb9ac40, ...
00520         // (the last word 0x1366a992 was rounded up because the next one is 0xcbb9ac40 -- first bit is one 0xc..)
00521         // 256 32bit words for the mantissa -- about 2464 valid decimal digits
00522         };    
00523 
00524         // above value was calculated using Big<1,400> type on a 32bit platform
00525         // and then the first 256 words were taken,
00526         // the calculating was made by using LnSurrounding1(2) method
00527         // which took 4035 iterations
00528         // (the result was compared with ln(2) taken from http://ja0hxv.calico.jp/pai/estart.html)
00529         // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
00530         // and on 64bit platform value 128 (256/2=128))
00531 
00532         mantissa.SetFromTable (temp_table, sizeof(temp_table) / sizeof(int));
00533         exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
00534         info = 0;
00535     }
00536 
00537 
00538     /*!
00539         this method sets the value of ln(10)
00540         the natural logarithm from 10
00541 
00542         I introduced this constant especially to make the conversion ToString()
00543         being faster. In fact the method ToString() is keeping values of logarithms
00544         it has calculated but it must calculate the logarithm at least once.
00545         If a program, which uses this library, is running for a long time this
00546         would be ok, but for programs which are running shorter, for example for
00547         CGI applications which only once are printing values, this would be much
00548         inconvenience. Then if we're printing with base (radix) 10 and the mantissa
00549         of our value is smaller than or equal to TTMATH_BUILTIN_VARIABLES_SIZE
00550         we don't calculate the logarithm but take it from this constant.
00551     */
00552     void SetLn10 ()
00553     {
00554     static const unsigned int temp_table[] = {
00555         0x935d8ddd, 0xaaa8ac16, 0xea56d62b, 0x82d30a28, 0xe28fecf9, 0xda5df90e, 0x83c61e82, 0x01f02d72, 
00556         0x962f02d7, 0xb1a8105c, 0xcc70cbc0, 0x2c5f0d68, 0x2c622418, 0x410be2da, 0xfb8f7884, 0x02e516d6, 
00557         0x782cf8a2, 0x8a8c911e, 0x765aa6c3, 0xb0d831fb, 0xef66ceb0, 0x4ab3c6fa, 0x5161bb49, 0xd219c7bb, 
00558         0xca67b35b, 0x23605085, 0x8e93368d, 0x44789c4f, 0x5b08b057, 0xd5ede20f, 0x469ea58e, 0x9305e981, 
00559         0xe2478fca, 0xad3aee98, 0x9cd5b42e, 0x6a271619, 0xa47ecb26, 0x978c5d4f, 0xdb1d28ea, 0x57d4fdc0, 
00560         0xe40bf3cc, 0x1e14126a, 0x45765cde, 0x268339db, 0xf47fa96d, 0xeb271060, 0xaf88486e, 0xa9b7401e, 
00561         0x3dfd3c51, 0x748e6d6e, 0x3848c8d2, 0x5faf1bca, 0xe88047f1, 0x7b0d9b50, 0xa949eaaa, 0xdf69e8a5, 
00562         0xf77e3760, 0x4e943960, 0xe38a5700, 0xffde2db1, 0xad6bfbff, 0xd821ba0a, 0x4cb0466d, 0x61ba648e, 
00563         0xef99c8e5, 0xf6974f36, 0x3982a78c, 0xa45ddfc8, 0x09426178, 0x19127a6e, 0x3b70fcda, 0x2d732d47, 
00564         0xb5e4b1c8, 0xc0e5a10a, 0xaa6604a5, 0x324ec3dc, 0xbc64ea80, 0x6e198566, 0x1f1d366c, 0x20663834, 
00565         0x4d5e843f, 0x20642b97, 0x0a62d18e, 0x478f7bd5, 0x8fcd0832, 0x4a7b32a6, 0xdef85a05, 0xeb56323a, 
00566         0x421ef5e0, 0xb00410a0, 0xa0d9c260, 0x794a976f, 0xf6ff363d, 0xb00b6b33, 0xf42c58de, 0xf8a3c52d, 
00567         0xed69b13d, 0xc1a03730, 0xb6524dc1, 0x8c167e86, 0x99d6d20e, 0xa2defd2b, 0xd006f8b4, 0xbe145a2a, 
00568         0xdf3ccbb3, 0x189da49d, 0xbc1261c8, 0xb3e4daad, 0x6a36cecc, 0xb2d5ae5b, 0x89bf752f, 0xb5dfb353, 
00569         0xff3065c4, 0x0cfceec8, 0x1be5a9a9, 0x67fddc57, 0xc4b83301, 0x006bf062, 0x4b40ed7a, 0x56c6cdcd, 
00570         0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f8, 
00571         0xfb5f06c3, 0x58ac8f70, 0xfa9d8c59, 0x8c574502, 0xbaf54c96, 0xc84911f0, 0x0482d095, 0x1a0af022, 
00572         0xabbab080, 0xec97efd3, 0x671e4e0e, 0x52f166b6, 0xcd5cd226, 0x0dc67795, 0x2e1e34a3, 0xf799677f, 
00573         0x2c1d48f1, 0x2944b6c5, 0x2ba1307e, 0x704d67f9, 0x1c1035e4, 0x4e927c63, 0x03cf12bf, 0xe2cd2e31, 
00574         0xf8ee4843, 0x344d51b0, 0xf37da42b, 0x9f0b0fd9, 0x134fb2d9, 0xf815e490, 0xd966283f, 0x23962766, 
00575         0xeceab1e4, 0xf3b5fc86, 0x468127e2, 0xb606d10d, 0x3a45f4b6, 0xb776102d, 0x2fdbb420, 0x80c8fa84, 
00576         0xd0ff9f45, 0xc58aef38, 0xdb2410fd, 0x1f1cebad, 0x733b2281, 0x52ca5f36, 0xddf29daa, 0x544334b8, 
00577         0xdeeaf659, 0x4e462713, 0x1ed485b4, 0x6a0822e1, 0x28db471c, 0xa53938a8, 0x44c3bef7, 0xf35215c8, 
00578         0xb382bc4e, 0x3e4c6f15, 0x6285f54c, 0x17ab408e, 0xccbf7f5e, 0xd16ab3f6, 0xced2846d, 0xf457e14f, 
00579         0xbb45d9c5, 0x646ad497, 0xac697494, 0x145de32e, 0x93907128, 0xd263d521, 0x79efb424, 0xd64651d6, 
00580         0xebc0c9f0, 0xbb583a44, 0xc6412c84, 0x85bb29a6, 0x4d31a2cd, 0x92954469, 0xa32b1abd, 0xf7f5202c, 
00581         0xa4aa6c93, 0x2e9b53cf, 0x385ab136, 0x2741f356, 0x5de9c065, 0x6009901c, 0x88abbdd8, 0x74efcf73, 
00582         0x3f761ad4, 0x35f3c083, 0xfd6b8ee0, 0x0bef11c7, 0xc552a89d, 0x58ce4a21, 0xd71e54f2, 0x4157f6c7, 
00583         0xd4622316, 0xe98956d7, 0x450027de, 0xcbd398d8, 0x4b98b36a, 0x0724c25c, 0xdb237760, 0xe9324b68, 
00584         0x7523e506, 0x8edad933, 0x92197f00, 0xb853a326, 0xb330c444, 0x65129296, 0x34bc0670, 0xe177806d, 
00585         0xe338dac4, 0x5537492a, 0xe19add83, 0xcf45000f, 0x5b423bce, 0x6497d209, 0xe30e18a1, 0x3cbf0687, 
00586         0x67973103, 0xd9485366, 0x81506bba, 0x2e93a9a4, 0x7dd59d3f, 0xf17cd746, 0x8c2075be, 0x552a4348 // last one was: 0x552a4347
00587         // 0xb4a638ef, ...
00588         //(the last word 0x552a4347 was rounded up because the next one is 0xb4a638ef -- first bit is one 0xb..)
00589         // 256 32bit words for the mantissa -- about 2464 valid digits (decimal)
00590         };    
00591 
00592         // above value was calculated using Big<1,400> type on a 32bit platform
00593         // and then the first 256 32bit words were taken,
00594         // the calculating was made by using LnSurrounding1(10) method
00595         // which took 22080 iterations
00596         // (the result was compared with ln(10) taken from http://ja0hxv.calico.jp/pai/estart.html)
00597         // (the formula used in LnSurrounding1(x) converges badly when
00598         // the x is greater than one but in fact we can use it, only the
00599         // number of iterations will be greater)
00600         // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
00601         // and on 64bit platform value 128 (256/2=128))
00602 
00603         mantissa.SetFromTable (temp_table, sizeof(temp_table) / sizeof(int));
00604         exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
00605         info = 0;
00606     }
00607 
00608 
00609     /*!
00610         this method sets the maximum value which can be held in this type
00611     */
00612     void SetMax ()
00613     {
00614         info = 0;
00615         mantissa.SetMax ();
00616         exponent.SetMax ();
00617 
00618         // we don't have to use 'Standardizing()' because the last bit from
00619         // the mantissa is set
00620     }
00621 
00622 
00623     /*!
00624         this method sets the minimum value which can be held in this type
00625     */
00626     void SetMin ()
00627     {
00628         info = 0;
00629 
00630         mantissa.SetMax ();
00631         exponent.SetMax ();
00632         SetSign ();
00633 
00634         // we don't have to use 'Standardizing()' because the last bit from
00635         // the mantissa is set
00636     }
00637 
00638 
00639     /*!
00640         testing whether there is a value zero or not
00641     */
00642     bool IsZero () const
00643     {
00644         return IsInfoBit (TTMATH_BIG_ZERO);
00645     }
00646 
00647 
00648     /*!
00649         this method returns true when there's the sign set
00650         also we don't check the NaN flag
00651     */
00652     bool IsSign () const
00653     {
00654         return IsInfoBit (TTMATH_BIG_SIGN);
00655     }
00656 
00657 
00658     /*!
00659         this method returns true when there is not a valid number
00660     */
00661     bool IsNan () const
00662     {
00663         return IsInfoBit (TTMATH_BIG_NAN);
00664     }
00665 
00666 
00667 
00668     /*!
00669         this method clears the sign
00670         (there'll be an absolute value)
00671 
00672             e.g.
00673             -1 -> 1
00674             2  -> 2
00675     */
00676     void Abs ()
00677     {
00678         ClearInfoBit (TTMATH_BIG_SIGN);
00679     }
00680 
00681 
00682     /*!
00683         this method remains the 'sign' of the value
00684         e.g.  -2 = -1 
00685                0 = 0
00686               10 = 1
00687     */
00688     void Sgn ()
00689     {
00690         // we have to check the NaN flag, because the next SetOne() method would clear it
00691         if( IsNan () )
00692             return;
00693 
00694         if( IsSign () )
00695         {
00696             SetOne ();
00697             SetSign ();
00698         }
00699         else
00700         if( IsZero () )
00701             SetZero (); // !! is nedeed here?
00702         else
00703             SetOne ();
00704     }
00705 
00706 
00707 
00708     /*!
00709         this method sets the sign
00710 
00711             e.g.
00712             -1 -> -1
00713             2  -> -2
00714 
00715         we do not check whether there is a zero or not, if you're using this method
00716         you must be sure that the value is (or will be afterwards) different from zero
00717     */
00718     void SetSign ()
00719     {
00720         SetInfoBit (TTMATH_BIG_SIGN);
00721     }
00722 
00723 
00724     /*!
00725         this method changes the sign
00726         when there is a value of zero then the sign is not changed
00727 
00728             e.g.
00729             -1 -> 1
00730             2  -> -2
00731     */
00732     void ChangeSign ()
00733     {
00734         // we don't have to check the NaN flag here
00735 
00736         if( IsZero () )
00737             return;
00738 
00739         if( IsSign () )
00740             ClearInfoBit (TTMATH_BIG_SIGN);
00741         else
00742             SetInfoBit (TTMATH_BIG_SIGN);
00743     }
00744 
00745 
00746 
00747 private:
00748 
00749     /*!
00750         this method does the half-to-even rounding (banker's rounding)
00751 
00752         if is_half is:
00753           true  - that means the rest was equal the half (0.5 decimal)
00754           false - that means the rest was greater than a half (greater than 0.5 decimal)
00755 
00756         if the rest was less than a half then don't call this method
00757         (the rounding should does nothing then)
00758     */
00759     uint  RoundHalfToEven(bool is_half, bool rounding_up = true)
00760     {
00761     uint  c = 0;
00762 
00763         if( !is_half || mantissa.IsTheLowestBitSet () )
00764         {
00765             if( rounding_up )
00766             {
00767                 if( mantissa.AddOne () )
00768                 {
00769                     mantissa.Rcr (1, 1);
00770                     c = exponent.AddOne ();
00771                 }
00772             }
00773             else
00774             {
00775                 #ifdef TTMATH_DEBUG
00776                 uint  c_from_zero =
00777                 #endif
00778                 mantissa.SubOne();
00779 
00780                 // we're using rounding_up=false in Add() when the mantissas have different signs
00781                 // mantissa can be zero only when previous mantissa was equal to ss2.mantissa
00782                 // but in such a case 'last_bit_set' will not be set and consequently 'do_rounding' will be false
00783                 TTMATH_ASSERT( c_from_zero == 0 )
00784             }
00785         }
00786 
00787     return c;
00788     }
00789 
00790 
00791 
00792 
00793 
00794     /*!
00795     *
00796     *    basic mathematic functions
00797     *
00798     */
00799 
00800 
00801     /*!
00802         this method adds one to the existing value
00803     */
00804     uint  AddOne()
00805     {
00806     Big<exp, man> one;
00807 
00808         one.SetOne();
00809 
00810     return Add (one);
00811     }
00812 
00813 
00814     /*!
00815         this method subtracts one from the existing value
00816     */
00817     uint  SubOne()
00818     {
00819     Big<exp, man> one;
00820 
00821         one.SetOne();
00822 
00823     return Sub (one);
00824     }
00825 
00826 
00827 private:
00828 
00829 
00830     /*!
00831         an auxiliary method for adding
00832     */
00833     void AddCheckExponents(    Big<exp, man> & ss2,
00834                             Int<exp> & exp_offset,
00835                             bool & last_bit_set,
00836                             bool & rest_zero,
00837                             bool & do_adding,
00838                             bool & do_rounding)
00839     {
00840     Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
00841 
00842         if( exp_offset == mantissa_size_in_bits )
00843         {
00844             last_bit_set = ss2.mantissa.IsTheHighestBitSet();
00845             rest_zero    = ss2.mantissa.AreFirstBitsZero(man*TTMATH_BITS_PER_UINT - 1);
00846             do_rounding  = true;    // we'are only rounding
00847         }
00848         else
00849         if( exp_offset < mantissa_size_in_bits )
00850         {
00851             uint  moved = exp_offset.ToInt(); // how many times we must move ss2.mantissa
00852             rest_zero  = true;
00853 
00854             if( moved > 0 )
00855             {
00856                 last_bit_set = static_cast<bool>( ss2.mantissa.GetBit(moved-1) );
00857 
00858                 if( moved > 1 )
00859                     rest_zero = ss2.mantissa.AreFirstBitsZero(moved - 1);
00860             
00861                 // (2) moving 'exp_offset' times
00862                 ss2.mantissa.Rcr(moved, 0);
00863             }
00864 
00865             do_adding    = true; 
00866             do_rounding  = true;
00867         }
00868 
00869         // if exp_offset is greater than mantissa_size_in_bits then we do nothing
00870         // ss2 is too small for taking into consideration in the sum
00871     }
00872 
00873 
00874     /*!
00875         an auxiliary method for adding
00876     */
00877     uint  AddMantissas(    Big<exp, man> & ss2,
00878                         bool & last_bit_set,
00879                         bool & rest_zero)
00880     {
00881     uint  c = 0;
00882 
00883         if( IsSign () == ss2.IsSign() )
00884         {
00885             // values have the same signs
00886             if( mantissa.Add(ss2.mantissa) )
00887             {
00888                 // we have one bit more from addition (carry)
00889                 // now rest_zero means the old rest_zero with the old last_bit_set
00890                 rest_zero    = (!last_bit_set && rest_zero);
00891                 last_bit_set = mantissa.Rcr(1,1);
00892                 c += exponent.AddOne();
00893             }
00894         }
00895         else
00896         {
00897             // values have different signs
00898             // there shouldn't be a carry here because
00899             // (1) (2) guarantee that the mantissa of this
00900             // is greater than or equal to the mantissa of the ss2
00901 
00902             #ifdef TTMATH_DEBUG
00903             uint  c_temp =
00904             #endif
00905             mantissa.Sub(ss2.mantissa);
00906 
00907             TTMATH_ASSERT( c_temp == 0 )
00908         }
00909 
00910     return c;
00911     }
00912 
00913 
00914 public:
00915 
00916 
00917     /*!
00918         Addition this = this + ss2
00919 
00920         it returns carry if the sum is too big
00921     */
00922     uint  Add (Big<exp, man> ss2, bool round = true, bool adding = true)
00923     {
00924     bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
00925     Int<exp>  exp_offset( exponent );
00926     uint  c = 0;
00927 
00928         if( IsNan () || ss2.IsNan () )
00929             return CheckCarry (1);
00930 
00931         if( !adding )
00932             ss2.ChangeSign (); // subtracting
00933 
00934         exp_offset.Sub ( ss2.exponent );
00935         exp_offset.Abs ();
00936 
00937         // (1) abs(this) will be >= abs(ss2)
00938         if( SmallerWithoutSignThan (ss2) )
00939             Swap (ss2);
00940     
00941         if( ss2.IsZero () )
00942             return 0;
00943 
00944         last_bit_set = rest_zero = do_adding = do_rounding = false;
00945         rounding_up = (IsSign () == ss2.IsSign ());
00946 
00947         AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
00948 
00949         if( do_adding )
00950             c += AddMantissas(ss2, last_bit_set, rest_zero);
00951 
00952         if( !round || !last_bit_set )
00953             do_rounding = false;
00954 
00955         if( do_rounding )
00956             c += RoundHalfToEven(rest_zero, rounding_up);
00957 
00958         if( do_adding || do_rounding )
00959             c += Standardizing ();
00960 
00961     return CheckCarry (c);
00962     }
00963 
00964 
00965     /*!
00966         Subtraction this = this - ss2
00967 
00968         it returns carry if the result is too big
00969     */
00970     uint  Sub (const Big<exp, man> & ss2, bool round = true)
00971     {
00972         return Add (ss2, round, false);
00973     }
00974         
00975 
00976     /*!
00977         bitwise AND
00978 
00979         this and ss2 must be >= 0
00980         return values:
00981             0 - ok
00982             1 - carry
00983             2 - this or ss2 was negative
00984     */
00985     uint  BitAnd (Big<exp, man> ss2)
00986     {
00987         if( IsNan () || ss2.IsNan () )
00988             return CheckCarry (1);
00989 
00990         if( IsSign () || ss2.IsSign () )
00991         {
00992             SetNan ();
00993             return 2;
00994         }
00995 
00996         if( IsZero () )
00997             return 0;
00998 
00999         if( ss2.IsZero () )
01000         {
01001             SetZero ();
01002             return 0;
01003         }
01004 
01005         Int<exp>  exp_offset( exponent );
01006         Int<exp>  mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
01007 
01008         uint  c = 0;
01009 
01010         exp_offset.Sub ( ss2.exponent );
01011         exp_offset.Abs ();
01012 
01013         // abs(this) will be >= abs(ss2)
01014         if( SmallerWithoutSignThan (ss2) )
01015             Swap (ss2);
01016 
01017         if( exp_offset >= mantissa_size_in_bits )
01018         {
01019             // the second value is too small
01020             SetZero ();
01021             return 0;
01022         }
01023 
01024         // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
01025         ss2.mantissa.Rcr ( exp_offset.ToInt (), 0 );
01026         mantissa.BitAnd (ss2.mantissa);
01027 
01028         c += Standardizing ();
01029 
01030     return CheckCarry (c);
01031     }
01032 
01033 
01034     /*!
01035         bitwise OR
01036 
01037         this and ss2 must be >= 0
01038         return values:
01039             0 - ok
01040             1 - carry
01041             2 - this or ss2 was negative
01042     */
01043     uint  BitOr (Big<exp, man> ss2)
01044     {
01045         if( IsNan () || ss2.IsNan () )
01046             return CheckCarry (1);
01047 
01048         if( IsSign () || ss2.IsSign () )
01049         {
01050             SetNan ();
01051             return 2;
01052         }
01053         
01054         if( IsZero () )
01055         {
01056             *this = ss2;
01057             return 0;
01058         }
01059 
01060         if( ss2.IsZero () )
01061             return 0;
01062 
01063         Int<exp>  exp_offset( exponent );
01064         Int<exp>  mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
01065 
01066         uint  c = 0;
01067 
01068         exp_offset.Sub ( ss2.exponent );
01069         exp_offset.Abs ();
01070 
01071         // abs(this) will be >= abs(ss2)
01072         if( SmallerWithoutSignThan (ss2) )
01073             Swap (ss2);
01074 
01075         if( exp_offset >= mantissa_size_in_bits )
01076             // the second value is too small
01077             return 0;
01078 
01079         // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
01080         ss2.mantissa.Rcr ( exp_offset.ToInt (), 0 );
01081         mantissa.BitOr (ss2.mantissa);
01082 
01083         c += Standardizing ();
01084 
01085     return CheckCarry (c);
01086     }
01087 
01088 
01089     /*!
01090         bitwise XOR
01091 
01092         this and ss2 must be >= 0
01093         return values:
01094             0 - ok
01095             1 - carry
01096             2 - this or ss2 was negative
01097     */
01098     uint  BitXor (Big<exp, man> ss2)
01099     {
01100         if( IsNan () || ss2.IsNan () )
01101             return CheckCarry (1);
01102 
01103         if( IsSign () || ss2.IsSign () )
01104         {
01105             SetNan ();
01106             return 2;
01107         }
01108         
01109         if( ss2.IsZero () )
01110             return 0;
01111 
01112         if( IsZero () )
01113         {
01114             *this = ss2;
01115             return 0;
01116         }
01117 
01118         Int<exp>  exp_offset( exponent );
01119         Int<exp>  mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
01120 
01121         uint  c = 0;
01122 
01123         exp_offset.Sub ( ss2.exponent );
01124         exp_offset.Abs ();
01125 
01126         // abs(this) will be >= abs(ss2)
01127         if( SmallerWithoutSignThan (ss2) )
01128             Swap (ss2);
01129 
01130         if( exp_offset >= mantissa_size_in_bits )
01131             // the second value is too small
01132             return 0;
01133 
01134         // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
01135         ss2.mantissa.Rcr ( exp_offset.ToInt (), 0 );
01136         mantissa.BitXor (ss2.mantissa);
01137 
01138         c += Standardizing ();
01139 
01140     return CheckCarry (c);
01141     }
01142 
01143 
01144 
01145     /*!
01146         Multiplication this = this * ss2 (ss2 is uint)
01147 
01148         ss2 without a sign
01149     */
01150     uint  MulUInt (uint  ss2)
01151     {
01152     UInt<man+1> man_result;
01153     uint  i,c = 0;
01154 
01155         if( IsNan () )
01156             return 1;
01157 
01158         if( IsZero () )
01159             return 0;
01160 
01161         if( ss2 == 0 )
01162         {
01163             SetZero ();
01164             return 0;
01165         }
01166 
01167         // man_result = mantissa * ss2.mantissa
01168         mantissa.MulInt (ss2, man_result);
01169 
01170         sint bit = UInt<man>::FindLeadingBitInWord(man_result.table [man]); // man - last word
01171         
01172         if( bit!=-1 && uint (bit) > (TTMATH_BITS_PER_UINT/2) )
01173         {
01174             // 'i' will be from 0 to TTMATH_BITS_PER_UINT
01175             i = man_result.CompensationToLeft ();
01176             c = exponent.Add ( TTMATH_BITS_PER_UINT - i );
01177 
01178             for(i=0 ; i<man ; ++i)
01179                 mantissa.table [i] = man_result.table [i+1];
01180         }
01181         else
01182         {
01183             if( bit != -1 )
01184             {
01185                 man_result.Rcr (bit+1, 0);
01186                 c += exponent.Add (bit+1);
01187             }
01188 
01189             for(i=0 ; i<man ; ++i)
01190                 mantissa.table [i] = man_result.table [i];
01191         }
01192 
01193         c += Standardizing ();
01194 
01195     return CheckCarry (c);
01196     }
01197 
01198 
01199     /*!
01200         Multiplication this = this * ss2 (ss2 is sint)
01201 
01202         ss2 with a sign
01203     */
01204     uint  MulInt (sint ss2)
01205     {
01206         if( IsNan () )
01207             return 1;
01208 
01209         if( ss2 == 0 )
01210         {
01211             SetZero ();
01212             return 0;
01213         }
01214 
01215         if( IsZero () )
01216             return 0;
01217 
01218         if( IsSign () == (ss2<0) )
01219         {
01220             // the signs are the same (both are either - or +), the result is positive
01221             Abs ();
01222         }
01223         else
01224         {
01225             // the signs are different, the result is negative
01226             SetSign ();
01227         }
01228 
01229         if( ss2<0 )
01230             ss2 = -ss2;
01231 
01232 
01233     return MulUInt ( uint (ss2) );
01234     }
01235 
01236 
01237 private:
01238 
01239 
01240     /*!
01241         this method checks whether a table pointed by 'tab' and 'len'
01242         has the value 0.5 decimal
01243         (it is treated as the comma operator would be before the highest bit)
01244         call this method only if the highest bit is set - you have to test it beforehand
01245 
01246         return:
01247           true  - tab was equal the half (0.5 decimal)
01248           false - tab was greater than a half (greater than 0.5 decimal)
01249 
01250     */
01251     bool CheckGreaterOrEqualHalf(uint  * tab, uint  len)
01252     {
01253     uint  i;
01254 
01255         TTMATH_ASSERT( len>0 && (tab[len-1] & TTMATH_UINT_HIGHEST_BIT)!=0 )
01256 
01257         for(i=0 ; i<len-1 ; ++i)
01258             if( tab[i] != 0 )
01259                 return false;
01260 
01261         if( tab[i] != TTMATH_UINT_HIGHEST_BIT )
01262             return false;
01263 
01264     return true;
01265     }
01266 
01267 
01268 private:
01269 
01270     /*!
01271         multiplication this = this * ss2
01272         this method returns a carry
01273     */
01274     uint  MulRef(const Big<exp, man> & ss2, bool round = true)
01275     {
01276     TTMATH_REFERENCE_ASSERT( ss2 )
01277 
01278     UInt<man*2> man_result;
01279     uint  c = 0;
01280     uint  i;
01281 
01282         if( IsNan () || ss2.IsNan () )
01283             return CheckCarry (1);
01284 
01285         if( IsZero () )
01286             return 0;
01287 
01288         if( ss2.IsZero () )
01289         {
01290             SetZero ();
01291             return 0;
01292         }
01293 
01294         // man_result = mantissa * ss2.mantissa
01295         mantissa.MulBig(ss2.mantissa, man_result);
01296 
01297         // 'i' will be from 0 to man*TTMATH_BITS_PER_UINT
01298         // because mantissa and ss2.mantissa are standardized 
01299         // (the highest bit in man_result is set to 1 or
01300         // if there is a zero value in man_result the method CompensationToLeft()
01301         // returns 0 but we'll correct this at the end in Standardizing() method)
01302         i = man_result.CompensationToLeft();
01303         uint  exp_add = man * TTMATH_BITS_PER_UINT - i;
01304 
01305         if( exp_add )
01306             c += exponent.Add( exp_add );
01307 
01308         c += exponent.Add( ss2.exponent );
01309 
01310         for(i=0 ; i<man ; ++i)
01311             mantissa.table[i] = man_result.table[i+man];
01312 
01313         if( round && (man_result.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
01314         {
01315             bool is_half = CheckGreaterOrEqualHalf(man_result.table, man);
01316             c += RoundHalfToEven(is_half);        
01317         }
01318 
01319         if( IsSign () == ss2.IsSign() )
01320         {
01321             // the signs are the same, the result is positive
01322             Abs ();
01323         }
01324         else
01325         {
01326             // the signs are different, the result is negative
01327             // if the value is zero it will be corrected later in Standardizing method
01328             SetSign ();
01329         }
01330 
01331         c += Standardizing ();
01332 
01333     return CheckCarry (c);
01334     }
01335     
01336 
01337 public:
01338 
01339 
01340     /*!
01341         multiplication this = this * ss2
01342         this method returns a carry
01343     */
01344     uint  Mul (const Big<exp, man> & ss2, bool round = true)
01345     {
01346         if( this == &ss2 )
01347         {
01348             Big<exp, man> copy_ss2(ss2);
01349             return MulRef(copy_ss2, round);
01350         }
01351         else
01352         {
01353             return MulRef(ss2, round);
01354         }
01355     }
01356 
01357 
01358 private:
01359 
01360     /*!
01361         division this = this / ss2
01362 
01363         return value:
01364         0 - ok
01365         1 - carry (in a division carry can be as well)
01366         2 - improper argument (ss2 is zero)
01367     */
01368     uint  DivRef(const Big<exp, man> & ss2, bool round = true)
01369     {
01370     TTMATH_REFERENCE_ASSERT( ss2 )
01371 
01372     UInt<man*2> man1;
01373     UInt<man*2> man2;
01374     uint  i,c = 0;
01375         
01376         if( IsNan () || ss2.IsNan () )
01377             return CheckCarry (1);
01378 
01379         if( ss2.IsZero () )
01380         {
01381             SetNan ();
01382             return 2;
01383         }
01384 
01385         if( IsZero () )
01386             return 0;
01387 
01388         // !! this two loops can be joined together
01389 
01390         for(i=0 ; i<man ; ++i)
01391         {
01392             man1.table[i+man] = mantissa.table[i];
01393             man2.table[i]     = ss2.mantissa.table[i];
01394         }
01395 
01396         for(i=0 ; i<man ; ++i)
01397         {
01398             man1.table[i] = 0;
01399             man2.table[i+man] = 0;
01400         }
01401 
01402         man1.Div(man2);
01403 
01404         i = man1.CompensationToLeft();
01405 
01406         if( i )
01407             c += exponent.Sub(i);
01408 
01409         c += exponent.Sub(ss2.exponent);
01410         
01411         for(i=0 ; i<man ; ++i)
01412             mantissa.table[i] = man1.table[i+man];
01413 
01414         if( round && (man1.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
01415         {
01416             bool is_half = CheckGreaterOrEqualHalf(man1.table, man);
01417             c += RoundHalfToEven(is_half);
01418         }
01419 
01420         if( IsSign () == ss2.IsSign () )
01421             Abs ();
01422         else
01423             SetSign (); // if there is a zero it will be corrected in Standardizing()
01424 
01425         c += Standardizing ();
01426 
01427     return CheckCarry (c);
01428     }
01429 
01430 
01431 public:
01432 
01433     /*!
01434         division this = this / ss2
01435 
01436         return value:
01437         0 - ok
01438         1 - carry (in a division carry can be as well)
01439         2 - improper argument (ss2 is zero)
01440     */
01441     uint  Div (const Big<exp, man> & ss2, bool round = true)
01442     {
01443         if( this == &ss2 )
01444         {
01445             Big<exp, man> copy_ss2(ss2);
01446             return DivRef(copy_ss2, round);
01447         }
01448         else
01449         {
01450             return DivRef(ss2, round);
01451         }
01452     }
01453 
01454 
01455 private:
01456 
01457     /*!
01458         the remainder from a division
01459     */
01460     uint  ModRef(const Big<exp, man> & ss2)
01461     {
01462     TTMATH_REFERENCE_ASSERT( ss2 )
01463 
01464     uint  c = 0;
01465 
01466         if( IsNan () || ss2.IsNan () )
01467             return CheckCarry (1);
01468 
01469         if( ss2.IsZero () )
01470         {
01471             SetNan ();
01472             return 2;
01473         }
01474 
01475         if( !SmallerWithoutSignThan (ss2) )
01476         {
01477             Big<exp, man> temp(*this);
01478 
01479             c = temp.Div(ss2);
01480             temp.SkipFraction();
01481             c += temp.Mul(ss2);
01482             c += Sub (temp);
01483 
01484             if( !SmallerWithoutSignThan ( ss2 ) )
01485                 c += 1;
01486         }
01487 
01488     return CheckCarry (c);
01489     }
01490 
01491 
01492 public:
01493 
01494     /*!
01495         the remainder from a division
01496 
01497         e.g.
01498          12.6 mod  3 =  0.6   because  12.6 = 3*4 + 0.6
01499         -12.6 mod  3 = -0.6   bacause -12.6 = 3*(-4) + (-0.6)
01500          12.6 mod -3 =  0.6
01501         -12.6 mod -3 = -0.6
01502 
01503         it means:
01504         in other words: this(old) = ss2 * q + this(new)
01505 
01506         return value:
01507         0 - ok
01508         1 - carry
01509         2 - improper argument (ss2 is zero)
01510     */
01511     uint  Mod (const Big<exp, man> & ss2)
01512     {
01513         if( this == &ss2 )
01514         {
01515             Big<exp, man> copy_ss2(ss2);
01516             return ModRef(copy_ss2);
01517         }
01518         else
01519         {
01520             return ModRef(ss2);
01521         }
01522     }
01523 
01524 
01525     /*!
01526         this method returns: 'this' mod 2
01527         (either zero or one)
01528 
01529         this method is much faster than using Mod( object_with_value_two )
01530     */
01531     uint  Mod2 () const
01532     {
01533         if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
01534             return 0;
01535 
01536         sint exp_int = exponent.ToInt ();
01537         // 'exp_int' is negative (or zero), we set it as positive
01538         exp_int = -exp_int;
01539 
01540     return mantissa.GetBit (exp_int);
01541     }
01542 
01543 
01544     /*!
01545         power this = this ^ pow
01546         (pow without a sign)
01547 
01548         binary algorithm (r-to-l)
01549 
01550         return values:
01551         0 - ok
01552         1 - carry
01553         2 - incorrect arguments (0^0)
01554     */
01555     template<uint pow_size>
01556     uint  Pow (UInt<pow_size> pow)
01557     {
01558         if( IsNan () )
01559             return 1;
01560 
01561         if( IsZero () )
01562         {
01563             if( pow.IsZero () )
01564             {
01565                 // we don't define zero^zero
01566                 SetNan ();
01567                 return 2;
01568             }
01569 
01570             // 0^(+something) is zero
01571             return 0;
01572         }
01573 
01574         Big<exp, man> start(*this);
01575         Big<exp, man> result;
01576         result.SetOne ();
01577         uint  c = 0;
01578 
01579         while( !c )
01580         {
01581             if( pow.table [0] & 1 )
01582                 c += result.Mul (start);
01583 
01584             pow.Rcr (1);
01585 
01586             if( pow.IsZero () )
01587                 break;
01588 
01589             c += start.Mul (start);
01590         }
01591 
01592         *this = result;
01593 
01594     return CheckCarry (c);
01595     }
01596 
01597 
01598     /*!
01599         power this = this ^ pow
01600         p can be negative
01601 
01602         return values:
01603         0 - ok
01604         1 - carry
01605         2 - incorrect arguments 0^0 or 0^(-something)
01606     */
01607     template<uint pow_size>
01608     uint  Pow (Int<pow_size> pow)
01609     {
01610         if( IsNan () )
01611             return 1;
01612 
01613         if( !pow.IsSign () )
01614             return Pow ( UInt<pow_size>(pow) );
01615 
01616         if( IsZero () )
01617         {
01618             // if 'p' is negative then
01619             // 'this' must be different from zero
01620             SetNan ();
01621             return 2;
01622         }
01623 
01624         uint  c = pow.ChangeSign ();
01625 
01626         Big<exp, man> t(*this);
01627         c += t.Pow ( UInt<pow_size>(pow) ); // here can only be a carry (return:1)
01628 
01629         SetOne ();
01630         c += Div (t);
01631 
01632     return CheckCarry (c);
01633     }
01634 
01635 
01636     /*!
01637         power this = this ^ abs([pow])
01638         pow is treated as a value without a sign and without a fraction
01639          if pow has a sign then the method pow.Abs() is used
01640          if pow has a fraction the fraction is skipped (not used in calculation)
01641 
01642         return values:
01643         0 - ok
01644         1 - carry
01645         2 - incorrect arguments (0^0)
01646     */
01647     uint  PowUInt (Big<exp, man> pow)
01648     {
01649         if( IsNan () || pow.IsNan () )
01650             return CheckCarry (1);
01651 
01652         if( IsZero () )
01653         {
01654             if( pow.IsZero () )
01655             {
01656                 SetNan ();
01657                 return 2;
01658             }
01659 
01660             // 0^(+something) is zero
01661             return 0;
01662         }
01663 
01664         if( pow.IsSign () )
01665             pow.Abs ();
01666 
01667         Big<exp, man> start(*this);
01668         Big<exp, man> result;
01669         Big<exp, man> one;
01670         uint  c = 0;
01671         one.SetOne ();
01672         result = one;
01673 
01674         while( !c )
01675         {
01676             if( pow.Mod2 () )
01677                 c += result.Mul (start);
01678 
01679             c += pow.exponent.SubOne ();
01680 
01681             if( pow < one )
01682                 break;
01683 
01684             c += start.Mul (start);
01685         }
01686 
01687         *this = result;
01688 
01689     return CheckCarry (c);
01690     }
01691 
01692 
01693     /*!
01694         power this = this ^ [pow]
01695         pow is treated as a value without a fraction
01696         pow can be negative
01697 
01698         return values:
01699         0 - ok
01700         1 - carry
01701         2 - incorrect arguments 0^0 or 0^(-something)
01702     */
01703     uint  PowInt (const Big<exp, man> & pow)
01704     {
01705         if( IsNan () || pow.IsNan () )
01706             return CheckCarry (1);
01707 
01708         if( !pow.IsSign () )
01709             return PowUInt (pow);
01710 
01711         if( IsZero () )
01712         {
01713             // if 'pow' is negative then
01714             // 'this' must be different from zero
01715             SetNan ();
01716             return 2;
01717         }
01718 
01719         Big<exp, man> temp(*this);
01720         uint  c = temp.PowUInt (pow); // here can only be a carry (result:1)
01721 
01722         SetOne ();
01723         c += Div (temp);
01724 
01725     return CheckCarry (c);
01726     }
01727 
01728 
01729     /*!
01730         power this = this ^ pow
01731         this must be greater than zero (this > 0)
01732         pow can be negative and with fraction
01733 
01734         return values:
01735         0 - ok
01736         1 - carry
01737         2 - incorrect argument ('this' <= 0)
01738     */
01739     uint  PowFrac (const Big<exp, man> & pow)
01740     {
01741         if( IsNan () || pow.IsNan () )
01742             return CheckCarry (1);
01743 
01744         Big<exp, man> temp;
01745         uint  c = temp.Ln (*this);
01746 
01747         if( c != 0 ) // can be 2 from Ln()
01748         {
01749             SetNan ();
01750             return c;
01751         }
01752 
01753         c += temp.Mul (pow);
01754         c += Exp (temp);
01755 
01756     return CheckCarry (c);
01757     }
01758 
01759 
01760     /*!
01761         power this = this ^ pow
01762         pow can be negative and with fraction
01763 
01764         return values:
01765         0 - ok
01766         1 - carry
01767         2 - incorrect argument ('this' or 'pow')
01768     */
01769     uint  Pow (const Big<exp, man> & pow)
01770     {
01771         if( IsNan () || pow.IsNan () )
01772             return CheckCarry (1);
01773 
01774         if( IsZero () )
01775         {
01776             // 0^pow will be 0 only for pow>0
01777             if( pow.IsSign () || pow.IsZero () )
01778             {
01779                 SetNan ();
01780                 return 2;
01781             }
01782 
01783             SetZero ();
01784 
01785         return 0;
01786         }
01787 
01788         if( pow.exponent>-sint(man*TTMATH_BITS_PER_UINT) && pow.exponent<=0 )
01789         {
01790             if( pow.IsInteger () )
01791                 return PowInt ( pow );
01792         }
01793 
01794     return PowFrac (pow);
01795     }
01796 
01797 
01798     /*!
01799         this function calculates the square root
01800         e.g. let this=9 then this.Sqrt() gives 3
01801 
01802         return: 0 - ok
01803                 1 - carry
01804                 2 - improper argument (this<0 or NaN)
01805     */
01806     uint  Sqrt ()
01807     {
01808         if( IsNan () || IsSign () )
01809         {
01810             SetNan ();
01811             return 2;
01812         }
01813 
01814         if( IsZero () )
01815             return 0;
01816 
01817         Big<exp, man> old(*this);
01818         Big<exp, man> ln;
01819         uint  c = 0;
01820 
01821         // we're using the formula: sqrt(x) = e ^ (ln(x) / 2)
01822         c += ln.Ln (*this);
01823         c += ln.exponent.SubOne (); // ln = ln / 2
01824         c += Exp (ln);
01825 
01826         // above formula doesn't give accurate results for some integers
01827         // e.g. Sqrt(81) would not be 9 but a value very closed to 9
01828         // we're rounding the result, calculating result*result and comparing
01829         // with the old value, if they are equal then the result is an integer too
01830 
01831         if( !c && old.IsInteger () && !IsInteger () )
01832         {
01833             Big<exp, man> temp(*this);
01834             c += temp.Round ();
01835 
01836             Big<exp, man> temp2(temp);
01837             c += temp.Mul (temp2);
01838 
01839             if( temp == old )
01840                 *this = temp2;
01841         }
01842 
01843     return CheckCarry (c);
01844     }
01845 
01846 
01847 private:
01848 
01849 #ifdef TTMATH_CONSTANTSGENERATOR
01850 public:
01851 #endif
01852 
01853     /*!
01854         Exponent this = exp(x) = e^x where x is in (-1,1)
01855 
01856         we're using the formula exp(x) = 1 + (x)/(1!) + (x^2)/(2!) + (x^3)/(3!) + ...
01857     */
01858     void ExpSurrounding0 (const Big<exp,man> & x, uint  * steps = 0)
01859     {
01860         TTMATH_REFERENCE_ASSERT( x )
01861 
01862         Big<exp,man> denominator, denominator_i;
01863         Big<exp,man> one, old_value, next_part;
01864         Big<exp,man> numerator = x;
01865         
01866         SetOne ();
01867         one.SetOne ();
01868         denominator.SetOne ();
01869         denominator_i.SetOne ();
01870 
01871         uint  i;
01872         old_value = *this;
01873 
01874         // we begin from 1 in order to not test at the beginning
01875     #ifdef TTMATH_CONSTANTSGENERATOR
01876         for(i=1 ; true ; ++i)
01877     #else
01878         for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
01879     #endif
01880         {
01881             bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
01882 
01883             next_part = numerator;
01884 
01885             if( next_part.Div ( denominator ) )
01886                 // if there is a carry here we only break the loop 
01887                 // however the result we return as good
01888                 // it means there are too many parts of the formula
01889                 break;
01890 
01891             // there shouldn't be a carry here
01892             Add ( next_part );
01893 
01894             if( testing )
01895             {
01896                 if( old_value == *this )
01897                     // we've added next few parts of the formula but the result
01898                     // is still the same then we break the loop
01899                     break;
01900                 else
01901                     old_value = *this;
01902             }
01903 
01904             // we set the denominator and the numerator for a next part of the formula
01905             if( denominator_i.Add (one) )
01906                 // if there is a carry here the result we return as good
01907                 break;
01908 
01909             if( denominator.Mul (denominator_i) )
01910                 break;
01911 
01912             if( numerator.Mul (x) )
01913                 break;
01914         }
01915 
01916         if( steps )
01917             *steps = i;
01918     }
01919 
01920 public:
01921 
01922 
01923     /*!
01924         Exponent this = exp(x) = e^x
01925 
01926         we're using the fact that our value is stored in form of:
01927             x = mantissa * 2^exponent
01928         then
01929             e^x = e^(mantissa* 2^exponent) or
01930             e^x = (e^mantissa)^(2^exponent)
01931 
01932         'Exp' returns a carry if we can't count the result ('x' is too big)
01933     */
01934     uint  Exp (const Big<exp,man> & x)
01935     {
01936     uint  c = 0;
01937         
01938         if( x.IsNan () )
01939             return CheckCarry (1);
01940 
01941         if( x.IsZero () )
01942         {
01943             SetOne ();
01944         return 0;
01945         }
01946 
01947         // m will be the value of the mantissa in range (-1,1)
01948         Big<exp,man> m(x);
01949         m.exponent = -sint(man*TTMATH_BITS_PER_UINT);
01950 
01951         // 'e_' will be the value of '2^exponent'
01952         //   e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;  and
01953         //   e_.exponent.Add(1) mean:
01954         //     e_.mantissa.table[0] = 1;
01955         //     e_.Standardizing();
01956         //     e_.exponent.Add(man*TTMATH_BITS_PER_UINT)
01957         //     (we must add 'man*TTMATH_BITS_PER_UINT' because we've taken it from the mantissa)
01958         Big<exp,man> e_(x);
01959         e_.mantissa.SetZero ();
01960         e_.mantissa.table [man-1] = TTMATH_UINT_HIGHEST_BIT;
01961         c += e_.exponent.Add (1);
01962         e_.Abs ();
01963 
01964         /*
01965             now we've got:
01966             m - the value of the mantissa in range (-1,1)
01967             e_ - 2^exponent
01968 
01969             e_ can be as:
01970             ...2^-2, 2^-1, 2^0, 2^1, 2^2 ...
01971             ...1/4 , 1/2 , 1  , 2  , 4   ...
01972 
01973             above one e_ is integer
01974 
01975             if e_ is greater than 1 we calculate the exponent as:
01976                 e^(m * e_) = ExpSurrounding0(m) ^ e_
01977             and if e_ is smaller or equal one we calculate the exponent in this way:
01978                 e^(m * e_) = ExpSurrounding0(m* e_)
01979             because if e_ is smaller or equal 1 then the product of m*e_ is smaller or equal m
01980         */
01981 
01982         if( e_ <= 1 )
01983         {
01984             m.Mul (e_);
01985             ExpSurrounding0 (m);
01986         }
01987         else
01988         {
01989             ExpSurrounding0 (m);
01990             c += PowUInt (e_);
01991         }
01992     
01993     return CheckCarry (c);
01994     }
01995 
01996 
01997 
01998 
01999 private:
02000 
02001 #ifdef TTMATH_CONSTANTSGENERATOR
02002 public:
02003 #endif
02004 
02005     /*!
02006         Natural logarithm this = ln(x) where x in range <1,2)
02007 
02008         we're using the formula:
02009         ln x = 2 * [ (x-1)/(x+1) + (1/3)((x-1)/(x+1))^3 + (1/5)((x-1)/(x+1))^5 + ... ]
02010     */
02011     void LnSurrounding1 (const Big<exp,man> & x, uint  * steps = 0)
02012     {
02013         Big<exp,man> old_value, next_part, denominator, one, two, x1(x), x2(x);
02014 
02015         one.SetOne ();
02016 
02017         if( x == one )
02018         {
02019             // LnSurrounding1(1) is 0
02020             SetZero ();
02021             return;
02022         }
02023 
02024         two = 2;
02025 
02026         x1.Sub (one);
02027         x2.Add (one);
02028 
02029         x1.Div(x2);
02030         x2 = x1;
02031         x2.Mul (x1);
02032 
02033         denominator.SetOne ();
02034         SetZero ();
02035 
02036         old_value = *this;
02037         uint  i;
02038 
02039 
02040     #ifdef TTMATH_CONSTANTSGENERATOR
02041         for(i=1 ; true ; ++i)
02042     #else
02043         // we begin from 1 in order to not test at the beginning
02044         for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
02045     #endif
02046         {
02047             bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
02048 
02049             next_part = x1;
02050 
02051             if( next_part.Div (denominator) )
02052                 // if there is a carry here we only break the loop 
02053                 // however the result we return as good
02054                 // it means there are too many parts of the formula
02055                 break;
02056 
02057             // there shouldn't be a carry here
02058             Add (next_part);
02059 
02060             if( testing )
02061             {
02062                 if( old_value == *this )
02063                     // we've added next (step_test) parts of the formula but the result
02064                     // is still the same then we break the loop
02065                     break;
02066                 else
02067                     old_value = *this;
02068             }
02069 
02070             if( x1.Mul(x2) )
02071                 // if there is a carry here the result we return as good
02072                 break;
02073 
02074             if( denominator.Add (two) )
02075                 break;
02076         }
02077 
02078         // this = this * 2
02079         // ( there can't be a carry here because we calculate the logarithm between <1,2) )
02080         exponent.AddOne ();
02081 
02082         if( steps )
02083             *steps = i;
02084     }
02085 
02086 
02087 
02088 
02089 public:
02090 
02091 
02092     /*!
02093         Natural logarithm this = ln(x)
02094         (a logarithm with the base equal 'e')
02095 
02096         we're using the fact that our value is stored in form of:
02097             x = mantissa * 2^exponent
02098         then
02099             ln(x) = ln (mantissa * 2^exponent) = ln (mantissa) + (exponent * ln (2))
02100 
02101         the mantissa we'll show as a value from range <1,2) because the logarithm
02102         is decreasing too fast when 'x' is going to 0
02103 
02104         return values:
02105             0 - ok
02106             1 - overflow (carry)
02107             2 - incorrect argument (x<=0)
02108     */
02109     uint  Ln (const Big<exp,man> & x)
02110     {
02111         if( x.IsNan () )
02112             return CheckCarry (1);
02113 
02114         if( x.IsSign () || x.IsZero () )
02115         {
02116             SetNan ();
02117             return 2;
02118         }
02119 
02120         Big<exp,man> exponent_temp;
02121         exponent_temp.FromInt ( x.exponent );
02122 
02123         // m will be the value of the mantissa in range <1,2)
02124         Big<exp,man> m(x);
02125         m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1);
02126 
02127         // we must add 'man*TTMATH_BITS_PER_UINT-1' because we've taken it from the mantissa
02128         uint  c = exponent_temp.Add (man*TTMATH_BITS_PER_UINT-1);
02129 
02130         LnSurrounding1 (m);
02131 
02132         Big<exp,man> ln2;
02133         ln2.SetLn2 ();
02134         c += exponent_temp.Mul (ln2);
02135         c += Add (exponent_temp);
02136 
02137     return CheckCarry (c);
02138     }
02139 
02140 
02141     /*!
02142         Logarithm from 'x' with a 'base'
02143 
02144         we're using the formula:
02145             Log(x) with 'base' = ln(x) / ln(base)
02146 
02147         return values:
02148             0 - ok
02149             1 - overflow
02150             2 - incorrect argument (x<=0)
02151             3 - incorrect base (a<=0 lub a=1)
02152     */
02153     uint  Log (const Big<exp,man> & x, const Big<exp,man> & base)
02154     {
02155         if( x.IsNan () || base.IsNan () )
02156             return CheckCarry (1);
02157 
02158         if( x.IsSign () || x.IsZero () )
02159         {
02160             SetNan ();
02161             return 2;
02162         }
02163 
02164         Big<exp,man> denominator;;
02165         denominator.SetOne ();
02166 
02167         if( base.IsSign () || base.IsZero () || base==denominator )
02168         {
02169             SetNan ();
02170             return 3;
02171         }
02172         
02173         if( x == denominator ) // (this is: if x == 1)
02174         {
02175             // log(1) is 0
02176             SetZero ();
02177             return 0;
02178         }
02179 
02180         // another error values we've tested at the beginning
02181         // there can only be a carry
02182         uint  c = Ln (x);
02183 
02184         c += denominator.Ln (base);
02185         c += Div (denominator);
02186 
02187     return CheckCarry (c);
02188     }
02189 
02190 
02191 
02192 
02193     /*!
02194     *
02195     *    converting methods
02196     *
02197     */
02198 
02199 
02200     /*!
02201         converting from another type of a Big object
02202     */
02203     template<uint another_exp, uint another_man>
02204     uint  FromBig (const Big<another_exp, another_man> & another)
02205     {
02206         info = another.info;
02207 
02208         if( IsNan () )
02209             return 1;
02210 
02211         if( exponent.FromInt (another.exponent) )
02212         {
02213             SetNan ();
02214             return 1;
02215         }
02216 
02217         uint  man_len_min = (man < another_man)? man : another_man;
02218         uint  i;
02219         uint  c = 0;
02220 
02221         for( i = 0 ; i<man_len_min ; ++i )
02222             mantissa.table [man-1-i] = another.mantissa.table [another_man-1-i];
02223     
02224         for( ; i<man ; ++i )
02225             mantissa.table [man-1-i] = 0;
02226 
02227 
02228         // MS Visual Express 2005 reports a warning (in the lines with 'uint man_diff = ...'):
02229         // warning C4307: '*' : integral constant overflow
02230         // but we're using 'if( man > another_man )' and 'if( man < another_man )' and there'll be no such situation here
02231         #ifdef _MSC_VER
02232         #pragma warning( disable: 4307 )
02233         #endif
02234 
02235         if( man > another_man )
02236         {
02237             uint  man_diff = (man - another_man) * TTMATH_BITS_PER_UINT;
02238             c += exponent.SubInt (man_diff, 0);
02239         }
02240         else
02241         if( man < another_man )
02242         {
02243             uint  man_diff = (another_man - man) * TTMATH_BITS_PER_UINT;
02244             c += exponent.AddInt (man_diff, 0);
02245         }
02246         
02247         #ifdef _MSC_VER
02248         #pragma warning( default: 4307 )
02249         #endif
02250 
02251         // mantissa doesn't have to be standardized (either the highest bit is set or all bits are equal zero)
02252         CorrectZero();
02253 
02254     return CheckCarry (c);
02255     }
02256 
02257 
02258 private:
02259 
02260     /*!
02261         an auxiliary method for converting 'this' into 'result'
02262         if the value is too big this method returns a carry (1)
02263     */
02264     uint  ToUIntOrInt(uint  & result) const
02265     {
02266         result = 0;
02267 
02268         if( IsZero () )
02269             return 0;
02270 
02271         sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
02272 
02273         if( exponent > maxbit + sint(TTMATH_BITS_PER_UINT) )
02274             // if exponent > (maxbit + sint(TTMATH_BITS_PER_UINT)) the value can't be passed
02275             // into the 'sint' type (it's too big)
02276             return 1;
02277 
02278         if( exponent <= maxbit )
02279             // our value is from the range of (-1,1) and we return zero
02280             return 0;
02281 
02282         // exponent is from a range of (maxbit, maxbit + sint(TTMATH_BITS_PER_UINT) >
02283         // and [maxbit + sint(TTMATH_BITS_PER_UINT] <= 0
02284         sint how_many_bits = exponent.ToInt ();
02285 
02286         // how_many_bits is negative, we'll make it positive
02287         how_many_bits = -how_many_bits;
02288     
02289         result = (mantissa.table [man-1] >> (how_many_bits % TTMATH_BITS_PER_UINT));
02290 
02291     return 0;
02292     }
02293 
02294 
02295 public:
02296 
02297     /*!
02298         this method converts 'this' into uint
02299     */
02300     uint  ToUInt () const
02301     {
02302     uint  result;
02303 
02304         ToUInt (result);
02305 
02306     return result;
02307     }
02308 
02309 
02310     /*!
02311         this method converts 'this' into 'result'
02312 
02313         if the value is too big this method returns a carry (1)
02314     */
02315     uint  ToUInt (uint  & result) const
02316     {
02317         if( ToUIntOrInt(result) )
02318             return 1;
02319 
02320         if( IsSign () )
02321             return 1;
02322 
02323     return 0;
02324     }
02325 
02326 
02327     /*!
02328         this method converts 'this' into sint
02329     */
02330     sint ToInt () const
02331     {
02332     sint result;
02333 
02334         ToInt (result);
02335 
02336     return result;
02337     }
02338 
02339 
02340     /*!
02341         this method converts 'this' into 'result'
02342 
02343         if the value is too big this method returns a carry (1)
02344     */
02345     uint  ToInt (uint  & result) const
02346     {
02347         return ToUInt (result);
02348     }
02349 
02350 
02351     /*!
02352         this method converts 'this' into 'result'
02353 
02354         if the value is too big this method returns a carry (1)
02355     */
02356     uint  ToInt (sint & result) const
02357     {
02358     uint  result_uint;
02359 
02360         uint  c = ToUIntOrInt(result_uint);
02361         result = sint(result_uint);
02362 
02363         if( c )
02364             return 1;
02365 
02366         uint  mask = 0;
02367 
02368         if( IsSign () )
02369         {
02370             mask = TTMATH_UINT_MAX_VALUE;
02371             result = -result;
02372         }
02373 
02374     return ((result & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
02375     }
02376 
02377 
02378 private:
02379 
02380     /*!
02381         an auxiliary method for converting 'this' into 'result'
02382 
02383         if the value is too big this method returns a carry (1)
02384     */
02385     template<uint int_size>
02386     uint  ToUIntOrInt(UInt<int_size> & result) const
02387     {
02388         result.SetZero ();
02389 
02390         if( IsZero () )
02391             return 0;
02392         
02393         sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
02394 
02395         if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )
02396             // if exponent > (maxbit + sint(int_size*TTMATH_BITS_PER_UINT)) the value can't be passed
02397             // into the 'UInt<int_size>' type (it's too big)
02398             return 1;
02399 
02400         if( exponent <= maxbit )
02401             // our value is from range (-1,1) and we return zero
02402             return 0;
02403 
02404         sint how_many_bits = exponent.ToInt ();
02405 
02406         if( how_many_bits < 0 )
02407         {
02408             how_many_bits = -how_many_bits;
02409             uint  index    = how_many_bits / TTMATH_BITS_PER_UINT;
02410 
02411             UInt<man>  mantissa_temp(mantissa);
02412             mantissa_temp.Rcr( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
02413 
02414             for(uint  i=index, a=0 ; i<man ; ++i,++a)
02415                 result.table [a] = mantissa_temp.table[i];
02416         }
02417         else
02418         {
02419             uint  index = how_many_bits / TTMATH_BITS_PER_UINT;
02420 
02421             if( index + (man-1) < int_size )
02422             {
02423                 // above 'if' is always true
02424                 // this is only to get rid of a warning "warning: array subscript is above array bounds"
02425                 // (from gcc)
02426                 // we checked the condition there: "if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )"
02427                 // but gcc doesn't understand our types - exponent is Int<>
02428 
02429                 for(uint  i=0 ; i<man ; ++i)
02430                     result.table [index+i] = mantissa.table[i];
02431             }
02432 
02433             result.Rcl ( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
02434         }
02435 
02436     return 0;
02437     }
02438 
02439 
02440 public:
02441 
02442     /*!
02443         this method converts 'this' into 'result'
02444 
02445         if the value is too big this method returns a carry (1)
02446     */
02447     template<uint int_size>
02448     uint  ToUInt (UInt<int_size> & result) const
02449     {
02450         uint  c = ToUIntOrInt(result);
02451 
02452         if( c )
02453             return 1;
02454 
02455         if( IsSign () )
02456             return 1;
02457 
02458     return 0;
02459     }
02460 
02461 
02462     /*!
02463         this method converts 'this' into 'result'
02464 
02465         if the value is too big this method returns a carry (1)
02466     */
02467     template<uint int_size>
02468     uint  ToInt (UInt<int_size> & result) const
02469     {
02470         return ToUInt (result);
02471     }
02472 
02473 
02474     /*!
02475         this method converts 'this' into 'result'
02476 
02477         if the value is too big this method returns a carry (1)
02478     */
02479     template<uint int_size>
02480     uint  ToInt (Int<int_size> & result) const
02481     {
02482         uint  c = ToUIntOrInt(result);
02483 
02484         if( c )
02485             return 1;
02486 
02487         uint  mask = 0;
02488 
02489         if( IsSign () )
02490         {
02491             result.ChangeSign ();
02492             mask = TTMATH_UINT_MAX_VALUE;
02493         }
02494 
02495     return ((result.table [int_size-1] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT))? 0 : 1;
02496     }
02497 
02498 
02499     /*!
02500         a method for converting 'uint' to this class
02501     */
02502     uint  FromUInt (uint  value)
02503     {
02504         if( value == 0 )
02505         {
02506             SetZero ();
02507             return 0;
02508         }
02509 
02510         info = 0;
02511 
02512         for(uint  i=0 ; i<man-1 ; ++i)
02513             mantissa.table [i] = 0;
02514 
02515         mantissa.table [man-1] = value;
02516         exponent = -sint(man-1) * sint(TTMATH_BITS_PER_UINT);
02517 
02518         // there shouldn't be a carry because 'value' has the 'uint' type 
02519         Standardizing ();
02520 
02521     return 0;
02522     }
02523 
02524 
02525     /*!
02526         a method for converting 'uint' to this class
02527     */
02528     uint  FromInt (uint  value)
02529     {
02530         return FromUInt (value);
02531     }
02532 
02533 
02534     /*!
02535         a method for converting 'sint' to this class
02536     */
02537     uint  FromInt (sint value)
02538     {
02539     bool is_sign = false;
02540 
02541         if( value < 0 )
02542         {
02543             value   = -value;
02544             is_sign = true;
02545         }
02546 
02547         FromUInt (uint (value));
02548 
02549         if( is_sign )
02550             SetSign ();
02551 
02552     return 0;
02553     }
02554 
02555 
02556 
02557     /*!
02558         this method converts from standard double into this class
02559 
02560         standard double means IEEE-754 floating point value with 64 bits
02561         it is as follows (from http://www.psc.edu/general/software/packages/ieee/ieee.html):
02562 
02563         The IEEE double precision floating point standard representation requires
02564         a 64 bit word, which may be represented as numbered from 0 to 63, left to
02565         right. The first bit is the sign bit, S, the next eleven bits are the
02566         exponent bits, 'E', and the final 52 bits are the fraction 'F':
02567 
02568         S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
02569         0 1        11 12                                                63
02570 
02571         The value V represented by the word may be determined as follows:
02572 
02573         * If E=2047 and F is nonzero, then V=NaN ("Not a number")
02574         * If E=2047 and F is zero and S is 1, then V=-Infinity
02575         * If E=2047 and F is zero and S is 0, then V=Infinity
02576         * If 0<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
02577           to represent the binary number created by prefixing F with an implicit
02578           leading 1 and a binary point.
02579         * If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
02580           "unnormalized" values.
02581         * If E=0 and F is zero and S is 1, then V=-0
02582         * If E=0 and F is zero and S is 0, then V=0 
02583     */
02584 
02585 #ifdef TTMATH_PLATFORM32
02586 
02587     uint  FromDouble (double value)
02588     {
02589         // I am not sure what will be on a platform which has 
02590         // a different endianness... but we use this library only
02591         // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
02592         union 
02593         {
02594             double d;
02595             uint  u[2]; // two 32bit words
02596         } temp;
02597 
02598         temp.d = value;
02599 
02600         sint e  = ( temp.u[1] & 0x7FF00000u) >> 20;
02601         uint  m1 = ((temp.u[1] &    0xFFFFFu) << 11) | (temp.u[0] >> 21);
02602         uint  m2 = temp.u[0] << 11;
02603         
02604         if( e == 2047 )
02605         {
02606             // If E=2047 and F is nonzero, then V=NaN ("Not a number")
02607             // If E=2047 and F is zero and S is 1, then V=-Infinity
02608             // If E=2047 and F is zero and S is 0, then V=Infinity
02609 
02610             // we do not support -Infinity and +Infinity
02611             // we assume that there is always NaN 
02612 
02613             SetNan ();
02614         }
02615         else
02616         if( e > 0 )
02617         {
02618             // If 0<E<2047 then
02619             // V=(-1)**S * 2 ** (E-1023) * (1.F)
02620             // where "1.F" is intended to represent the binary number
02621             // created by prefixing F with an implicit leading 1 and a binary point.
02622             
02623             FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
02624                                     e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
02625                                     m1, m2);
02626 
02627             // we do not have to call Standardizing() here
02628             // because the mantissa will have the highest bit set
02629         }
02630         else
02631         {
02632             // e == 0
02633 
02634             if( m1 != 0 || m2 != 0 )
02635             {
02636                 // If E=0 and F is nonzero,
02637                 // then V=(-1)**S * 2 ** (-1022) * (0.F)
02638                 // These are "unnormalized" values.
02639 
02640                 UInt<2> m;
02641                 m.table [1] = m1;
02642                 m.table [0] = m2;
02643                 uint  moved = m.CompensationToLeft ();
02644 
02645                 FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
02646                                         e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
02647                                         m.table [1], m.table [0]);
02648             }
02649             else
02650             {
02651                 // If E=0 and F is zero and S is 1, then V=-0
02652                 // If E=0 and F is zero and S is 0, then V=0 
02653 
02654                 // we do not support -0 or 0, only is one 0
02655                 SetZero ();
02656             }
02657         }
02658 
02659     return 0; // never be a carry
02660     }
02661 
02662 
02663 private:
02664 
02665     void FromDouble_SetExpAndMan(bool is_sign, int e, uint  mhighest, uint  m1, uint  m2)
02666     {
02667         exponent = e;
02668 
02669         if( man > 1 )
02670         {
02671             mantissa.table [man-1] = m1 | mhighest;
02672             mantissa.table [sint(man-2)] = m2;
02673             // although man>1 we're using casting into sint
02674             // to get rid from a warning which generates Microsoft Visual:
02675             // warning C4307: '*' : integral constant overflow
02676 
02677             for(uint  i=0 ; i<man-2 ; ++i)
02678                 mantissa.table [i] = 0;
02679         }
02680         else
02681         {
02682             mantissa.table[0] = m1 | mhighest;
02683         }
02684 
02685         info = 0;
02686     
02687         // the value should be different from zero
02688         TTMATH_ASSERT( mantissa.IsZero() == false )
02689 
02690         if( is_sign )
02691             SetSign ();
02692     }
02693 
02694 
02695 #else
02696 
02697 public:
02698 
02699     // 64bit platforms
02700     uint  FromDouble (double value)
02701     {
02702         // I am not sure what will be on a plaltform which has 
02703         // a different endianness... but we use this library only
02704         // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
02705         union 
02706         {
02707             double d;
02708             uint  u; // one 64bit word
02709         } temp;
02710 
02711         temp.d = value;
02712                           
02713         sint e = (temp.u & 0x7FF0000000000000ul) >> 52;
02714         uint  m = (temp.u &    0xFFFFFFFFFFFFFul) << 11;
02715         
02716         if( e == 2047 )
02717         {
02718             // If E=2047 and F is nonzero, then V=NaN ("Not a number")
02719             // If E=2047 and F is zero and S is 1, then V=-Infinity
02720             // If E=2047 and F is zero and S is 0, then V=Infinity
02721 
02722             // we do not support -Infinity and +Infinity
02723             // we assume that there is always NaN 
02724 
02725             SetNan ();
02726         }
02727         else
02728         if( e > 0 )
02729         {
02730             // If 0<E<2047 then
02731             // V=(-1)**S * 2 ** (E-1023) * (1.F)
02732             // where "1.F" is intended to represent the binary number
02733             // created by prefixing F with an implicit leading 1 and a binary point.
02734             
02735             FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
02736                                     e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
02737                                     0x8000000000000000ul, m);
02738 
02739             // we do not have to call Standardizing() here
02740             // because the mantissa will have the highest bit set
02741         }
02742         else
02743         {
02744             // e == 0
02745 
02746             if( m != 0 )
02747             {
02748                 // If E=0 and F is nonzero,
02749                 // then V=(-1)**S * 2 ** (-1022) * (0.F)
02750                 // These are "unnormalized" values.
02751 
02752                 FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
02753                                         e - 1022 - man*TTMATH_BITS_PER_UINT + 1, 0, m);
02754                 Standardizing ();
02755             }
02756             else
02757             {
02758                 // If E=0 and F is zero and S is 1, then V=-0
02759                 // If E=0 and F is zero and S is 0, then V=0 
02760 
02761                 // we do not support -0 or 0, only is one 0
02762                 SetZero ();
02763             }
02764         }
02765 
02766     return 0; // never be a carry
02767     }
02768 
02769 private:
02770 
02771     void FromDouble_SetExpAndMan(bool is_sign, sint e, uint  mhighest, uint  m)
02772     {
02773         exponent = e;
02774         mantissa.table[man-1] = m | mhighest;
02775 
02776         for(uint  i=0 ; i<man-1 ; ++i)
02777             mantissa.table[i] = 0;
02778 
02779         info = 0;
02780 
02781         // the value should be different from zero
02782         TTMATH_ASSERT( mantissa.IsZero() == false )
02783 
02784         if( is_sign )
02785             SetSign ();
02786     }
02787 
02788 #endif
02789 
02790 
02791 public:
02792 
02793 
02794     /*!
02795         this method converts from float to this class
02796     */
02797     uint  FromFloat (float value)
02798     {
02799         return FromDouble (double(value));
02800     }
02801 
02802 
02803     /*!
02804         this method converts from this class into the 'double'
02805 
02806         if the value is too big:
02807             'result' will be +/-infinity (depending on the sign)
02808         if the value is too small:
02809             'result' will be 0
02810     */
02811     double ToDouble () const
02812     {
02813     double result;
02814 
02815         ToDouble (result);
02816 
02817     return result;
02818     }
02819 
02820 
02821 private:
02822 
02823 
02824     /*!
02825         an auxiliary method to check if the float value is +/-infinity
02826         we provide this method because isinf(float) in only in C99 language
02827 
02828         description taken from: http://www.psc.edu/general/software/packages/ieee/ieee.php
02829 
02830         The IEEE single precision floating point standard representation requires a 32 bit word,
02831         which may be represented as numbered from 0 to 31, left to right.
02832         The first bit is the sign bit, S, the next eight bits are the exponent bits, 'E',
02833         and the final 23 bits are the fraction 'F':
02834 
02835         S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
02836         0 1      8 9                    31
02837 
02838         The value V represented by the word may be determined as follows:
02839 
02840             * If E=255 and F is nonzero, then V=NaN ("Not a number")
02841             * If E=255 and F is zero and S is 1, then V=-Infinity
02842             * If E=255 and F is zero and S is 0, then V=Infinity
02843             * If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent
02844               the binary number created by prefixing F with an implicit leading 1 and a binary point.
02845             * If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
02846             * If E=0 and F is zero and S is 1, then V=-0
02847             * If E=0 and F is zero and S is 0, then V=0         
02848     */
02849     bool IsInf(float value) const
02850     {
02851         // need testing on a 64 bit machine
02852 
02853         union 
02854         {
02855             float d;
02856             uint  u;
02857         } temp;
02858 
02859         temp.d = value;
02860 
02861         if( ((temp.u >> 23) & 0xff) == 0xff )
02862         {
02863             if( (temp.u & 0x7FFFFF) == 0 )
02864                 return true; // +/- infinity
02865         }
02866 
02867     return false;
02868     }
02869 
02870 
02871 public:
02872 
02873     /*!
02874         this method converts from this class into the 'float'
02875 
02876         if the value is too big:
02877             'result' will be +/-infinity (depending on the sign)
02878         if the value is too small:
02879             'result' will be 0
02880     */
02881     float ToFloat () const
02882     {
02883     float result;
02884 
02885         ToFloat (result);
02886 
02887     return result;
02888     }
02889 
02890 
02891     /*!
02892         this method converts from this class into the 'float'
02893 
02894         if the value is too big:
02895             'result' will be +/-infinity (depending on the sign)
02896             and the method returns 1
02897         if the value is too small:
02898             'result' will be 0
02899             and the method returns 1
02900     */
02901     uint  ToFloat (float & result) const
02902     {
02903     double result_double;
02904 
02905         uint  c = ToDouble (result_double);
02906         result = float(result_double);
02907         
02908         if( result == -0.0f )
02909             result = 0.0f;
02910 
02911         if( c )
02912             return 1;
02913 
02914         // although the result_double can have a correct value
02915         // but after converting to float there can be infinity
02916 
02917         if( IsInf(result) )
02918             return 1;
02919 
02920         if( result == 0.0f && result_double != 0.0 )
02921             // result_double was too small for float
02922             return 1;
02923 
02924     return 0;
02925     }
02926 
02927 
02928     /*!
02929         this method converts from this class into the 'double'
02930 
02931         if the value is too big:
02932             'result' will be +/-infinity (depending on the sign)
02933             and the method returns 1
02934         if the value is too small:
02935             'result' will be 0
02936             and the method returns 1
02937     */
02938     uint  ToDouble (double & result) const
02939     {
02940         if( IsZero () )
02941         {
02942             result = 0.0;
02943             return 0;
02944         }
02945 
02946         if( IsNan () )
02947         {
02948             result = ToDouble_SetDouble( false, 2047, 0, false, true);
02949 
02950         return 0;
02951         }
02952 
02953         sint e_correction = sint(man*TTMATH_BITS_PER_UINT) - 1;
02954 
02955         if( exponent >= 1024 - e_correction )
02956         {
02957             // +/- infinity
02958             result = ToDouble_SetDouble( IsSign (), 2047, 0, true);
02959 
02960         return 1;
02961         }
02962         else
02963         if( exponent <= -1023 - 52 - e_correction )
02964         {
02965             // too small value - we assume that there'll be a zero
02966             result = 0;
02967 
02968             // and return a carry
02969         return 1;
02970         }
02971         
02972         sint e = exponent.ToInt () + e_correction;
02973 
02974         if( e <= -1023 )
02975         {
02976             // -1023-52 < e <= -1023  (unnormalized value)
02977             result = ToDouble_SetDouble( IsSign (), 0, -(e + 1023));
02978         }
02979         else
02980         {
02981             // -1023 < e < 1024
02982             result = ToDouble_SetDouble( IsSign (), e + 1023, -1);
02983         }
02984 
02985     return 0;
02986     }
02987 
02988 private:
02989 
02990 #ifdef TTMATH_PLATFORM32
02991 
02992     // 32bit platforms
02993     double ToDouble_SetDouble(bool is_sign, uint  e, sint move, bool infinity = false, bool nan = false) const
02994     {
02995         union 
02996         {
02997             double d;
02998             uint  u[2]; // two 32bit words
02999         } temp;
03000 
03001         temp.u[0] = temp.u[1] = 0;
03002 
03003         if( is_sign )
03004             temp.u[1] |= 0x80000000u;
03005 
03006         temp.u[1] |= (e << 20) & 0x7FF00000u;
03007 
03008         if( nan )
03009         {
03010             temp.u[0] |= 1;
03011             return temp.d;
03012         }
03013 
03014         if( infinity )
03015             return temp.d;
03016 
03017         UInt<2> m;
03018         m.table[1] = mantissa.table[man-1];
03019         m.table[0] = ( man > 1 ) ? mantissa.table[sint(man-2)] : 0;
03020         // although man>1 we're using casting into sint
03021         // to get rid from a warning which generates Microsoft Visual:
03022         // warning C4307: '*' : integral constant overflow
03023 
03024         m.Rcr( 12 + move );
03025         m.table[1] &= 0xFFFFFu; // cutting the 20 bit (when 'move' was -1)
03026 
03027         temp.u[1] |= m.table[1];
03028         temp.u[0] |= m.table[0];
03029 
03030     return temp.d;
03031     }
03032 
03033 #else
03034 
03035     // 64bit platforms
03036     double ToDouble_SetDouble(bool is_sign, uint  e, sint move, bool infinity = false, bool nan = false) const
03037     {
03038         union 
03039         {
03040             double d;
03041             uint  u; // 64bit word
03042         } temp;
03043 
03044         temp.u = 0;
03045         
03046         if( is_sign )
03047             temp.u |= 0x8000000000000000ul;
03048                         
03049         temp.u |= (e << 52) & 0x7FF0000000000000ul;
03050 
03051         if( nan )
03052         {
03053             temp.u |= 1;
03054             return temp.d;
03055         }
03056 
03057         if( infinity )
03058             return temp.d;
03059 
03060         uint  m = mantissa.table[man-1];
03061 
03062         m >>= ( 12 + move );
03063         m &= 0xFFFFFFFFFFFFFul; // cutting the 20 bit (when 'move' was -1)
03064         temp.u |= m;
03065 
03066     return temp.d;
03067     }
03068 
03069 #endif
03070 
03071 
03072 public:
03073 
03074 
03075     /*!
03076         an operator= for converting 'sint' to this class
03077     */
03078     Big<exp, man> & operator= (sint value)
03079     {
03080         FromInt (value);
03081 
03082     return *this;
03083     }
03084 
03085 
03086     /*!
03087         an operator= for converting 'uint' to this class
03088     */
03089     Big<exp, man> & operator= (uint  value)
03090     {
03091         FromUInt (value);
03092 
03093     return *this;
03094     }
03095 
03096 
03097     /*!
03098         an operator= for converting 'float' to this class
03099     */
03100     Big<exp, man> & operator= (float value)
03101     {
03102         FromFloat (value);
03103 
03104     return *this;
03105     }
03106 
03107 
03108     /*!
03109         an operator= for converting 'double' to this class
03110     */
03111     Big<exp, man> & operator= (double value)
03112     {
03113         FromDouble (value);
03114 
03115     return *this;
03116     }
03117 
03118 
03119     /*!
03120         a constructor for converting 'sint' to this class
03121     */
03122     Big (sint value)
03123     {
03124         FromInt (value);
03125     }
03126 
03127     /*!
03128         a constructor for converting 'uint' to this class
03129     */
03130     Big (uint  value)
03131     {    
03132         FromUInt (value);
03133     }
03134     
03135 
03136     /*!
03137         a constructor for converting 'double' to this class
03138     */
03139     Big (double value)
03140     {
03141         FromDouble (value);
03142     }
03143 
03144 
03145     /*!
03146         a constructor for converting 'float' to this class
03147     */
03148     Big (float value)
03149     {
03150         FromFloat (value);
03151     }
03152 
03153 
03154 #ifdef TTMATH_PLATFORM32
03155 
03156     /*!
03157         this method converts 'this' into 'result' (64 bit unsigned integer)
03158         if the value is too big this method returns a carry (1)
03159     */
03160     uint  ToUInt (ulint  & result) const
03161     {
03162     UInt<2> temp; // 64 bits container
03163 
03164         uint  c = ToUInt (temp);
03165         temp.ToUInt (result);
03166 
03167     return c;
03168     }
03169 
03170 
03171     /*!
03172         this method converts 'this' into 'result' (64 bit unsigned integer)
03173         if the value is too big this method returns a carry (1)
03174     */
03175     uint  ToInt (ulint  & result) const
03176     {
03177         return ToUInt (result);
03178     }
03179 
03180 
03181     /*!
03182         this method converts 'this' into 'result' (64 bit unsigned integer)
03183         if the value is too big this method returns a carry (1)
03184     */
03185     uint  ToInt (slint & result) const
03186     {
03187     Int<2> temp; // 64 bits container
03188 
03189         uint  c = ToInt (temp);
03190         temp.ToInt (result);
03191 
03192     return c;
03193     }
03194 
03195 
03196     /*!
03197         a method for converting 'ulint' (64bit unsigned integer) to this class
03198     */
03199     uint  FromUInt (ulint  value)
03200     {
03201         if( value == 0 )
03202         {
03203             SetZero ();
03204             return 0;
03205         }
03206 
03207         info = 0;
03208 
03209         if( man == 1 )
03210         {
03211             sint bit = mantissa.FindLeadingBitInWord (uint (value >> TTMATH_BITS_PER_UINT));
03212 
03213             if( bit != -1 )
03214             {
03215                 // the highest word from value is different from zero
03216                 bit += 1;
03217                 value >>= bit;
03218                 exponent = bit;
03219             }
03220             else
03221             {
03222                 exponent.SetZero ();
03223             }
03224 
03225             mantissa.table [0] = uint (value);
03226         }
03227         else
03228         {
03229         #ifdef _MSC_VER
03230         //warning C4307: '*' : integral constant overflow
03231         #pragma warning( disable: 4307 )
03232         #endif
03233 
03234             // man >= 2
03235             mantissa.table [man-1] = uint (value >> TTMATH_BITS_PER_UINT);
03236             mantissa.table [man-2] = uint (value);
03237 
03238         #ifdef _MSC_VER
03239         //warning C4307: '*' : integral constant overflow
03240         #pragma warning( default: 4307 )
03241         #endif
03242 
03243             exponent = -sint(man-2) * sint(TTMATH_BITS_PER_UINT);
03244 
03245             for(uint  i=0 ; i<man-2 ; ++i)
03246                 mantissa.table [i] = 0;
03247         }
03248 
03249         // there shouldn't be a carry because 'value' has the 'ulint' type 
03250         // (we have    sufficient exponent)
03251         Standardizing ();
03252 
03253     return 0;
03254     }
03255 
03256 
03257     /*!
03258         a method for converting 'ulint' (64bit unsigned integer) to this class
03259     */
03260     uint  FromInt (ulint  value)
03261     {
03262         return FromUInt (value);
03263     }
03264 
03265 
03266     /*!
03267         a method for converting 'slint' (64bit signed integer) to this class
03268     */
03269     uint  FromInt (slint value)
03270     {
03271     bool is_sign = false;
03272 
03273         if( value < 0 )
03274         {
03275             value   = -value;
03276             is_sign = true;
03277         }
03278 
03279         FromUInt (ulint (value));
03280 
03281         if( is_sign )
03282             SetSign ();
03283 
03284     return 0;
03285     }
03286 
03287 
03288     /*!
03289         a constructor for converting 'ulint' (64bit unsigned integer) to this class
03290     */
03291     Big (ulint  value)
03292     {    
03293         FromUInt (value);
03294     }
03295 
03296 
03297     /*!
03298         an operator for converting 'ulint' (64bit unsigned integer) to this class
03299     */
03300     Big<exp, man> & operator= (ulint  value)
03301     {    
03302         FromUInt (value);
03303 
03304     return *this;
03305     }
03306 
03307 
03308     /*!
03309         a constructor for converting 'slint' (64bit signed integer) to this class
03310     */
03311     Big (slint value)
03312     {    
03313         FromInt (value);
03314     }
03315 
03316 
03317     /*!
03318         an operator for converting 'slint' (64bit signed integer) to this class
03319     */
03320     Big<exp, man> & operator= (slint value)
03321     {    
03322         FromInt (value);
03323 
03324     return *this;
03325     }
03326 
03327 #endif
03328 
03329 
03330 
03331 #ifdef TTMATH_PLATFORM64
03332 
03333 
03334     /*!
03335         this method converts 'this' into 'result' (32 bit unsigned integer)
03336         ***this method is created only on a 64bit platform***
03337         if the value is too big this method returns a carry (1)
03338     */
03339     uint  ToUInt (unsigned int & result) const
03340     {
03341     uint  result_uint;
03342 
03343         uint  c = ToUInt (result_uint);
03344         result = (unsigned int)result_uint;
03345 
03346         if( c || result_uint != uint (result) )
03347             return 1;
03348 
03349     return 0;
03350     }
03351 
03352 
03353     /*!
03354         this method converts 'this' into 'result' (32 bit unsigned integer)
03355         ***this method is created only on a 64bit platform***
03356         if the value is too big this method returns a carry (1)
03357     */
03358     uint  ToInt (unsigned int & result) const
03359     {
03360         return ToUInt (result);
03361     }
03362 
03363 
03364     /*!
03365         this method converts 'this' into 'result' (32 bit signed integer)
03366         ***this method is created only on a 64bit platform***
03367         if the value is too big this method returns a carry (1)
03368     */
03369     uint  ToInt (signed int & result) const
03370     {
03371     sint result_sint;
03372 
03373         uint  c = ToInt (result_sint);
03374         result = (signed int)result_sint;
03375 
03376         if( c || result_sint != sint(result) )
03377             return 1;
03378 
03379     return 0;
03380     }
03381 
03382 
03383     /*
03384         this method converts 32 bit unsigned int to this class
03385         ***this method is created only on a 64bit platform***
03386     */
03387     uint  FromUInt (unsigned int value)
03388     {
03389         return FromUInt (uint (value));
03390     }
03391 
03392 
03393     /*
03394         this method converts 32 bit unsigned int to this class
03395         ***this method is created only on a 64bit platform***
03396     */
03397     uint  FromInt (unsigned int value)
03398     {
03399         return FromUInt (uint (value));
03400     }
03401 
03402 
03403     /*
03404         this method converts 32 bit signed int to this class
03405         ***this method is created only on a 64bit platform***
03406     */
03407     uint  FromInt (signed int value)
03408     {
03409         return FromInt (sint(value));
03410     }
03411 
03412 
03413     /*!
03414         an operator= for converting 32 bit unsigned int to this class
03415         ***this operator is created only on a 64bit platform***
03416     */
03417     Big<exp, man> & operator= (unsigned int value)
03418     {
03419         FromUInt (value);
03420 
03421     return *this;
03422     }
03423 
03424 
03425     /*!
03426         a constructor for converting 32 bit unsigned int to this class
03427         ***this constructor is created only on a 64bit platform***
03428     */
03429     Big (unsigned int value)
03430     {
03431         FromUInt (value);
03432     }
03433 
03434 
03435     /*!
03436         an operator for converting 32 bit signed int to this class
03437         ***this operator is created only on a 64bit platform***
03438     */
03439     Big<exp, man> & operator= (signed int value)
03440     {
03441         FromInt (value);
03442 
03443     return *this;
03444     }
03445 
03446 
03447     /*!
03448         a constructor for converting 32 bit signed int to this class
03449         ***this constructor is created only on a 64bit platform***
03450     */
03451     Big (signed int value)
03452     {
03453         FromInt (value);
03454     }
03455 
03456 #endif
03457 
03458 
03459 private:
03460 
03461     /*!
03462         an auxiliary method for converting from UInt and Int
03463 
03464         we assume that there'll never be a carry here
03465         (we have an exponent and the value in Big can be bigger than
03466         that one from the UInt)
03467     */
03468     template<uint int_size>
03469     uint  FromUIntOrInt(const UInt<int_size> & value, sint compensation)
03470     {
03471         uint  minimum_size = (int_size < man)? int_size : man;
03472         exponent          = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation;
03473 
03474         // copying the highest words
03475         uint  i;
03476         for(i=1 ; i<=minimum_size ; ++i)
03477             mantissa.table [man-i] = value.table [int_size-i];
03478 
03479         // setting the rest of mantissa.table into zero (if some has left)
03480         for( ; i<=man ; ++i)
03481             mantissa.table [man-i] = 0;
03482 
03483         // the highest bit is either one or zero (when the whole mantissa is zero)
03484         // we can only call CorrectZero()
03485         CorrectZero();
03486 
03487     return 0;
03488     }
03489 
03490 
03491 public:
03492 
03493     /*!
03494         a method for converting from 'UInt<int_size>' to this class
03495     */
03496     template<uint int_size>
03497     uint  FromUInt (UInt<int_size> value)
03498     {
03499         info = 0;
03500         sint compensation = (sint)value.CompensationToLeft ();
03501     
03502     return FromUIntOrInt(value, compensation);
03503     }
03504 
03505 
03506     /*!
03507         a method for converting from 'UInt<int_size>' to this class
03508     */
03509     template<uint int_size>
03510     uint  FromInt (const UInt<int_size> & value)
03511     {
03512         return FromUInt (value);
03513     }
03514 
03515         
03516     /*!
03517         a method for converting from 'Int<int_size>' to this class
03518     */
03519     template<uint int_size>
03520     uint  FromInt (Int<int_size> value)
03521     {
03522         info = 0;
03523         bool is_sign = false;
03524 
03525         if( value.IsSign () )
03526         {
03527             value.ChangeSign ();
03528             is_sign = true;
03529         }
03530         
03531         sint compensation = (sint)value.CompensationToLeft ();
03532         FromUIntOrInt(value, compensation);
03533 
03534         if( is_sign )
03535             SetSign ();
03536 
03537     return 0;
03538     }
03539 
03540 
03541     /*!
03542         an operator= for converting from 'Int<int_size>' to this class
03543     */
03544     template<uint int_size>
03545     Big<exp,man> & operator= (const Int<int_size> & value)
03546     {
03547         FromInt (value);
03548 
03549     return *this;
03550     }
03551 
03552 
03553     /*!
03554         a constructor for converting from 'Int<int_size>' to this class
03555     */
03556     template<uint int_size>
03557     Big (const Int<int_size> & value)
03558     {
03559         FromInt (value);
03560     }
03561 
03562 
03563     /*!
03564         an operator= for converting from 'UInt<int_size>' to this class
03565     */
03566     template<uint int_size>
03567     Big<exp,man> & operator= (const UInt<int_size> & value)
03568     {
03569         FromUInt (value);
03570 
03571     return *this;
03572     }
03573 
03574 
03575     /*!
03576         a constructor for converting from 'UInt<int_size>' to this class
03577     */
03578     template<uint int_size>
03579     Big (const UInt<int_size> & value)
03580     {
03581         FromUInt (value);
03582     }
03583 
03584 
03585     /*!
03586         an operator= for converting from 'Big<another_exp, another_man>' to this class
03587     */
03588     template<uint another_exp, uint another_man>
03589     Big<exp,man> & operator= (const Big<another_exp, another_man> & value)
03590     {
03591         FromBig (value);
03592 
03593     return *this;
03594     }
03595 
03596 
03597     /*!
03598         a constructor for converting from 'Big<another_exp, another_man>' to this class
03599     */
03600     template<uint another_exp, uint another_man>
03601     Big (const Big<another_exp, another_man> & value)
03602     {
03603         FromBig (value);
03604     }
03605 
03606 
03607     /*!
03608         a default constructor
03609 
03610         by default we don't set any of the members to zero
03611         only NaN flag is set
03612 
03613         if you want the mantissa and exponent to be set to zero 
03614         define TTMATH_BIG_DEFAULT_CLEAR macro
03615         (useful for debug purposes)
03616     */
03617     Big ()
03618     {
03619         #ifdef TTMATH_BIG_DEFAULT_CLEAR
03620 
03621             SetZeroNan ();
03622 
03623         #else
03624 
03625             info = TTMATH_BIG_NAN;
03626             // we're directly setting 'info' (instead of calling SetNan())
03627             // in order to get rid of a warning saying that 'info' is uninitialized
03628 
03629         #endif
03630     }
03631 
03632 
03633     /*!
03634         a destructor
03635     */
03636     ~Big ()
03637     {
03638     }
03639 
03640 
03641     /*!
03642         the default assignment operator
03643     */
03644     Big<exp,man> & operator= (const Big<exp,man> & value)
03645     {
03646         info     = value.info;
03647         exponent = value.exponent;
03648         mantissa = value.mantissa;
03649 
03650     return *this;
03651     }
03652 
03653 
03654     /*!
03655         a constructor for copying from another object of this class
03656     */
03657     
03658     Big (const Big<exp,man> & value)
03659     {
03660         operator= (value);
03661     }
03662     
03663 
03664 
03665     /*!
03666         a method for converting into a string
03667         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03668 
03669         output:
03670             return value:
03671             0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
03672             1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
03673                 is somewhere an error in the library)
03674     */
03675     uint  ToString (    std::string & result,
03676                     uint  base         = 10,
03677                     bool scient       = false,
03678                     sint scient_from  = 15,
03679                     sint round        = -1,
03680                     bool trim_zeroes  = true,
03681                     char comma     = '.' ) const
03682     {
03683         Conv  conv;
03684 
03685         conv.base          = base;
03686         conv.scient        = scient;
03687         conv.scient_from   = scient_from;
03688         conv.round         = round;
03689         conv.trim_zeroes   = trim_zeroes;
03690         conv.comma         = static_cast<uint >(comma);
03691 
03692     return ToStringBase<std::string, char>(result, conv);
03693     }
03694 
03695 
03696     /*!
03697         a method for converting into a string
03698         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03699     */
03700     uint  ToString (std::string & result, const Conv  & conv) const
03701     {
03702         return ToStringBase<std::string, char>(result, conv);
03703     }
03704 
03705 
03706     /*!
03707         a method for converting into a string
03708         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03709     */
03710     std::string ToString (const Conv  & conv) const
03711     {
03712         std::string result;
03713         ToStringBase<std::string, char>(result, conv);
03714         
03715     return result;
03716     }
03717 
03718 
03719     /*!
03720         a method for converting into a string
03721         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03722     */
03723     std::string ToString (uint  base = 10) const
03724     {
03725         Conv  conv;
03726         conv.base  = base;
03727 
03728     return ToString (conv);
03729     }
03730 
03731 
03732 
03733 #ifndef TTMATH_DONT_USE_WCHAR
03734 
03735 
03736     /*!
03737         a method for converting into a string
03738         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03739     */
03740     uint  ToString (    std::wstring & result,
03741                     uint  base         = 10,
03742                     bool scient       = false,
03743                     sint scient_from  = 15,
03744                     sint round        = -1,
03745                     bool trim_zeroes  = true,
03746                     wchar_t comma     = '.' ) const
03747     {
03748         Conv  conv;
03749 
03750         conv.base          = base;
03751         conv.scient        = scient;
03752         conv.scient_from   = scient_from;
03753         conv.round         = round;
03754         conv.trim_zeroes   = trim_zeroes;
03755         conv.comma         = static_cast<uint >(comma);
03756 
03757     return ToStringBase<std::wstring, wchar_t>(result, conv);
03758     }
03759 
03760 
03761     /*!
03762         a method for converting into a string
03763         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03764     */
03765     uint  ToString (std::wstring & result, const Conv  & conv) const
03766     {
03767         return ToStringBase<std::wstring, wchar_t>(result, conv);
03768     }
03769 
03770 
03771     /*!
03772         a method for converting into a string
03773         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03774     */
03775     std::wstring ToWString (const Conv  & conv) const
03776     {
03777         std::wstring result;
03778         ToStringBase<std::wstring, wchar_t>(result, conv);
03779         
03780     return result;
03781     }
03782 
03783 
03784     /*!
03785         a method for converting into a string
03786         struct Conv is defined in ttmathtypes.h, look there for more information about parameters
03787     */
03788     std::wstring ToWString (uint  base = 10) const
03789     {
03790         Conv  conv;
03791         conv.base  = base;
03792 
03793     return ToWString (conv);
03794     }
03795 
03796 #endif
03797 
03798 
03799 
03800 private:
03801 
03802 
03803     /*!
03804         an auxiliary method for converting into the string
03805     */
03806     template<class string_type, class char_type>
03807     uint  ToStringBase(string_type & result, const Conv  & conv) const
03808     {
03809         static char error_overflow_msg[] = "overflow";
03810         static char error_nan_msg[]      = "NaN";
03811         result.erase();
03812 
03813         if( IsNan () )
03814         {
03815             Misc::AssignString (result, error_nan_msg);
03816             return 0;
03817         }
03818 
03819         if( conv.base <2 || conv.base >16 )
03820         {
03821             Misc::AssignString (result, error_overflow_msg);
03822             return 1;
03823         }
03824     
03825         if( IsZero () )
03826         {
03827             result = '0';
03828 
03829         return 0;
03830         }
03831 
03832         /*
03833             since 'base' is greater or equal 2 that 'new_exp' of type 'Int<exp>' should
03834             hold the new value of exponent but we're using 'Int<exp+1>' because
03835             if the value for example would be 'max()' then we couldn't show it
03836 
03837                 max() ->  11111111 * 2 ^ 11111111111  (bin)(the mantissa and exponent have all bits set)
03838                 if we were using 'Int<exp>' we couldn't show it in this format:
03839                 1,1111111 * 2 ^ 11111111111  (bin)
03840                 because we have to add something to the mantissa and because 
03841                 mantissa is full we can't do it and it'll be a carry
03842                 (look at ToString_SetCommaAndExponent(...))
03843 
03844                 when the base would be greater than two (for example 10) 
03845                 we could use 'Int<exp>' here
03846         */
03847         Int<exp+1> new_exp;
03848 
03849         if( ToString_CreateNewMantissaAndExponent<string_type, char_type>(result, conv, new_exp) )
03850         {
03851             Misc::AssignString (result, error_overflow_msg);
03852             return 1;
03853         }
03854 
03855             
03856         if( ToString_SetCommaAndExponent<string_type, char_type>(result, conv, new_exp) )
03857         {
03858             Misc::AssignString (result, error_overflow_msg);
03859             return 1;
03860         }
03861 
03862         if( IsSign () )
03863             result.insert(result.begin(), '-');
03864 
03865 
03866     // converted successfully
03867     return 0;
03868     }
03869 
03870 
03871 
03872     /*!
03873         in the method 'ToString_CreateNewMantissaAndExponent()' we're using 
03874         type 'Big<exp+1,man>' and we should have the ability to use some
03875         necessary methods from that class (methods which are private here)
03876     */
03877     friend class Big<exp-1,man>;
03878 
03879 
03880     /*!
03881         an auxiliary method for converting into the string
03882 
03883         input:
03884             base - the base in range <2,16>
03885 
03886         output:
03887             return values:
03888                 0 - ok
03889                 1 - if there was a carry
03890             new_man - the new mantissa for 'base'
03891             new_exp - the new exponent for 'base'
03892 
03893         mathematic part:
03894 
03895         the value is stored as:
03896             value = mantissa * 2^exponent
03897         we want to show 'value' as:
03898             value = new_man * base^new_exp
03899 
03900         then 'new_man' we'll print using the standard method from UInt<> type for printing
03901         and 'new_exp' is the offset of the comma operator in a system of a base 'base'
03902 
03903         value = mantissa * 2^exponent
03904         value = mantissa * 2^exponent * (base^new_exp / base^new_exp)
03905         value = mantissa * (2^exponent / base^new_exp) * base^new_exp
03906 
03907         look at the part (2^exponent / base^new_exp), there'll be good if we take
03908         a 'new_exp' equal that value when the (2^exponent / base^new_exp) will be equal one
03909 
03910         on account of the 'base' is not as power of 2 (can be from 2 to 16),
03911         this formula will not be true for integer 'new_exp' then in our case we take 
03912         'base^new_exp' _greater_ than '2^exponent' 
03913 
03914         if 'base^new_exp' were smaller than '2^exponent' the new mantissa could be
03915         greater than the max value of the container UInt<man>
03916 
03917         value = mantissa * (2^exponent / base^new_exp) * base^new_exp
03918           let M = mantissa * (2^exponent / base^new_exp) then
03919         value = M * base^new_exp
03920 
03921         in our calculation we treat M as floating value showing it as:
03922             M = mm * 2^ee where ee will be <= 0 
03923 
03924         next we'll move all bits of mm into the right when ee is equal zero
03925         abs(ee) must not be too big that only few bits from mm we can leave
03926 
03927         then we'll have:
03928             M = mmm * 2^0
03929         'mmm' is the new_man which we're looking for
03930 
03931 
03932         new_exp we calculate in this way:
03933             2^exponent <= base^new_exp
03934             new_exp >= log base (2^exponent)   <- logarithm with the base 'base' from (2^exponent)
03935             
03936             but we need new_exp as integer then we test:
03937             if new_exp is greater than zero and with fraction we add one to new_exp
03938               new_exp = new_exp + 1    (if new_exp>0 and with fraction)
03939             and at the end we take the integer part:
03940               new_exp = int(new_exp)
03941     */
03942     template<class string_type, class char_type>
03943     uint  ToString_CreateNewMantissaAndExponent(    string_type & new_man, const Conv  & conv,
03944                                                 Int<exp+1> & new_exp) const
03945     {
03946     uint  c = 0;
03947 
03948         if( conv.base <2 || conv.base >16 )
03949             return 1;
03950     
03951         // special method for base equal 2
03952         if( conv.base  == 2 )
03953             return ToString_CreateNewMantissaAndExponent_Base2(new_man, new_exp);
03954 
03955         // special method for base equal 4
03956         if( conv.base  == 4 )
03957             return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 2);
03958 
03959         // special method for base equal 8
03960         if( conv.base  == 8 )
03961             return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 3);
03962 
03963         // special method for base equal 16
03964         if( conv.base  == 16 )
03965             return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 4);
03966 
03967 
03968         // this = mantissa * 2^exponent
03969 
03970         // temp = +1 * 2^exponent  
03971         // we're using a bigger type than 'big<exp,man>' (look below)
03972         Big<exp+1,man> temp;
03973         temp.info = 0;
03974         temp.exponent = exponent;
03975         temp.mantissa.SetOne ();
03976         c += temp.Standardizing ();
03977 
03978         // new_exp_ = log base (2^exponent)   
03979         // if new_exp_ is positive and with fraction then we add one 
03980         Big<exp+1,man> new_exp_;
03981         c += new_exp_.ToString_Log(temp, conv.base ); // this logarithm isn't very complicated
03982 
03983         // rounding up to the nearest integer
03984         if( !new_exp_.IsInteger () )
03985         {
03986             if( !new_exp_.IsSign () )
03987                 c += new_exp_.AddOne(); // new_exp_ > 0 and with fraction
03988 
03989             new_exp_.SkipFraction ();
03990         }
03991 
03992         if( ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp) )
03993         {
03994             // in very rare cases there can be an overflow from ToString_CreateNewMantissaTryExponent
03995             // it means that new_exp_ was too small (the problem comes from floating point numbers precision)
03996             // so we increse new_exp_ and try again
03997             new_exp_.AddOne();
03998             c += ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp);
03999         }
04000 
04001     return (c==0)? 0 : 1;
04002     }
04003 
04004 
04005 
04006     /*!
04007         an auxiliary method for converting into the string
04008 
04009         trying to calculate new_man for given exponent (new_exp_)
04010         if there is a carry it can mean that new_exp_ is too small
04011     */
04012     template<class string_type, class char_type>
04013     uint  ToString_CreateNewMantissaTryExponent(    string_type & new_man, const Conv & conv,
04014                                                 const Big<exp+1,man> & new_exp_, Int<exp+1> & new_exp) const
04015     {
04016     uint  c = 0;
04017 
04018         // because 'base^new_exp' is >= '2^exponent' then 
04019         // because base is >= 2 then we've got:
04020         // 'new_exp_' must be smaller or equal 'new_exp'
04021         // and we can pass it into the Int<exp> type
04022         // (in fact we're using a greater type then it'll be ok)
04023         c += new_exp_.ToInt(new_exp);
04024 
04025         // base_ = base
04026         Big<exp+1,man> base_(conv.base);
04027 
04028         // base_ = base_ ^ new_exp_
04029         c += base_.Pow( new_exp_ ); // use new_exp_ so Pow(Big<> &) version will be used
04030         // if we hadn't used a bigger type than 'Big<exp,man>' then the result
04031         // of this formula 'Pow(...)' would have been with an overflow
04032 
04033         // temp = mantissa * 2^exponent / base_^new_exp_
04034         Big<exp+1,man> temp;
04035         temp.info = 0;
04036         temp.mantissa = mantissa;
04037         temp.exponent = exponent;
04038         c += temp.Div(base_);
04039 
04040         // moving all bits of the mantissa into the right 
04041         // (how many times to move depend on the exponent)
04042         c += temp.ToString_MoveMantissaIntoRight();
04043 
04044         // because we took 'new_exp' as small as it was
04045         // possible ([log base (2^exponent)] + 1) that after the division 
04046         // (temp.Div( base_ )) the value of exponent should be equal zero or 
04047         // minimum smaller than zero then we've got the mantissa which has 
04048         // maximum valid bits
04049         temp.mantissa.ToString(new_man, conv.base);
04050 
04051         if( IsInteger () )
04052         {
04053             // making sure the new mantissa will be without fraction (integer)
04054             ToString_CheckMantissaInteger<string_type, char_type>(new_man, new_exp);
04055         }
04056         else
04057         if( conv.base_round )
04058         {
04059             c += ToString_BaseRound<string_type, char_type>(new_man, conv, new_exp);
04060         }
04061 
04062     return (c==0)? 0 : 1;
04063     }
04064 
04065 
04066     /*!
04067         this method calculates the logarithm
04068         it is used by ToString_CreateNewMantissaAndExponent() method
04069 
04070         it's not too complicated
04071         because x=+1*2^exponent (mantissa is one) then during the calculation
04072         the Ln(x) will not be making the long formula from LnSurrounding1()
04073         and only we have to calculate 'Ln(base)' but it'll be calculated
04074         only once, the next time we will get it from the 'history'
04075 
04076         x is greater than 0
04077         base is in <2,16> range
04078     */
04079     uint  ToString_Log(const Big<exp,man> & x, uint  base)
04080     {
04081         TTMATH_REFERENCE_ASSERT( x )
04082         TTMATH_ASSERT( base>=2 && base<=16 )
04083 
04084         Big <exp,man> temp;
04085         temp.SetOne ();
04086 
04087         if( x == temp )
04088         {
04089             // log(1) is 0
04090             SetZero ();
04091 
04092         return 0;
04093         }
04094 
04095         // there can be only a carry
04096         // because the 'x' is in '1+2*exponent' form then 
04097         // the long formula from LnSurrounding1() will not be calculated
04098         // (LnSurrounding1() will return one immediately)
04099         uint  c = Ln (x);
04100 
04101         if( base==10 && man<=TTMATH_BUILTIN_VARIABLES_SIZE )
04102         {
04103             // for the base equal 10 we're using SetLn10() instead of calculating it
04104             // (only if we have the constant sufficient big)
04105             temp.SetLn10();
04106         }
04107         else
04108         {
04109             c += ToString_LogBase(base, temp);
04110         }
04111 
04112         c += Div ( temp );
04113 
04114     return (c==0)? 0 : 1;
04115     }
04116 
04117 
04118 #ifndef TTMATH_MULTITHREADS
04119 
04120     /*!
04121         this method calculates the logarithm of 'base'
04122         it's used in single thread environment
04123     */
04124     uint  ToString_LogBase(uint  base, Big<exp,man> & result)
04125     {
04126         TTMATH_ASSERT( base>=2 && base<=16 )
04127 
04128         // this guardians are initialized before the program runs (static POD types)
04129         static int guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
04130         static Big<exp,man> log_history[15];
04131         uint  index = base - 2;
04132         uint  c = 0;
04133     
04134         if( guardians[index] == 0 )
04135         {
04136             Big<exp,man> base_(base);
04137             c += log_history[index].Ln(base_);
04138             guardians[index] = 1;
04139         }
04140 
04141         result = log_history[index];
04142 
04143     return (c==0)? 0 : 1;
04144     }
04145 
04146 #else
04147 
04148     /*!
04149         this method calculates the logarithm of 'base'
04150         it's used in multi-thread environment
04151     */
04152     uint  ToString_LogBase(uint  base, Big<exp,man> & result)
04153     {
04154         TTMATH_ASSERT( base>=2 && base<=16 )
04155 
04156         // this guardians are initialized before the program runs (static POD types)
04157         volatile static sig_atomic_t guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
04158         static Big<exp,man> * plog_history;
04159         uint  index = base - 2;
04160         uint  c = 0;
04161     
04162         // double-checked locking
04163         if( guardians[index] == 0 )
04164         {
04165             ThreadLock thread_lock;
04166 
04167             // locking
04168             if( thread_lock.Lock() )
04169             {
04170                 static Big<exp,man> log_history[15];
04171 
04172                 if( guardians[index] == 0 )
04173                 {
04174                     plog_history = log_history;
04175                 
04176                     Big<exp,man> base_(base);
04177                     c += log_history[index].Ln(base_);
04178                     guardians[index] = 1;
04179                 }
04180             }
04181             else
04182             {
04183                 // there was a problem with locking, we store the result directly in 'result' object
04184                 Big<exp,man> base_(base);
04185                 c += result.Ln(base_);
04186                 
04187             return (c==0)? 0 : 1;
04188             }
04189 
04190             // automatically unlocking
04191         }
04192 
04193         result = plog_history[index];
04194 
04195     return (c==0)? 0 : 1;
04196     }
04197 
04198 #endif
04199 
04200     /*!
04201         an auxiliary method for converting into the string (private)
04202 
04203         this method moving all bits from mantissa into the right side
04204         the exponent tell us how many times moving (the exponent is <=0)
04205     */
04206     uint  ToString_MoveMantissaIntoRight()
04207     {
04208         if( exponent.IsZero() )
04209             return 0;
04210         
04211         // exponent can't be greater than zero
04212         // because we would cat the highest bits of the mantissa
04213         if( !exponent.IsSign() )
04214             return 1;
04215 
04216 
04217         if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
04218             // if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
04219             // it means that we must cut the whole mantissa
04220             // (there'll not be any of the valid bits)
04221             return 1;
04222 
04223         // e will be from (-man*TTMATH_BITS_PER_UINT, 0>
04224         sint e = -( exponent.ToInt() );
04225         mantissa.Rcr(e,0);
04226 
04227     return 0;
04228     }
04229 
04230 
04231     /*!
04232         a special method similar to the 'ToString_CreateNewMantissaAndExponent'
04233         when the 'base' is equal 2
04234 
04235         we use it because if base is equal 2 we don't have to make those
04236         complicated calculations and the output is directly from the source
04237         (there will not be any small distortions)
04238     */
04239     template<class string_type>
04240     uint  ToString_CreateNewMantissaAndExponent_Base2(    string_type & new_man,
04241                                                         Int<exp+1> & new_exp     ) const
04242     {
04243         for( sint i=man-1 ; i>=0 ; --i )
04244         {
04245             uint  value = mantissa.table[i]; 
04246 
04247             for( uint  bit=0 ; bit<TTMATH_BITS_PER_UINT ; ++bit )
04248             {
04249                 if( (value & TTMATH_UINT_HIGHEST_BIT) != 0 )
04250                     new_man += '1';
04251                 else
04252                     new_man += '0';
04253 
04254                 value <<= 1;
04255             }
04256         }
04257 
04258         new_exp = exponent;
04259 
04260     return 0;
04261     }
04262 
04263 
04264     /*!
04265         a special method used to calculate the new mantissa and exponent
04266         when the 'base' is equal 4, 8 or 16
04267 
04268         when base is 4 then bits is 2
04269         when base is 8 then bits is 3
04270         when base is 16 then bits is 4
04271         (and the algorithm can be used with a base greater than 16)
04272     */
04273     template<class string_type>
04274     uint  ToString_CreateNewMantissaAndExponent_BasePow2(    string_type & new_man,
04275                                                             Int<exp+1> & new_exp,
04276                                                             uint  bits) const
04277     {
04278         sint move;                            // how many times move the mantissa
04279         UInt<man+1> man_temp(mantissa);        // man+1 for moving
04280         new_exp = exponent;
04281         new_exp.DivInt((sint)bits, move);
04282 
04283         if( move != 0 )
04284         {
04285             // we're moving the man_temp to left-hand side
04286             if( move < 0 )
04287             {
04288                 move = sint(bits) + move;
04289                 new_exp.SubOne();            // when move is < than 0 then new_exp is < 0 too
04290             }
04291 
04292             man_temp.Rcl(move);
04293         }
04294 
04295 
04296         if( bits == 3 )
04297         {
04298             // base 8
04299             // now 'move' is greater than or equal 0
04300             uint  len = man*TTMATH_BITS_PER_UINT + move;
04301             return ToString_CreateNewMantissaAndExponent_Base8(new_man, man_temp, len, bits);
04302         }
04303         else
04304         {
04305             // base 4 or 16
04306             return ToString_CreateNewMantissaAndExponent_Base4or16(new_man, man_temp, bits);
04307         }
04308     }
04309 
04310 
04311     /*!
04312         a special method used to calculate the new mantissa
04313         when the 'base' is equal 8
04314 
04315         bits is always 3
04316 
04317         we can use this algorithm when the base is 4 or 16 too
04318         but we have a faster method ToString_CreateNewMantissaAndExponent_Base4or16()
04319     */
04320     template<class string_type>
04321     uint  ToString_CreateNewMantissaAndExponent_Base8(    string_type & new_man,
04322                                                         UInt<man+1> & man_temp,
04323                                                         uint  len,
04324                                                         uint  bits) const
04325     {
04326         uint  shift = TTMATH_BITS_PER_UINT - bits;
04327         uint  mask  = TTMATH_UINT_MAX_VALUE >> shift;
04328         uint  i;
04329 
04330         for( i=0 ; i<len ; i+=bits )
04331         {
04332             uint  digit = man_temp.table[0] & mask;
04333             new_man.insert(new_man.begin(), static_cast<char>(Misc::DigitToChar (digit)));
04334 
04335             man_temp.Rcr(bits);
04336         }
04337 
04338         TTMATH_ASSERT( man_temp.IsZero() )
04339 
04340     return 0;
04341     }
04342 
04343 
04344     /*!
04345         a special method used to calculate the new mantissa
04346         when the 'base' is equal 4 or 16
04347 
04348         when the base is equal 4 or 16 the bits is 2 or 4
04349         and because TTMATH_BITS_PER_UINT (32 or 64) is divisible by 2 (or 4)
04350         then we can get digits from the end of our mantissa
04351     */
04352     template<class string_type>
04353     uint  ToString_CreateNewMantissaAndExponent_Base4or16(    string_type & new_man,
04354                                                             UInt<man+1> & man_temp,
04355                                                             uint  bits) const
04356     {
04357         TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 2 == 0 )
04358         TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 4 == 0 )
04359 
04360         uint  shift = TTMATH_BITS_PER_UINT - bits;
04361         uint  mask  = TTMATH_UINT_MAX_VALUE << shift;
04362         uint  digit;
04363 
04364          // table[man] - last word - is different from zero if we moved man_temp
04365         digit = man_temp.table[man];
04366 
04367         if( digit != 0 )
04368             new_man += static_cast<char>(Misc::DigitToChar(digit));
04369 
04370 
04371         for( int i=man-1 ; i>=0 ; --i )
04372         {
04373             uint  shift_local = shift;
04374             uint  mask_local  = mask;
04375 
04376             while( mask_local != 0 )
04377             {
04378                 digit = man_temp.table[i] & mask_local;
04379 
04380                 if( shift_local != 0 )
04381                     digit = digit >> shift_local;
04382 
04383                 new_man    += static_cast<char>(Misc::DigitToChar (digit));
04384                 mask_local  = mask_local >> bits;
04385                 shift_local = shift_local - bits;
04386             }
04387         }
04388 
04389     return 0;
04390     }
04391 
04392 
04393     /*!
04394         an auxiliary method for converting into the string
04395     */
04396     template<class string_type, class char_type>
04397     bool ToString_RoundMantissaWouldBeInteger(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
04398     {
04399         // if new_exp is greater or equal to zero then we have an integer value,
04400         // if new_exp is equal -1 then we have only one digit after the comma
04401         // and after rounding it would be an integer value
04402         if( !new_exp.IsSign() || new_exp == -1 )
04403             return true;
04404 
04405         if( new_man.size() >= TTMATH_UINT_HIGHEST_BIT || new_man.size() < 2 )
04406             return true; // oops, the mantissa is too large for calculating (or too small) - we are not doing the base rounding
04407         
04408         uint  i = 0;
04409         char_type digit;
04410 
04411         if( new_exp >= -sint(new_man.size()) )
04412         {
04413             uint  new_exp_abs = -new_exp.ToInt();
04414             i = new_man.size() - new_exp_abs; // start from the first digit after the comma operator
04415         }
04416         
04417         if( Misc::CharToDigit (new_man[new_man.size()-1]) >= conv.base/2 )
04418         {
04419             if( new_exp < -sint(new_man.size()) )
04420             {
04421                 // there are some zeroes after the comma operator
04422                 // (between the comma and the first digit from the mantissa)
04423                 // and the result value will never be an integer
04424                 return false;
04425             }
04426 
04427             digit = static_cast<char_type>( Misc::DigitToChar (conv.base-1) );
04428         }
04429         else
04430         {
04431             digit = '0';
04432         }
04433 
04434         for( ; i < new_man.size()-1 ; ++i)
04435             if( new_man[i] != digit )
04436                 return false; // it will not be an integer
04437 
04438     return true; // it will be integer after rounding
04439     }
04440 
04441 
04442     /*!
04443         an auxiliary method for converting into the string
04444         (when this is integer)
04445 
04446         after floating point calculating the new mantissa can consist of some fraction
04447         so if our value is integer we should check the new mantissa
04448         (after the decimal point there should be only zeroes)
04449         
04450         often this is a last digit different from zero
04451         ToString_BaseRound would not get rid of it because the method make a test against 
04452         an integer value (ToString_RoundMantissaWouldBeInteger) and returns immediately
04453     */
04454     template<class string_type, class char_type>
04455     void ToString_CheckMantissaInteger(string_type & new_man, const Int<exp+1> & new_exp) const
04456     {
04457         if( !new_exp.IsSign() )
04458             return; // return if new_exp >= 0
04459         
04460         uint  i = 0;
04461         uint  man_size = new_man.size();
04462 
04463         if( man_size >= TTMATH_UINT_HIGHEST_BIT )
04464             return; // ops, the mantissa is too long
04465 
04466         sint sman_size = -sint(man_size);
04467 
04468         if( new_exp >= sman_size )
04469         {
04470             sint e = new_exp.ToInt();
04471             e = -e;
04472             // now e means how many last digits from the mantissa should be equal zero
04473 
04474             i = man_size - uint (e);
04475         }
04476 
04477         for( ; i<man_size ; ++i)
04478             new_man[i] = '0';
04479     }
04480 
04481 
04482     /*!
04483         an auxiliary method for converting into the string
04484 
04485         this method is used for base!=2, base!=4, base!=8 and base!=16
04486         we do the rounding when the value has fraction (is not an integer)
04487     */
04488     template<class string_type, class char_type>
04489     uint  ToString_BaseRound(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
04490     {
04491         // we must have minimum two characters
04492         if( new_man.size() < 2 )
04493             return 0;
04494 
04495         // assert that there will not be an integer after rounding
04496         if( ToString_RoundMantissaWouldBeInteger<string_type, char_type>(new_man, conv, new_exp) )
04497             return 0;
04498 
04499         typename string_type::size_type i = new_man.length() - 1;
04500 
04501         // we're erasing the last character
04502         uint  digit = Misc::CharToDigit ( new_man[i] );
04503         new_man.erase(i, 1);
04504         uint  c = new_exp.AddOne();
04505 
04506         // if the last character is greater or equal 'base/2'
04507         // we are adding one into the new mantissa
04508         if( digit >= conv.base / 2 )
04509             ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
04510 
04511     return c;
04512     }
04513     
04514 
04515     /*!
04516         an auxiliary method for converting into the string
04517 
04518         this method addes one into the new mantissa
04519     */
04520     template<class string_type, class char_type>
04521     void ToString_RoundMantissa_AddOneIntoMantissa(string_type & new_man, const Conv & conv) const
04522     {
04523         if( new_man.empty() )
04524             return;
04525 
04526         sint i = sint( new_man.length() ) - 1;
04527         bool was_carry = true;
04528 
04529         for( ; i>=0 && was_carry ; --i )
04530         {
04531             // we can have the comma as well because
04532             // we're using this method later in ToString_CorrectDigitsAfterComma_Round()
04533             // (we're only ignoring it)
04534             if( new_man[i] == static_cast<char_type>(conv.comma) )
04535                 continue;
04536 
04537             // we're adding one
04538             uint  digit = Misc::CharToDigit ( new_man[i] ) + 1;
04539 
04540             if( digit == conv.base )
04541                 digit = 0;
04542             else
04543                 was_carry = false;
04544 
04545             new_man[i] = static_cast<char_type>( Misc::DigitToChar (digit) );
04546         }
04547 
04548         if( i<0 && was_carry )
04549             new_man.insert( new_man.begin() , '1' );
04550     }
04551 
04552 
04553 
04554     /*!
04555         an auxiliary method for converting into the string
04556 
04557         this method sets the comma operator and/or puts the exponent
04558         into the string
04559     */
04560     template<class string_type, class char_type>
04561     uint  ToString_SetCommaAndExponent(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
04562     {
04563     uint  carry = 0;
04564 
04565         if( new_man.empty() )
04566             return carry;
04567 
04568         Int<exp+1> scientific_exp( new_exp );
04569 
04570         // 'new_exp' depends on the 'new_man' which is stored like this e.g:
04571         //  32342343234 (the comma is at the end)
04572         // we'd like to show it in this way:
04573         //  3.2342343234 (the 'scientific_exp' is connected with this example)
04574 
04575         sint offset = sint( new_man.length() ) - 1;
04576         carry += scientific_exp.Add( offset );
04577         // there shouldn't have been a carry because we're using
04578         // a greater type -- 'Int<exp+1>' instead of 'Int<exp>'
04579 
04580         bool print_scientific = conv.scient;
04581 
04582         if( !print_scientific )
04583         {
04584             if( scientific_exp > conv.scient_from || scientific_exp < -sint(conv.scient_from) )
04585                 print_scientific = true;
04586         }
04587 
04588         if( !print_scientific )
04589             ToString_SetCommaAndExponent_Normal<string_type, char_type>(new_man, conv, new_exp);
04590         else
04591             // we're passing the 'scientific_exp' instead of 'new_exp' here
04592             ToString_SetCommaAndExponent_Scientific<string_type, char_type>(new_man, conv, scientific_exp);
04593 
04594     return (carry==0)? 0 : 1;
04595     }
04596 
04597 
04598     /*!
04599         an auxiliary method for converting into the string
04600     */
04601     template<class string_type, class char_type>
04602     void ToString_SetCommaAndExponent_Normal(string_type & new_man,    const Conv & conv, Int<exp+1> & new_exp ) const
04603     {
04604         if( !new_exp.IsSign() ) // it means: if( new_exp >= 0 )
04605             ToString_SetCommaAndExponent_Normal_AddingZero<string_type, char_type>(new_man, new_exp);
04606         else
04607             ToString_SetCommaAndExponent_Normal_SetCommaInside<string_type, char_type>(new_man, conv, new_exp);
04608 
04609 
04610         ToString_Group_man<string_type, char_type>(new_man, conv);
04611     }
04612 
04613 
04614     /*!
04615         an auxiliary method for converting into the string
04616     */
04617     template<class string_type, class char_type>
04618     void ToString_SetCommaAndExponent_Normal_AddingZero(string_type & new_man,
04619                                                         Int<exp+1> & new_exp) const
04620     {
04621         // we're adding zero characters at the end
04622         // 'i' will be smaller than 'when_scientific' (or equal)
04623         uint  i = new_exp.ToInt();
04624         
04625         if( new_man.length() + i > new_man.capacity() )
04626             // about 6 characters more (we'll need it for the comma or something)
04627             new_man.reserve( new_man.length() + i + 6 );
04628         
04629         for( ; i>0 ; --i)
04630             new_man += '0';
04631     }
04632 
04633 
04634     /*!
04635         an auxiliary method for converting into the string
04636     */
04637     template<class string_type, class char_type>
04638     void ToString_SetCommaAndExponent_Normal_SetCommaInside(
04639                                                             string_type & new_man,
04640                                                             const Conv & conv,
04641                                                             Int<exp+1> & new_exp ) const
04642     {
04643         // new_exp is < 0 
04644 
04645         sint new_man_len = sint(new_man.length()); // 'new_man_len' with a sign
04646         sint e = -( new_exp.ToInt() ); // 'e' will be positive
04647 
04648         if( new_exp > -new_man_len )
04649         {
04650             // we're setting the comma within the mantissa
04651             
04652             sint index = new_man_len - e;
04653             new_man.insert( new_man.begin() + index, static_cast<char_type>(conv.comma));
04654         }
04655         else
04656         {
04657             // we're adding zero characters before the mantissa
04658 
04659             uint  how_many = e - new_man_len;
04660             string_type man_temp(how_many+1, '0');
04661 
04662             man_temp.insert( man_temp.begin()+1, static_cast<char_type>(conv.comma));
04663             new_man.insert(0, man_temp);
04664         }
04665 
04666         ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
04667     }
04668 
04669 
04670     /*!
04671         an auxiliary method for converting into the string
04672     */
04673     template<class string_type, class char_type>
04674     void ToString_SetCommaAndExponent_Scientific(    string_type & new_man,
04675                                                     const Conv & conv,
04676                                                     Int<exp+1> & scientific_exp ) const
04677     {
04678         if( new_man.empty() )
04679             return;
04680         
04681         if( new_man.size() > 1 )
04682         {
04683             new_man.insert( new_man.begin()+1, static_cast<char_type>(conv.comma) );
04684             ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
04685         }
04686 
04687         ToString_Group_man<string_type, char_type>(new_man, conv);
04688 
04689         if( conv.base == 10 )
04690         {
04691             new_man += 'e';
04692 
04693             if( !scientific_exp.IsSign() )
04694                 new_man += '+';
04695         }
04696         else
04697         {
04698             // the 10 here is meant as the base 'base'
04699             // (no matter which 'base' we're using there'll always be 10 here)
04700             Misc::AddString (new_man, "*10^");
04701         }
04702 
04703         string_type temp_exp;
04704         scientific_exp.ToString( temp_exp, conv.base );
04705 
04706         new_man += temp_exp;
04707     }
04708 
04709 
04710     /*!
04711         an auxiliary method for converting into the string
04712     */
04713     template<class string_type, class char_type>
04714     void ToString_Group_man(string_type & new_man, const Conv & conv) const
04715     {
04716         typedef typename string_type::size_type StrSize;
04717 
04718         if( conv.group == 0 )
04719             return;
04720 
04721         // first we're looking for the comma operator
04722         StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
04723 
04724         if( index == string_type::npos )
04725             index = new_man.size();    
04726 
04727         ToString_Group_man_before_comma<string_type, char_type>(new_man, conv, index);
04728         ToString_Group_man_after_comma<string_type, char_type>(new_man, conv, index+1);
04729     }
04730 
04731 
04732 
04733     /*!
04734         an auxiliary method for converting into the string
04735     */
04736     template<class string_type, class char_type>
04737     void ToString_Group_man_before_comma(    string_type & new_man, const Conv & conv,
04738                                             typename string_type::size_type & index) const
04739     {
04740     typedef typename string_type::size_type StrSize;
04741 
04742         uint  group = 0;
04743         StrSize i = index;
04744         uint  group_digits = conv.group_digits;
04745 
04746         if( group_digits < 1 )
04747             group_digits = 1;
04748 
04749         // adding group characters before the comma operator
04750         // i>0 because on the first position we don't put any additional grouping characters
04751         for( ; i>0 ; --i, ++group)
04752         {
04753             if( group >= group_digits )
04754             {
04755                 group = 0;
04756                 new_man.insert(i, 1, static_cast<char_type>(conv.group));
04757                 ++index;
04758             }
04759         }
04760     }
04761 
04762 
04763     /*!
04764         an auxiliary method for converting into the string
04765     */
04766     template<class string_type, class char_type>
04767     void ToString_Group_man_after_comma(string_type & new_man, const Conv & conv,
04768                                         typename string_type::size_type index) const
04769     {
04770         uint  group = 0;
04771         uint  group_digits = conv.group_digits;
04772 
04773         if( group_digits < 1 )
04774             group_digits = 1;
04775 
04776         for( ; index<new_man.size() ; ++index, ++group)
04777         {
04778             if( group >= group_digits )
04779             {
04780                 group = 0;
04781                 new_man.insert(index, 1, static_cast<char_type>(conv.group));
04782                 ++index;
04783             }
04784         }
04785     }
04786 
04787 
04788     /*!
04789         an auxiliary method for converting into the string
04790     */
04791     template<class string_type, class char_type>
04792     void ToString_CorrectDigitsAfterComma(    string_type & new_man,
04793                                             const Conv & conv ) const
04794     {
04795         if( conv.round >= 0 )
04796             ToString_CorrectDigitsAfterComma_Round<string_type, char_type>(new_man, conv);
04797 
04798         if( conv.trim_zeroes )
04799             ToString_CorrectDigitsAfterComma_CutOffZeroCharacters<string_type, char_type>(new_man, conv);
04800     }
04801 
04802 
04803     /*!
04804         an auxiliary method for converting into the string
04805     */
04806     template<class string_type, class char_type>
04807     void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
04808                                                 string_type & new_man,
04809                                                 const Conv & conv) const
04810     {
04811         // minimum two characters
04812         if( new_man.length() < 2 )
04813             return;
04814 
04815         // we're looking for the index of the last character which is not zero
04816         uint  i = uint ( new_man.length() ) - 1;
04817         for( ; i>0 && new_man[i]=='0' ; --i );
04818 
04819         // if there is another character than zero at the end
04820         // we're finishing
04821         if( i == new_man.length() - 1 )
04822             return;
04823 
04824         // we must have a comma 
04825         // (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
04826         // which is called before)
04827         if( new_man.find_last_of(static_cast<char_type>(conv.comma), i) == string_type::npos )
04828             return;
04829 
04830         // if directly before the first zero is the comma operator
04831         // we're cutting it as well
04832         if( i>0 && new_man[i]==static_cast<char_type>(conv.comma) )
04833             --i;
04834 
04835         new_man.erase(i+1, new_man.length()-i-1);
04836     }
04837 
04838 
04839     /*!
04840         an auxiliary method for converting into the string
04841     */
04842     template<class string_type, class char_type>
04843     void ToString_CorrectDigitsAfterComma_Round(
04844                                             string_type & new_man,
04845                                             const Conv & conv ) const
04846     {
04847         typedef typename string_type::size_type StrSize;
04848 
04849         // first we're looking for the comma operator
04850         StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
04851 
04852         if( index == string_type::npos )
04853             // nothing was found (actually there can't be this situation)
04854             return;
04855 
04856         // we're calculating how many digits there are at the end (after the comma)
04857         // 'after_comma' will be greater than zero because at the end
04858         // we have at least one digit
04859         StrSize after_comma = new_man.length() - index - 1;
04860 
04861         // if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
04862         // we don't have anything for cutting
04863         if( static_cast<StrSize>(conv.round) >= after_comma )
04864             return;
04865 
04866         uint  last_digit = Misc::CharToDigit ( new_man[ index + conv.round + 1 ], conv.base );
04867 
04868         // we're cutting the rest of the string
04869         new_man.erase(index + conv.round + 1, after_comma - conv.round);
04870 
04871         if( conv.round == 0 )
04872         {
04873             // we're cutting the comma operator as well
04874             // (it's not needed now because we've cut the whole rest after the comma)
04875             new_man.erase(index, 1);
04876         }
04877 
04878         if( last_digit >= conv.base / 2 )
04879             // we must round here
04880             ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
04881     }
04882 
04883 
04884 
04885 public:
04886 
04887     /*!
04888         a method for converting a string into its value
04889 
04890         it returns 1 if the value is too big -- we cannot pass it into the range
04891         of our class Big<exp,man> (or if the base is incorrect)
04892 
04893         that means only digits before the comma operator can make this value too big, 
04894         all digits after the comma we can ignore
04895 
04896         'source' - pointer to the string for parsing
04897 
04898         if 'after_source' is set that when this method finishes
04899         it sets the pointer to the new first character after parsed value
04900 
04901         'value_read' - if the pointer is provided that means the value_read will be true
04902         only when a value has been actually read, there can be situation where only such
04903         a string '-' or '+' will be parsed -- 'after_source' will be different from 'source' but
04904         no value has been read (there are no digits)
04905         on other words if 'value_read' is true -- there is at least one digit in the string
04906     */
04907     uint  FromString (const char * source, uint  base = 10, const char ** after_source = 0, bool * value_read = 0)
04908     {
04909         Conv  conv;
04910         conv.base  = base;
04911 
04912         return FromStringBase(source, conv, after_source, value_read);
04913     }
04914 
04915 
04916     /*!
04917         a method for converting a string into its value
04918     */
04919     uint  FromString (const char * source, const Conv  & conv, const char ** after_source = 0, bool * value_read = 0)
04920     {
04921         return FromStringBase(source, conv, after_source, value_read);
04922     }
04923 
04924 
04925     /*!
04926         a method for converting a string into its value        
04927     */
04928     uint  FromString (const std::string & string, uint  base = 10, const char ** after_source = 0, bool * value_read = 0)
04929     {
04930         return FromString (string.c_str(), base, after_source, value_read);
04931     }
04932 
04933 
04934     /*!
04935         a method for converting a string into its value        
04936     */
04937     uint  FromString (const std::string & string, const Conv  & conv, const char ** after_source = 0, bool * value_read = 0)
04938     {
04939         return FromString (string.c_str(), conv, after_source, value_read);
04940     }
04941 
04942 
04943 #ifndef TTMATH_DONT_USE_WCHAR
04944 
04945     /*!
04946         a method for converting a string into its value
04947     */
04948     uint  FromString (const wchar_t * source, uint  base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
04949     {
04950         Conv  conv;
04951         conv.base  = base;
04952 
04953         return FromStringBase(source, conv, after_source, value_read);
04954     }
04955 
04956 
04957     /*!
04958         a method for converting a string into its value
04959     */
04960     uint  FromString (const wchar_t * source, const Conv  & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
04961     {
04962         return FromStringBase(source, conv, after_source, value_read);
04963     }
04964 
04965 
04966     /*!
04967         a method for converting a string into its value        
04968     */
04969     uint  FromString (const std::wstring & string, uint  base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
04970     {
04971         return FromString (string.c_str(), base, after_source, value_read);
04972     }
04973 
04974 
04975     /*!
04976         a method for converting a string into its value        
04977     */
04978     uint  FromString (const std::wstring & string, const Conv  & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
04979     {
04980         return FromString (string.c_str(), conv, after_source, value_read);
04981     }
04982 
04983 #endif
04984 
04985 
04986 private:
04987 
04988 
04989     /*!
04990         an auxiliary method for converting from a string
04991     */
04992     template<class char_type>
04993     uint  FromStringBase(const char_type * source, const Conv  & conv, const char_type ** after_source = 0, bool * value_read = 0)
04994     {
04995     bool is_sign;
04996     bool value_read_temp = false;
04997 
04998         if( conv.base <2 || conv.base >16 )
04999         {
05000             SetNan ();
05001 
05002             if( after_source )
05003                 *after_source = source;
05004 
05005             if( value_read )
05006                 *value_read = value_read_temp;
05007 
05008             return 1;
05009         }
05010 
05011         SetZero ();
05012         FromString_TestSign( source, is_sign );
05013 
05014         uint  c = FromString_ReadPartBeforeComma( source, conv, value_read_temp );
05015 
05016         if( FromString_TestCommaOperator(source, conv) )
05017             c += FromString_ReadPartAfterComma( source, conv, value_read_temp );
05018 
05019         if( value_read_temp && conv.base  == 10 )
05020             c += FromString_ReadScientificIfExists( source );
05021 
05022         if( is_sign && !IsZero () )
05023             ChangeSign ();
05024 
05025         if( after_source )
05026             *after_source = source;
05027 
05028         if( value_read )
05029             *value_read = value_read_temp;
05030 
05031     return CheckCarry (c);
05032     }
05033 
05034 
05035     /*!
05036         we're testing whether the value is with the sign
05037 
05038         (this method is used from 'FromString_ReadPartScientific' too)
05039     */
05040     template<class char_type>
05041     void FromString_TestSign( const char_type * & source, bool & is_sign )
05042     {
05043         Misc::SkipWhiteCharacters(source);
05044 
05045         is_sign = false;
05046 
05047         if( *source == '-' )
05048         {
05049             is_sign = true;
05050             ++source;
05051         }
05052         else
05053         if( *source == '+' )
05054         {
05055             ++source;
05056         }
05057     }
05058 
05059 
05060     /*!
05061         we're testing whether there's a comma operator
05062     */
05063     template<class char_type>
05064     bool FromString_TestCommaOperator(const char_type * & source, const Conv & conv)
05065     {
05066         if( (*source == static_cast<char_type>(conv.comma)) || 
05067             (*source == static_cast<char_type>(conv.comma2) && conv.comma2 != 0 ) )
05068         {
05069             ++source;
05070 
05071         return true;
05072         }
05073 
05074     return false;
05075     }
05076 
05077 
05078     /*!
05079         this method reads the first part of a string
05080         (before the comma operator)
05081     */
05082     template<class char_type>
05083     uint  FromString_ReadPartBeforeComma( const char_type * & source, const Conv & conv, bool & value_read )
05084     {
05085         sint character;
05086         Big<exp, man> temp;
05087         Big<exp, man> base_( conv.base );
05088         
05089         Misc::SkipWhiteCharacters( source );
05090 
05091         for( ; true ; ++source )
05092         {
05093             if( conv.group!=0 && *source==static_cast<char>(conv.group) )
05094                 continue;
05095 
05096             character = Misc::CharToDigit (*source, conv.base);
05097 
05098             if( character == -1 )
05099                 break;
05100 
05101             value_read = true;
05102             temp = character;
05103 
05104             if( Mul (base_) )
05105                 return 1;
05106 
05107             if( Add (temp) )
05108                 return 1;
05109         }
05110 
05111     return 0;
05112     }
05113 
05114 
05115     /*!
05116         this method reads the second part of a string
05117         (after the comma operator)
05118     */
05119     template<class char_type>
05120     uint  FromString_ReadPartAfterComma( const char_type * & source, const Conv & conv, bool & value_read )
05121     {
05122     sint character;
05123     uint  c = 0, power = 0;
05124     UInt<1> power_;
05125     Big<exp, man> sum, base_(conv.base);
05126 
05127         // we don't remove any white characters here
05128         sum.SetZero();
05129 
05130         for( ; sum.exponent.IsSign() || sum.exponent.IsZero() ; ++source )
05131         {
05132             if( conv.group!=0 && *source==static_cast<char>(conv.group) )
05133                 continue;
05134             
05135             character = Misc::CharToDigit (*source, conv.base);
05136 
05137             if( character == -1 )
05138                 break;
05139 
05140             value_read = true;
05141 
05142             // there actually shouldn't be a carry here
05143             c += sum.Mul(base_);
05144             c += sum.Add(character);
05145             power += 1;
05146 
05147             if( power == 0 )
05148                 c += 1;
05149         }
05150 
05151         // we could break the parsing somewhere in the middle of the string,
05152         // but the result (value) still can be good
05153         // we should set a correct value of 'source' now
05154         for( ; Misc::CharToDigit (*source, conv.base) != -1 ; ++source );
05155 
05156         power_ = power;
05157         c += base_.Pow(power_);
05158         c += sum.Div(base_);
05159         c += Add (sum);
05160 
05161     return (c==0)? 0 : 1;
05162     }
05163 
05164 
05165     /*!
05166         this method checks whether there is a scientific part: [e|E][-|+]value
05167 
05168         it is called when the base is 10 and some digits were read before
05169     */
05170     template<class char_type>
05171     uint  FromString_ReadScientificIfExists(const char_type * & source)
05172     {
05173     uint  c = 0;
05174 
05175         bool scientific_read = false;
05176         const char_type * before_scientific = source;
05177 
05178         if( FromString_TestScientific(source) )
05179             c += FromString_ReadPartScientific( source, scientific_read );
05180 
05181         if( !scientific_read )
05182             source = before_scientific;
05183 
05184     return (c==0)? 0 : 1;
05185     }
05186 
05187 
05188 
05189     /*!
05190         we're testing whether is there the character 'e'
05191 
05192         this character is only allowed when we're using the base equals 10
05193     */
05194     template<class char_type>
05195     bool FromString_TestScientific(const char_type * & source)
05196     {
05197         Misc::SkipWhiteCharacters(source);
05198 
05199         if( *source=='e' || *source=='E' )
05200         {
05201             ++source;
05202 
05203         return true;
05204         }
05205 
05206     return false;
05207     }
05208 
05209 
05210     /*!
05211         this method reads the exponent (after 'e' character) when there's a scientific
05212         format of value and only when we're using the base equals 10
05213     */
05214     template<class char_type>
05215     uint  FromString_ReadPartScientific( const char_type * & source, bool & scientific_read )
05216     {
05217     uint  c = 0;
05218     Big<exp, man> new_exponent, temp;
05219     bool was_sign = false;
05220 
05221         FromString_TestSign( source, was_sign );
05222         c += FromString_ReadPartScientific_ReadExponent( source, new_exponent, scientific_read );
05223 
05224         if( scientific_read )
05225         {
05226             if( was_sign )
05227                 new_exponent.ChangeSign();
05228 
05229             temp = 10;
05230             c += temp.Pow( new_exponent );
05231             c += Mul (temp);
05232         }
05233 
05234     return (c==0)? 0 : 1;
05235     }
05236 
05237 
05238     /*!
05239         this method reads the value of the extra exponent when scientific format is used
05240         (only when base == 10)
05241     */
05242     template<class char_type>
05243     uint  FromString_ReadPartScientific_ReadExponent( const char_type * & source, Big<exp, man> & new_exponent, bool & scientific_read )
05244     {
05245     sint character;
05246     Big<exp, man> base, temp;
05247 
05248         Misc::SkipWhiteCharacters(source);
05249 
05250         new_exponent.SetZero();
05251         base = 10;
05252 
05253         for( ; (character=Misc::CharToDigit (*source, 10)) != -1 ; ++source )
05254         {
05255             scientific_read = true;
05256 
05257             temp = character;
05258 
05259             if( new_exponent.Mul(base) )
05260                 return 1;
05261 
05262             if( new_exponent.Add(temp) )
05263                 return 1;
05264         }
05265 
05266     return 0;
05267     }
05268 
05269 
05270 public:
05271 
05272 
05273     /*!
05274         a constructor for converting a string into this class
05275     */
05276     Big (const char * string)
05277     {
05278         FromString ( string );
05279     }
05280 
05281 
05282     /*!
05283         a constructor for converting a string into this class
05284     */
05285     Big (const std::string & string)
05286     {
05287         FromString ( string.c_str() );
05288     }
05289 
05290 
05291     /*!
05292         an operator= for converting a string into its value
05293     */
05294     Big<exp, man> & operator= (const char * string)
05295     {
05296         FromString ( string );
05297 
05298     return *this;
05299     }
05300 
05301 
05302     /*!
05303         an operator= for converting a string into its value
05304     */
05305     Big<exp, man> & operator= (const std::string & string)
05306     {
05307         FromString ( string.c_str() );
05308 
05309     return *this;
05310     }
05311 
05312 
05313 
05314 #ifndef TTMATH_DONT_USE_WCHAR
05315 
05316     /*!
05317         a constructor for converting a string into this class
05318     */
05319     Big (const wchar_t * string)
05320     {
05321         FromString ( string );
05322     }
05323 
05324 
05325     /*!
05326         a constructor for converting a string into this class
05327     */
05328     Big (const std::wstring & string)
05329     {
05330         FromString ( string.c_str() );
05331     }
05332 
05333 
05334     /*!
05335         an operator= for converting a string into its value
05336     */
05337     Big<exp, man> & operator= (const wchar_t * string)
05338     {
05339         FromString ( string );
05340 
05341     return *this;
05342     }
05343 
05344 
05345     /*!
05346         an operator= for converting a string into its value
05347     */
05348     Big<exp, man> & operator= (const std::wstring & string)
05349     {
05350         FromString ( string.c_str() );
05351 
05352     return *this;
05353     }
05354 
05355 
05356 #endif
05357 
05358 
05359 
05360     /*!
05361     *
05362     *    methods for comparing
05363     *
05364     */
05365 
05366 
05367     /*!
05368         this method performs the formula 'abs(this) < abs(ss2)'
05369         and returns the result
05370 
05371         (in other words it treats 'this' and 'ss2' as values without a sign)
05372         we don't check the NaN flag
05373     */
05374     bool SmallerWithoutSignThan (const Big<exp,man> & ss2) const
05375     {
05376         if( IsZero () )
05377         {
05378             if( ss2.IsZero () )
05379                 // we've got two zeroes
05380                 return false;
05381             else
05382                 // this==0 and ss2!=0
05383                 return true;
05384         }
05385 
05386         if( ss2.IsZero () )
05387             // this!=0 and ss2==0
05388             return false;
05389 
05390         // we're using the fact that all bits in mantissa are pushed
05391         // into the left side -- Standardizing()
05392         if( exponent == ss2.exponent )
05393             return mantissa < ss2.mantissa;
05394 
05395     return exponent < ss2.exponent;
05396     }
05397 
05398 
05399     /*!
05400         this method performs the formula 'abs(this) > abs(ss2)'
05401         and returns the result
05402 
05403         (in other words it treats 'this' and 'ss2' as values without a sign)
05404         we don't check the NaN flag
05405     */
05406     bool GreaterWithoutSignThan (const Big<exp,man> & ss2) const
05407     {
05408         if( IsZero () )
05409         {
05410             if( ss2.IsZero () )
05411                 // we've got two zeroes
05412                 return false;
05413             else
05414                 // this==0 and ss2!=0
05415                 return false;
05416         }
05417 
05418         if( ss2.IsZero () )
05419             // this!=0 and ss2==0
05420             return true;
05421 
05422         // we're using the fact that all bits in mantissa are pushed
05423         // into the left side -- Standardizing()
05424         if( exponent == ss2.exponent )
05425             return mantissa > ss2.mantissa;
05426 
05427     return exponent > ss2.exponent;
05428     }
05429 
05430 
05431     /*!
05432         this method performs the formula 'abs(this) == abs(ss2)'
05433         and returns the result
05434 
05435         (in other words it treats 'this' and 'ss2' as values without a sign)
05436         we don't check the NaN flag
05437     */
05438     bool EqualWithoutSign (const Big<exp,man> & ss2) const
05439     {
05440         if( IsZero () )
05441         {
05442             if( ss2.IsZero () )
05443                 // we've got two zeroes
05444                 return true;
05445             else
05446                 // this==0 and ss2!=0
05447                 return false;
05448         }
05449 
05450         if( ss2.IsZero () )
05451             // this!=0 and ss2==0
05452             return false;
05453 
05454         if( exponent==ss2.exponent && mantissa==ss2.mantissa )
05455             return true;
05456 
05457     return false;
05458     }
05459 
05460 
05461     bool operator<(const Big<exp,man> & ss2) const
05462     {
05463         if( IsSign () && !ss2.IsSign () )
05464             // this<0 and ss2>=0
05465             return true;
05466 
05467         if( !IsSign () && ss2.IsSign () )
05468             // this>=0 and ss2<0
05469             return false;
05470 
05471         // both signs are the same
05472 
05473         if( IsSign () )
05474             return ss2.SmallerWithoutSignThan ( *this );
05475 
05476     return SmallerWithoutSignThan ( ss2 );
05477     }
05478 
05479 
05480     bool operator==(const Big<exp,man> & ss2) const
05481     {
05482         if( IsSign () != ss2.IsSign() )
05483             return false;
05484 
05485     return EqualWithoutSign ( ss2 );
05486     }
05487 
05488 
05489     bool operator>(const Big<exp,man> & ss2) const
05490     {
05491         if( IsSign () && !ss2.IsSign() )
05492             // this<0 and ss2>=0
05493             return false;
05494 
05495         if( !IsSign () && ss2.IsSign() )
05496             // this>=0 and ss2<0
05497             return true;
05498 
05499         // both signs are the same
05500 
05501         if( IsSign () )
05502             return ss2.GreaterWithoutSignThan( *this );
05503 
05504     return GreaterWithoutSignThan ( ss2 );
05505     }
05506 
05507 
05508     bool operator>=(const Big<exp,man> & ss2) const
05509     {
05510         return !operator<( ss2 );
05511     }
05512 
05513 
05514     bool operator<=(const Big<exp,man> & ss2) const
05515     {
05516         return !operator>( ss2 );
05517     }
05518 
05519 
05520     bool operator!=(const Big<exp,man> & ss2) const
05521     {
05522         return !operator==(ss2);
05523     }
05524 
05525 
05526 
05527 
05528 
05529     /*!
05530     *
05531     *    standard mathematical operators 
05532     *
05533     */
05534 
05535 
05536     /*!
05537         an operator for changing the sign
05538 
05539         this method is not changing 'this' but the changed value is returned
05540     */
05541     Big<exp,man> operator- () const
05542     {
05543         Big<exp,man> temp(*this);
05544 
05545         temp.ChangeSign ();
05546 
05547     return temp;
05548     }
05549 
05550 
05551     Big<exp,man> operator- (const Big<exp,man> & ss2) const
05552     {
05553     Big<exp,man> temp(*this);
05554 
05555         temp.Sub(ss2);
05556 
05557     return temp;
05558     }
05559 
05560     Big<exp,man> & operator-=(const Big<exp,man> & ss2)
05561     {
05562         Sub (ss2);
05563 
05564     return *this;
05565     }
05566 
05567 
05568     Big<exp,man> operator+(const Big<exp,man> & ss2) const
05569     {
05570     Big<exp,man> temp(*this);
05571 
05572         temp.Add(ss2);
05573 
05574     return temp;
05575     }
05576 
05577 
05578     Big<exp,man> & operator+=(const Big<exp,man> & ss2)
05579     {
05580         Add (ss2);
05581 
05582     return *this;
05583     }
05584 
05585 
05586     Big<exp,man> operator*(const Big<exp,man> & ss2) const
05587     {
05588     Big<exp,man> temp(*this);
05589 
05590         temp.Mul(ss2);
05591 
05592     return temp;
05593     }
05594 
05595 
05596     Big<exp,man> & operator*=(const Big<exp,man> & ss2)
05597     {
05598         Mul (ss2);
05599 
05600     return *this;
05601     }
05602 
05603 
05604     Big<exp,man> operator/(const Big<exp,man> & ss2) const
05605     {
05606     Big<exp,man> temp(*this);
05607 
05608         temp.Div(ss2);
05609 
05610     return temp;
05611     }
05612 
05613 
05614     Big<exp,man> & operator/=(const Big<exp,man> & ss2)
05615     {
05616         Div (ss2);
05617 
05618     return *this;
05619     }
05620 
05621 
05622     /*!
05623         Prefix operator e.g ++variable
05624     */
05625     Big<exp,man> & operator++ ()
05626     {
05627         AddOne();
05628 
05629     return *this;
05630     }
05631 
05632 
05633     /*!
05634         Postfix operator e.g variable++
05635     */
05636     Big<exp,man> operator++ (int)
05637     {
05638     Big<exp,man> temp( *this );
05639 
05640         AddOne();
05641 
05642     return temp;
05643     }
05644 
05645 
05646     Big<exp,man> & operator--()
05647     {
05648         SubOne();
05649 
05650     return *this;
05651     }
05652 
05653 
05654     Big<exp,man> operator--(int)
05655     {
05656     Big<exp,man> temp( *this );
05657 
05658         SubOne();
05659 
05660     return temp;
05661     }
05662 
05663 
05664 
05665     /*!
05666     *
05667     *    bitwise operators
05668     *   (we do not define bitwise not)
05669     */
05670 
05671 
05672     Big<exp,man> operator& (const Big<exp,man> & p2) const
05673     {
05674         Big<exp,man> temp( *this );
05675 
05676         temp.BitAnd (p2);
05677 
05678     return temp;
05679     }
05680 
05681 
05682     Big<exp,man> & operator&=(const Big<exp,man> & p2)
05683     {
05684         BitAnd (p2);
05685 
05686     return *this;
05687     }
05688 
05689 
05690     Big<exp,man> operator|(const Big<exp,man> & p2) const
05691     {
05692         Big<exp,man> temp( *this );
05693 
05694         temp.BitOr(p2);
05695 
05696     return temp;
05697     }
05698 
05699 
05700     Big<exp,man> & operator|=(const Big<exp,man> & p2)
05701     {
05702         BitOr (p2);
05703 
05704     return *this;
05705     }
05706 
05707 
05708     Big<exp,man> operator^(const Big<exp,man> & p2) const
05709     {
05710         Big<exp,man> temp( *this );
05711 
05712         temp.BitXor(p2);
05713 
05714     return temp;
05715     }
05716 
05717 
05718     Big<exp,man> & operator^=(const Big<exp,man> & p2)
05719     {
05720         BitXor (p2);
05721 
05722     return *this;
05723     }
05724 
05725 
05726 
05727 
05728 
05729 
05730     /*!
05731         this method makes an integer value by skipping any fractions
05732 
05733         for example:
05734             10.7 will be 10
05735             12.1  -- 12
05736             -20.2 -- 20
05737             -20.9 -- 20
05738             -0.7  -- 0
05739             0.8   -- 0
05740     */
05741     void SkipFraction ()
05742     {
05743         if( IsNan () || IsZero () )
05744             return;
05745 
05746         if( !exponent.IsSign () )
05747             // exponent >=0 -- the value don't have any fractions
05748             return;
05749 
05750         if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
05751         {
05752             // the value is from (-1,1), we return zero
05753             SetZero ();
05754             return;
05755         }
05756 
05757         // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
05758         sint e = exponent.ToInt ();
05759     
05760         mantissa.ClearFirstBits ( -e );
05761         
05762         // we don't have to standardize 'Standardizing()' the value because
05763         // there's at least one bit in the mantissa
05764         // (the highest bit which we didn't touch)
05765     }
05766 
05767 
05768     /*!
05769         this method remains only a fraction from the value
05770 
05771         for example:
05772             30.56 will be 0.56
05773             -12.67 -- -0.67
05774     */
05775     void RemainFraction ()
05776     {
05777         if( IsNan () || IsZero () )
05778             return;
05779 
05780         if( !exponent.IsSign () )
05781         {
05782             // exponent >= 0 -- the value doesn't have any fractions
05783             // we return zero
05784             SetZero ();
05785             return;
05786         }
05787 
05788         if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
05789         {
05790             // the value is from (-1,1)
05791             // we don't make anything with the value
05792             return;
05793         }
05794 
05795         // e will be from (-man*TTMATH_BITS_PER_UINT, 0)
05796         sint e = exponent.ToInt ();
05797 
05798         sint how_many_bits_leave = sint(man*TTMATH_BITS_PER_UINT) + e; // there'll be a subtraction -- e is negative
05799         mantissa.Rcl ( how_many_bits_leave, 0);
05800 
05801         // there'll not be a carry because the exponent is too small
05802         exponent.Sub ( how_many_bits_leave );
05803 
05804         // we must call Standardizing() here
05805         Standardizing ();
05806     }
05807 
05808 
05809 
05810     /*!
05811         this method returns true if the value is integer
05812         (there is no a fraction)
05813 
05814         (we don't check nan)
05815     */
05816     bool IsInteger () const
05817     {
05818         if( IsZero () )
05819             return true;
05820 
05821         if( !exponent.IsSign () )
05822             // exponent >=0 -- the value don't have any fractions
05823             return true;
05824 
05825         if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
05826             // the value is from (-1,1)
05827             return false;
05828 
05829         // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
05830         sint e = exponent.ToInt ();
05831         e = -e; // e means how many bits we must check
05832 
05833         uint  len  = e / TTMATH_BITS_PER_UINT;
05834         uint  rest = e % TTMATH_BITS_PER_UINT;
05835         uint  i    = 0;
05836 
05837         for( ; i<len ; ++i )
05838             if( mantissa.table [i] != 0 )
05839                 return false;
05840 
05841         if( rest > 0 )
05842         {
05843             uint  rest_mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
05844             if( (mantissa.table [i] & rest_mask) != 0 )
05845                 return false;
05846         }
05847 
05848     return true;
05849     }
05850 
05851 
05852     /*!
05853         this method rounds to the nearest integer value
05854         (it returns a carry if it was)
05855 
05856         for example:
05857             2.3 = 2
05858             2.8 = 3
05859 
05860             -2.3 = -2
05861             -2.8 = 3
05862     */
05863     uint  Round ()
05864     {
05865     Big<exp,man> half;
05866     uint  c;
05867 
05868         if( IsNan () )
05869             return 1;
05870 
05871         if( IsZero () )
05872             return 0;
05873 
05874         half.Set05 ();
05875 
05876         if( IsSign () )
05877         {
05878             // 'this' is < 0
05879             c = Sub ( half );
05880         }
05881         else
05882         {
05883             // 'this' is > 0
05884             c = Add ( half );
05885         }
05886 
05887         SkipFraction ();
05888 
05889     return CheckCarry (c);
05890     }
05891 
05892     
05893 
05894     /*!
05895     *
05896     *    input/output operators for standard streams
05897     *
05898     */
05899 
05900 private:
05901 
05902     /*!
05903         an auxiliary method for outputing to standard streams
05904     */
05905     template<class ostream_type, class string_type>
05906     static ostream_type & OutputToStream(ostream_type & s, const Big<exp,man> & l)
05907     {
05908     string_type ss;
05909 
05910         l.ToString (ss);
05911         s << ss;
05912 
05913     return s;
05914     }
05915 
05916 
05917 public:
05918 
05919 
05920     /*!
05921         output to standard streams
05922     */
05923     friend std::ostream & operator<<(std::ostream & s,  const Big<exp,man> & l)
05924     {
05925         return OutputToStream<std::ostream, std::string>(s, l);
05926     }
05927 
05928 
05929 #ifndef TTMATH_DONT_USE_WCHAR
05930 
05931     /*!
05932         output to standard streams
05933     */
05934     friend std::wostream & operator<<(std::wostream & s,  const Big<exp,man> & l)
05935     {
05936         return OutputToStream<std::wostream, std::wstring>(s, l);
05937     }
05938 
05939 #endif
05940 
05941 
05942 
05943 private:
05944 
05945     /*!
05946         an auxiliary method for converting from a string
05947     */
05948     template<class istream_type, class string_type, class char_type>
05949     static istream_type & InputFromStream(istream_type & s, Big<exp,man> & l)
05950     {
05951     string_type ss;
05952     
05953     // char or wchar_t for operator>>
05954     char_type z, old_z;
05955     bool was_comma = false;
05956     bool was_e     = false;
05957     
05958 
05959         // operator>> omits white characters if they're set for ommiting
05960         s >> z;
05961 
05962         if( z=='-' || z=='+' )
05963         {
05964             ss += z;
05965             s >> z; // we're reading a next character (white characters can be ommited)
05966         }
05967         
05968         old_z = 0;
05969 
05970         // we're reading only digits (base=10) and only one comma operator
05971         for( ; s.good() ; z=static_cast<char_type>(s.get()) )
05972         {
05973             if( z=='.' ||  z==',' )
05974             {
05975                 if( was_comma || was_e )
05976                     // second comma operator or comma operator after 'e' character
05977                     break;
05978 
05979                 was_comma = true;
05980             }
05981             else
05982             if( z == 'e' || z == 'E' )
05983             {
05984                 if( was_e )
05985                     // second 'e' character
05986                     break;
05987 
05988                 was_e = true;
05989             }
05990             else
05991             if( z == '+' || z == '-' )
05992             {
05993                 if( old_z != 'e' && old_z != 'E' )
05994                     // '+' or '-' is allowed only after 'e' character
05995                     break;
05996             }
05997             else
05998             if( Misc::CharToDigit (z, 10) < 0 )
05999                 break;
06000 
06001 
06002             ss   += z;
06003             old_z = z;
06004         }
06005 
06006         // we're leaving the last read character
06007         // (it's not belonging to the value)
06008         s.unget();
06009 
06010         l.FromString ( ss );
06011 
06012     return s;
06013     }
06014 
06015 
06016 
06017 public:
06018 
06019     /*!
06020         input from standard streams
06021     */
06022     friend std::istream & operator>> (std::istream & s, Big<exp,man> & l)
06023     {
06024         return InputFromStream<std::istream, std::string, char>(s, l);
06025     }
06026 
06027 
06028 #ifndef TTMATH_DONT_USE_WCHAR
06029 
06030     /*!
06031         input from standard streams
06032     */
06033     friend std::wistream & operator>> (std::wistream & s, Big<exp,man> & l)
06034     {
06035         return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
06036     }
06037 
06038 #endif
06039 
06040 };
06041 
06042 
06043 } // namespace
06044 
06045 #endif
06046