Library for big numbers from http://www.ttmath.org/
Dependents: PIDHeater82 Conceptcontroller_v_1_0 AlarmClockApp COG4050_adxl355_tilt ... more
ttmathtypes.h
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
Generated on Tue Jul 12 2022 14:03:18 by 1.7.2