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

ttmathtypes.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 
00039 #ifndef headerfilettmathtypes
00040 #define headerfilettmathtypes
00041 
00042 /*!
00043     \file ttmathtypes.h
00044     \brief constants used in the library
00045     
00046     As our library is written in header files (templates) we cannot use
00047     constants like 'const int' etc. because we should have some source files
00048     *.cpp to define this variables. Only what we can have are constants
00049     defined by #define preprocessor macros.
00050 
00051     All macros are preceded by TTMATH_ prefix
00052 */
00053 
00054 
00055 #include <stdexcept>
00056 #include <sstream>
00057 #include <vector>
00058 
00059 #ifndef _MSC_VER
00060 #include <stdint.h>
00061 // for uint64_t and int64_t on a 32 bit platform
00062 #endif
00063 
00064 
00065 
00066 /*!
00067     the version of the library
00068 
00069     TTMATH_PRERELEASE_VER is either zero or one
00070     zero means that this is the release version of the library
00071     (one means something like beta)
00072 */
00073 #define TTMATH_MAJOR_VER        0
00074 #define TTMATH_MINOR_VER        9
00075 #define TTMATH_REVISION_VER        3
00076 
00077 #define TTMATH_PRERELEASE_VER    0
00078 
00079 
00080 
00081 /*!
00082     you can define a platform explicitly by defining either
00083     TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
00084 */
00085 #if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
00086 
00087     #if !defined _M_X64 && !defined __x86_64__
00088 
00089         /*
00090             other platforms than x86 and amd64 are not recognized at the moment
00091             so you should set TTMATH_PLATFORMxx manually
00092         */
00093 
00094         // we're using a 32bit platform
00095         #define TTMATH_PLATFORM32
00096 
00097     #else
00098 
00099         //    we're using a 64bit platform
00100         #define TTMATH_PLATFORM64
00101 
00102     #endif
00103 
00104 #endif
00105 
00106 
00107 /*!
00108     asm version of the library is available by default only for:
00109     x86 and amd64 platforms and for Microsoft Visual and GCC compilers
00110 
00111     but you can force using asm version (the same asm as for Microsoft Visual)
00112     by defining TTMATH_FORCEASM macro
00113     you have to be sure that your compiler accept such an asm format
00114 */
00115 #ifndef TTMATH_FORCEASM
00116 
00117     #if !defined __i386__  && !defined _X86_ && !defined  _M_IX86 && !defined __x86_64__  && !defined _M_X64
00118         /*!
00119             x86 architecture:
00120             __i386__    defined by GNU C
00121             _X86_          defined by MinGW32
00122             _M_IX86     defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
00123 
00124             amd64 architecture:
00125             __x86_64__  defined by GNU C, CLANG (LLVM) and Sun Studio
00126             _M_X64      defined by Visual Studio
00127 
00128             asm version is available only for x86 or amd64 platforms
00129         */
00130         #define TTMATH_NOASM
00131     #endif
00132 
00133 
00134 
00135     #if !defined _MSC_VER && !defined __GNUC__
00136         /*!
00137             another compilers than MS VC or GCC or CLANG (LLVM) by default use no asm version
00138             (CLANG defines __GNUC__ too)
00139         */
00140         #define TTMATH_NOASM
00141     #endif
00142 
00143 #endif
00144 
00145 
00146 namespace ttmath
00147 {
00148 
00149 
00150 #ifdef TTMATH_PLATFORM32
00151 
00152     /*!
00153         on 32bit platforms one word (uint, sint) will be equal 32bits
00154     */
00155     typedef unsigned int uint ;
00156     typedef signed   int sint;
00157 
00158     /*!
00159         on 32 bit platform ulint and slint will be equal 64 bits
00160     */
00161     #ifdef _MSC_VER
00162         // long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
00163         // stdint.h is not available on Visual Studio prior to VS 2010 version
00164         typedef unsigned long long int ulint ;
00165         typedef signed   long long int slint;
00166     #else
00167         // we do not use 'long' here because there is a difference in unix and windows
00168         // environments: in unix 'long' has 64 bits but in windows it has only 32 bits
00169         typedef uint64_t ulint ;
00170         typedef int64_t  slint;
00171     #endif
00172 
00173     /*!
00174         how many bits there are in the uint type
00175     */
00176     #define TTMATH_BITS_PER_UINT 32u
00177 
00178     /*!
00179         the mask for the highest bit in the unsigned 32bit word (2^31)
00180     */
00181     #define TTMATH_UINT_HIGHEST_BIT 2147483648u
00182 
00183     /*!
00184         the max value of the unsigned 32bit word (2^32 - 1)
00185         (all bits equal one)
00186     */
00187     #define TTMATH_UINT_MAX_VALUE 4294967295u
00188 
00189     /*!
00190         the number of words (32bit words on 32bit platform)
00191         which are kept in built-in variables for a Big<> type
00192         (these variables are defined in ttmathbig.h)
00193     */
00194     #define TTMATH_BUILTIN_VARIABLES_SIZE 256u
00195 
00196     /*!
00197         this macro returns the number of machine words 
00198         capable to hold min_bits bits
00199         e.g. TTMATH_BITS(128) returns 4
00200     */
00201     #define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1)
00202 
00203 #else
00204 
00205     /*!
00206         on 64bit platforms one word (uint, sint) will be equal 64bits
00207     */
00208     #ifdef _MSC_VER
00209         /* in VC 'long' type has 32 bits, __int64 is VC extension */
00210         typedef unsigned __int64 uint ;
00211         typedef signed   __int64 sint;
00212     #else
00213         typedef unsigned long uint ;
00214         typedef signed   long sint;
00215     #endif 
00216 
00217     /*!
00218         on 64bit platforms we do not define ulint and slint
00219     */
00220 
00221     /*!
00222         how many bits there are in the uint type
00223     */
00224     #define TTMATH_BITS_PER_UINT 64ul
00225 
00226     /*!
00227         the mask for the highest bit in the unsigned 64bit word (2^63)
00228     */
00229     #define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
00230 
00231     /*!
00232         the max value of the unsigned 64bit word (2^64 - 1)
00233         (all bits equal one)
00234     */
00235     #define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
00236 
00237     /*!
00238         the number of words (64bit words on 64bit platforms)
00239         which are kept in built-in variables for a Big<> type
00240         (these variables are defined in ttmathbig.h)
00241     */
00242     #define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
00243 
00244     /*!
00245         this macro returns the number of machine words 
00246         capable to hold min_bits bits
00247         e.g. TTMATH_BITS(128) returns 2
00248     */
00249     #define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1)
00250 
00251 #endif
00252 }
00253 
00254 
00255 #if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
00256     #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
00257 
00258         #if defined(_WIN32)
00259             #define TTMATH_WIN32_THREADS
00260         #elif defined(unix) || defined(__unix__) || defined(__unix)
00261             #define TTMATH_POSIX_THREADS
00262         #endif
00263 
00264     #endif
00265 #endif
00266 
00267 
00268 
00269 /*!
00270     this variable defines how many iterations are performed
00271     during some kind of calculating when we're making any long formulas
00272     (for example Taylor series)
00273 
00274     it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
00275 
00276     note! there'll not be so many iterations, iterations are stopped when
00277     there is no sense to continue calculating (for example when the result
00278     still remains unchanged after adding next series and we know that the next
00279     series are smaller than previous ones)
00280 */
00281 #define TTMATH_ARITHMETIC_MAX_LOOP 10000
00282 
00283 
00284 
00285 /*!
00286     this is a limit when calculating Karatsuba multiplication
00287     if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
00288     the Karatsuba algorithm will use standard schoolbook multiplication
00289 */
00290 #ifdef TTMATH_DEBUG_LOG
00291     // if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
00292     #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
00293 #else
00294     #ifdef __GNUC__
00295         #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
00296     #else
00297         #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
00298     #endif
00299 #endif
00300 
00301 
00302 /*!
00303     this is a special value used when calculating the Gamma(x) function
00304     if x is greater than this value then the Gamma(x) will be calculated using
00305     some kind of series
00306 
00307     don't use smaller values than about 100
00308 */
00309 #define TTMATH_GAMMA_BOUNDARY 2000
00310 
00311 
00312 
00313 
00314 
00315 namespace ttmath
00316 {
00317 
00318     /*!
00319         lib type codes:
00320           asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
00321           asm_gcc_32  - with asm code designed for GCC (32 bits)
00322           asm_vc_64   - with asm for VC (64 bit)
00323           asm_gcc_64  - with asm for GCC (64 bit)
00324           no_asm_32   - pure C++ version (32 bit) - without any asm code
00325           no_asm_64   - pure C++ version (64 bit) - without any asm code
00326     */
00327     enum LibTypeCode 
00328     {
00329       asm_vc_32 = 0,
00330       asm_gcc_32,
00331       asm_vc_64,
00332       asm_gcc_64,
00333       no_asm_32,
00334       no_asm_64
00335     };
00336 
00337 
00338     /*!
00339         error codes
00340     */
00341     enum ErrorCode 
00342     {
00343         err_ok = 0,
00344         err_nothing_has_read,
00345         err_unknown_character,
00346         err_unexpected_final_bracket,
00347         err_stack_not_clear,
00348         err_unknown_variable,
00349         err_division_by_zero,
00350         err_interrupt,
00351         err_overflow,
00352         err_unknown_function,
00353         err_unknown_operator,
00354         err_unexpected_semicolon_operator,
00355         err_improper_amount_of_arguments,
00356         err_improper_argument,
00357         err_unexpected_end,
00358         err_internal_error,
00359         err_incorrect_name,
00360         err_incorrect_value,
00361         err_variable_exists,
00362         err_variable_loop,
00363         err_functions_loop,
00364         err_must_be_only_one_value,
00365         err_object_exists,
00366         err_unknown_object,
00367         err_still_calculating,
00368         err_in_short_form_used_function,
00369         err_percent_from
00370     };
00371 
00372 
00373     /*!
00374         this struct is used when converting to/from a string
00375         /temporarily only in Big::ToString() and Big::FromString()/
00376     */
00377     struct Conv 
00378     {
00379         /*!
00380             base (radix) on which the value will be shown (or read)
00381             default: 10
00382         */
00383         uint  base ;
00384 
00385 
00386         /*!
00387             used only in Big::ToString()
00388             if true the value will be always shown in the scientific mode, e.g: 123e+30
00389             default: false
00390         */
00391         bool scient ;
00392 
00393 
00394         /*!
00395             used only in Big::ToString()
00396             if scient is false then the value will be printed in the scientific mode
00397             only if the exponent is greater than scien_from
00398             default: 15
00399         */
00400         sint scient_from ;
00401 
00402 
00403         /*!
00404             if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
00405             and the result value is not an integer then we make an additional rounding
00406             (after converting the last digit from the result is skipped)
00407             default: true
00408 
00409             e.g.
00410             Conv c;
00411             c.base_round = false;
00412             Big<1, 1> a = "0.1";                       // decimal input
00413             std::cout << a.ToString(c) << std::endl;   // the result is: 0.099999999
00414         */
00415         bool base_round ;
00416 
00417 
00418         /*!
00419             used only in Big::ToString()
00420             tells how many digits after comma are possible
00421             default: -1 which means all digits are printed
00422 
00423             set it to zero if you want integer value only
00424 
00425             for example when the value is:
00426                 12.345678 and 'round' is 4
00427             then the result will be 
00428                 12.3457   (the last digit was rounded)
00429         */
00430         sint round ;
00431 
00432 
00433         /*!
00434             if true that not mattered digits in the mantissa will be cut off
00435             (zero characters at the end -- after the comma operator)
00436             e.g. 1234,78000 will be: 1234,78
00437             default: true
00438         */
00439         bool trim_zeroes ;
00440 
00441 
00442         /*!
00443             the main comma operator (used when reading and writing)
00444             default is a dot '.'
00445         */
00446         uint  comma ;
00447 
00448 
00449         /*!
00450             additional comma operator (used only when reading) 
00451             if you don't want it just set it to zero
00452             default is a comma ','
00453 
00454             this allowes you to convert from a value:
00455             123.45 as well as from 123,45
00456         */
00457         uint  comma2 ;
00458 
00459 
00460         /*!
00461             it sets the character which is used for grouping
00462             if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
00463 
00464             if you don't want grouping just set it to zero (which is default)
00465         */
00466         uint  group ;
00467 
00468 
00469         /*!
00470             how many digits should be grouped (it is used if 'group' is non zero)
00471             default: 3
00472         */
00473         uint  group_digits ;
00474 
00475 
00476         /*!
00477         */
00478         uint  group_exp; // not implemented yet
00479 
00480 
00481 
00482 
00483         Conv ()
00484         {
00485             // default values
00486             base          = 10;
00487             scient        = false;
00488             scient_from   = 15;
00489             base_round    = true;
00490             round         = -1;
00491             trim_zeroes   = true;
00492             comma         = '.';
00493             comma2        = ',';
00494             group         = 0;
00495             group_digits  = 3;
00496             group_exp    = 0;
00497         }
00498     };
00499 
00500 
00501 
00502     /*!
00503         this simple class can be used in multithreading model
00504         (you can write your own class derived from this one)
00505 
00506         for example: in some functions like Factorial() 
00507         /at the moment only Factorial/ you can give a pointer to 
00508         the 'stop object', if the method WasStopSignal() of this 
00509         object returns true that means we should break the calculating
00510         and return
00511     */
00512     class StopCalculating 
00513     {
00514     public:
00515         virtual bool WasStopSignal() const volatile { return false; }
00516         virtual ~StopCalculating (){}
00517     };
00518 
00519 
00520     /*!
00521         a small class which is useful when compiling with gcc
00522 
00523         object of this type holds the name and the line of a file
00524         in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
00525     */
00526     class ExceptionInfo 
00527     {
00528     const char * file;
00529     int line;
00530 
00531     public:
00532         ExceptionInfo () : file(0), line(0) {}
00533         ExceptionInfo (const char * f, int l) : file(f), line(l) {}
00534 
00535         std::string Where() const
00536         {
00537             if( !file )
00538                 return "unknown";
00539 
00540             std::ostringstream result;
00541             result << file << ":" << line;
00542 
00543         return result.str();
00544         }
00545     };
00546 
00547 
00548     /*!
00549         A small class used for reporting 'reference' errors
00550 
00551         In the library is used macro TTMATH_REFERENCE_ASSERT which
00552         can throw an exception of this type
00553 
00554         ** from version 0.9.2 this macro is removed from all methods
00555            in public interface so you don't have to worry about it **
00556 
00557         If you compile with gcc you can get a small benefit 
00558         from using method Where() (it returns std::string) with
00559         the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
00560         was used)
00561     */
00562     class ReferenceError  : public std::logic_error, public ExceptionInfo 
00563     {
00564     public:
00565 
00566         ReferenceError () : std::logic_error("reference error")
00567         {
00568         }
00569 
00570         ReferenceError (const char * f, int l) :
00571                             std::logic_error("reference error"), ExceptionInfo (f,l)
00572         {
00573         }
00574 
00575         std::string Where() const
00576         {
00577             return ExceptionInfo::Where();
00578         }
00579     };
00580 
00581 
00582     /*!
00583         a small class used for reporting errors
00584 
00585         in the library is used macro TTMATH_ASSERT which
00586         (if the condition in it is false) throw an exception
00587         of this type
00588 
00589         if you compile with gcc you can get a small benefit 
00590         from using method Where() (it returns std::string) with
00591         the name and the line of a file where the macro TTMATH_ASSERT
00592         was used)
00593     */
00594     class RuntimeError  : public std::runtime_error, public ExceptionInfo 
00595     {
00596     public:
00597 
00598         RuntimeError () : std::runtime_error("internal error")
00599         {
00600         }
00601 
00602         RuntimeError (const char * f, int l) :
00603                         std::runtime_error("internal error"), ExceptionInfo (f,l)
00604         {
00605         }
00606 
00607         std::string Where() const
00608         {
00609             return ExceptionInfo::Where();
00610         }
00611     };
00612 
00613 
00614 
00615     /*!
00616         TTMATH_DEBUG
00617         this macro enables further testing during writing your code
00618         you don't have to define it in a release mode
00619 
00620         if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
00621         are set as well    and these macros can throw an exception if a condition in it
00622         is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
00623 
00624         TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
00625     */
00626     #if defined DEBUG || defined _DEBUG
00627         #define TTMATH_DEBUG
00628     #endif
00629 
00630 
00631     #ifdef TTMATH_DEBUG
00632 
00633         #if defined(__FILE__) && defined(__LINE__)
00634 
00635             #define TTMATH_REFERENCE_ASSERT(expression) \
00636                 if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
00637 
00638             #define TTMATH_ASSERT(expression) \
00639                 if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
00640 
00641         #else
00642 
00643             #define TTMATH_REFERENCE_ASSERT(expression) \
00644                 if( &(expression) == this ) throw ReferenceError();
00645 
00646             #define TTMATH_ASSERT(expression) \
00647                 if( !(expression) ) throw RuntimeError();
00648         #endif
00649 
00650     #else
00651         #define TTMATH_REFERENCE_ASSERT(expression)
00652         #define TTMATH_ASSERT(expression)
00653     #endif
00654 
00655 
00656 
00657     #ifdef TTMATH_DEBUG_LOG
00658         #define TTMATH_LOG(msg)                             PrintLog(msg, std::cout);
00659         #define TTMATH_LOGC(msg, carry)                     PrintLog(msg, carry, std::cout);
00660         #define TTMATH_VECTOR_LOG(msg, vector, len)         PrintVectorLog(msg, std::cout, vector, len);
00661         #define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
00662     #else
00663         #define TTMATH_LOG(msg)
00664         #define TTMATH_LOGC(msg, carry)
00665         #define TTMATH_VECTOR_LOG(msg, vector, len)
00666         #define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
00667     #endif
00668 
00669 
00670 
00671 
00672 } // namespace
00673 
00674 
00675 #endif
00676 
00677