ttmathtypes.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /*
  2. * This file is a part of TTMath Bignum Library
  3. * and is distributed under the (new) BSD licence.
  4. * Author: Tomasz Sowa <[email protected]>
  5. */
  6. /*
  7. * Copyright (c) 2006-2012, Tomasz Sowa
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * * Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. *
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * * Neither the name Tomasz Sowa nor the names of contributors to this
  21. * project may be used to endorse or promote products derived
  22. * from this software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  28. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  34. * THE POSSIBILITY OF SUCH DAMAGE.
  35. */
  36. #ifndef headerfilettmathtypes
  37. #define headerfilettmathtypes
  38. /*!
  39. \file ttmathtypes.h
  40. \brief constants used in the library
  41. As our library is written in header files (templates) we cannot use
  42. constants like 'const int' etc. because we should have some source files
  43. *.cpp to define this variables. Only what we can have are constants
  44. defined by #define preprocessor macros.
  45. All macros are preceded by TTMATH_ prefix
  46. */
  47. #include <stdexcept>
  48. #include <sstream>
  49. #include <vector>
  50. #ifndef _MSC_VER
  51. #include <stdint.h>
  52. // for uint64_t and int64_t on a 32 bit platform
  53. #endif
  54. /*!
  55. the version of the library
  56. TTMATH_PRERELEASE_VER is either zero or one
  57. zero means that this is the release version of the library
  58. (one means something like beta)
  59. */
  60. #define TTMATH_MAJOR_VER 0
  61. #define TTMATH_MINOR_VER 9
  62. #define TTMATH_REVISION_VER 3
  63. #define TTMATH_PRERELEASE_VER 0
  64. /*!
  65. you can define a platform explicitly by defining either
  66. TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro
  67. */
  68. #if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64
  69. #if !defined _M_X64 && !defined __x86_64__
  70. /*
  71. other platforms than x86 and amd64 are not recognized at the moment
  72. so you should set TTMATH_PLATFORMxx manually
  73. */
  74. // we're using a 32bit platform
  75. #define TTMATH_PLATFORM32
  76. #else
  77. // we're using a 64bit platform
  78. #define TTMATH_PLATFORM64
  79. #endif
  80. #endif
  81. /*!
  82. asm version of the library is available by default only for:
  83. x86 and amd64 platforms and for Microsoft Visual and GCC compilers
  84. but you can force using asm version (the same asm as for Microsoft Visual)
  85. by defining TTMATH_FORCEASM macro
  86. you have to be sure that your compiler accept such an asm format
  87. */
  88. #ifndef TTMATH_FORCEASM
  89. #if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64
  90. /*!
  91. x86 architecture:
  92. __i386__ defined by GNU C
  93. _X86_ defined by MinGW32
  94. _M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++
  95. amd64 architecture:
  96. __x86_64__ defined by GNU C, CLANG (LLVM) and Sun Studio
  97. _M_X64 defined by Visual Studio
  98. asm version is available only for x86 or amd64 platforms
  99. */
  100. #define TTMATH_NOASM
  101. #endif
  102. #if !defined _MSC_VER && !defined __GNUC__
  103. /*!
  104. another compilers than MS VC or GCC or CLANG (LLVM) by default use no asm version
  105. (CLANG defines __GNUC__ too)
  106. */
  107. #define TTMATH_NOASM
  108. #endif
  109. #endif
  110. namespace ttmath
  111. {
  112. #ifdef TTMATH_PLATFORM32
  113. /*!
  114. on 32bit platforms one word (uint, sint) will be equal 32bits
  115. */
  116. typedef unsigned int uint;
  117. typedef signed int sint;
  118. /*!
  119. on 32 bit platform ulint and slint will be equal 64 bits
  120. */
  121. #ifdef _MSC_VER
  122. // long long on MS Windows (Visual and GCC mingw compilers) have 64 bits
  123. // stdint.h is not available on Visual Studio prior to VS 2010 version
  124. typedef unsigned long long int ulint;
  125. typedef signed long long int slint;
  126. #else
  127. // we do not use 'long' here because there is a difference in unix and windows
  128. // environments: in unix 'long' has 64 bits but in windows it has only 32 bits
  129. typedef uint64_t ulint;
  130. typedef int64_t slint;
  131. #endif
  132. /*!
  133. how many bits there are in the uint type
  134. */
  135. #define TTMATH_BITS_PER_UINT 32u
  136. /*!
  137. the mask for the highest bit in the unsigned 32bit word (2^31)
  138. */
  139. #define TTMATH_UINT_HIGHEST_BIT 2147483648u
  140. /*!
  141. the max value of the unsigned 32bit word (2^32 - 1)
  142. (all bits equal one)
  143. */
  144. #define TTMATH_UINT_MAX_VALUE 4294967295u
  145. /*!
  146. the number of words (32bit words on 32bit platform)
  147. which are kept in built-in variables for a Big<> type
  148. (these variables are defined in ttmathbig.h)
  149. */
  150. #define TTMATH_BUILTIN_VARIABLES_SIZE 256u
  151. /*!
  152. this macro returns the number of machine words
  153. capable to hold min_bits bits
  154. e.g. TTMATH_BITS(128) returns 4
  155. */
  156. #define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1)
  157. #else
  158. /*!
  159. on 64bit platforms one word (uint, sint) will be equal 64bits
  160. */
  161. #ifdef _MSC_VER
  162. /* in VC 'long' type has 32 bits, __int64 is VC extension */
  163. typedef unsigned __int64 uint;
  164. typedef signed __int64 sint;
  165. #else
  166. typedef unsigned long uint;
  167. typedef signed long sint;
  168. #endif
  169. /*!
  170. on 64bit platforms we do not define ulint and slint
  171. */
  172. /*!
  173. how many bits there are in the uint type
  174. */
  175. #define TTMATH_BITS_PER_UINT 64ul
  176. /*!
  177. the mask for the highest bit in the unsigned 64bit word (2^63)
  178. */
  179. #define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
  180. /*!
  181. the max value of the unsigned 64bit word (2^64 - 1)
  182. (all bits equal one)
  183. */
  184. #define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
  185. /*!
  186. the number of words (64bit words on 64bit platforms)
  187. which are kept in built-in variables for a Big<> type
  188. (these variables are defined in ttmathbig.h)
  189. */
  190. #define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
  191. /*!
  192. this macro returns the number of machine words
  193. capable to hold min_bits bits
  194. e.g. TTMATH_BITS(128) returns 2
  195. */
  196. #define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1)
  197. #endif
  198. }
  199. #if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
  200. #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
  201. #if defined(_WIN32)
  202. #define TTMATH_WIN32_THREADS
  203. #elif defined(unix) || defined(__unix__) || defined(__unix)
  204. #define TTMATH_POSIX_THREADS
  205. #endif
  206. #endif
  207. #endif
  208. /*!
  209. this variable defines how many iterations are performed
  210. during some kind of calculating when we're making any long formulas
  211. (for example Taylor series)
  212. it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
  213. note! there'll not be so many iterations, iterations are stopped when
  214. there is no sense to continue calculating (for example when the result
  215. still remains unchanged after adding next series and we know that the next
  216. series are smaller than previous ones)
  217. */
  218. #define TTMATH_ARITHMETIC_MAX_LOOP 10000
  219. /*!
  220. this is a limit when calculating Karatsuba multiplication
  221. if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
  222. the Karatsuba algorithm will use standard schoolbook multiplication
  223. */
  224. #ifdef TTMATH_DEBUG_LOG
  225. // if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
  226. #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
  227. #else
  228. #ifdef __GNUC__
  229. #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
  230. #else
  231. #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
  232. #endif
  233. #endif
  234. /*!
  235. this is a special value used when calculating the Gamma(x) function
  236. if x is greater than this value then the Gamma(x) will be calculated using
  237. some kind of series
  238. don't use smaller values than about 100
  239. */
  240. #define TTMATH_GAMMA_BOUNDARY 2000
  241. namespace ttmath
  242. {
  243. /*!
  244. lib type codes:
  245. asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
  246. asm_gcc_32 - with asm code designed for GCC (32 bits)
  247. asm_vc_64 - with asm for VC (64 bit)
  248. asm_gcc_64 - with asm for GCC (64 bit)
  249. no_asm_32 - pure C++ version (32 bit) - without any asm code
  250. no_asm_64 - pure C++ version (64 bit) - without any asm code
  251. */
  252. enum LibTypeCode
  253. {
  254. asm_vc_32 = 0,
  255. asm_gcc_32,
  256. asm_vc_64,
  257. asm_gcc_64,
  258. no_asm_32,
  259. no_asm_64
  260. };
  261. /*!
  262. error codes
  263. */
  264. enum ErrorCode
  265. {
  266. err_ok = 0,
  267. err_nothing_has_read,
  268. err_unknown_character,
  269. err_unexpected_final_bracket,
  270. err_stack_not_clear,
  271. err_unknown_variable,
  272. err_division_by_zero,
  273. err_interrupt,
  274. err_overflow,
  275. err_unknown_function,
  276. err_unknown_operator,
  277. err_unexpected_semicolon_operator,
  278. err_improper_amount_of_arguments,
  279. err_improper_argument,
  280. err_unexpected_end,
  281. err_internal_error,
  282. err_incorrect_name,
  283. err_incorrect_value,
  284. err_variable_exists,
  285. err_variable_loop,
  286. err_functions_loop,
  287. err_must_be_only_one_value,
  288. err_object_exists,
  289. err_unknown_object,
  290. err_still_calculating,
  291. err_in_short_form_used_function,
  292. err_percent_from
  293. };
  294. /*!
  295. this struct is used when converting to/from a string
  296. /temporarily only in Big::ToString() and Big::FromString()/
  297. */
  298. struct Conv
  299. {
  300. /*!
  301. base (radix) on which the value will be shown (or read)
  302. default: 10
  303. */
  304. uint base;
  305. /*!
  306. used only in Big::ToString()
  307. if true the value will be always shown in the scientific mode, e.g: 123e+30
  308. default: false
  309. */
  310. bool scient;
  311. /*!
  312. used only in Big::ToString()
  313. if scient is false then the value will be printed in the scientific mode
  314. only if the exponent is greater than scien_from
  315. default: 15
  316. */
  317. sint scient_from;
  318. /*!
  319. if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
  320. and the result value is not an integer then we make an additional rounding
  321. (after converting the last digit from the result is skipped)
  322. default: true
  323. e.g.
  324. Conv c;
  325. c.base_round = false;
  326. Big<1, 1> a = "0.1"; // decimal input
  327. std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
  328. */
  329. bool base_round;
  330. /*!
  331. used only in Big::ToString()
  332. tells how many digits after comma are possible
  333. default: -1 which means all digits are printed
  334. set it to zero if you want integer value only
  335. for example when the value is:
  336. 12.345678 and 'round' is 4
  337. then the result will be
  338. 12.3457 (the last digit was rounded)
  339. */
  340. sint round;
  341. /*!
  342. if true that not mattered digits in the mantissa will be cut off
  343. (zero characters at the end -- after the comma operator)
  344. e.g. 1234,78000 will be: 1234,78
  345. default: true
  346. */
  347. bool trim_zeroes;
  348. /*!
  349. the main comma operator (used when reading and writing)
  350. default is a dot '.'
  351. */
  352. uint comma;
  353. /*!
  354. additional comma operator (used only when reading)
  355. if you don't want it just set it to zero
  356. default is a comma ','
  357. this allowes you to convert from a value:
  358. 123.45 as well as from 123,45
  359. */
  360. uint comma2;
  361. /*!
  362. it sets the character which is used for grouping
  363. if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
  364. if you don't want grouping just set it to zero (which is default)
  365. */
  366. uint group;
  367. /*!
  368. how many digits should be grouped (it is used if 'group' is non zero)
  369. default: 3
  370. */
  371. uint group_digits;
  372. /*!
  373. */
  374. uint group_exp; // not implemented yet
  375. Conv()
  376. {
  377. // default values
  378. base = 10;
  379. scient = false;
  380. scient_from = 15;
  381. base_round = true;
  382. round = -1;
  383. trim_zeroes = true;
  384. comma = '.';
  385. comma2 = ',';
  386. group = 0;
  387. group_digits = 3;
  388. group_exp = 0;
  389. }
  390. };
  391. /*!
  392. this simple class can be used in multithreading model
  393. (you can write your own class derived from this one)
  394. for example: in some functions like Factorial()
  395. /at the moment only Factorial/ you can give a pointer to
  396. the 'stop object', if the method WasStopSignal() of this
  397. object returns true that means we should break the calculating
  398. and return
  399. */
  400. class StopCalculating
  401. {
  402. public:
  403. virtual bool WasStopSignal() const volatile { return false; }
  404. virtual ~StopCalculating(){}
  405. };
  406. /*!
  407. a small class which is useful when compiling with gcc
  408. object of this type holds the name and the line of a file
  409. in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
  410. */
  411. class ExceptionInfo
  412. {
  413. const char * file;
  414. int line;
  415. public:
  416. ExceptionInfo() : file(0), line(0) {}
  417. ExceptionInfo(const char * f, int l) : file(f), line(l) {}
  418. std::string Where() const
  419. {
  420. if( !file )
  421. return "unknown";
  422. std::ostringstream result;
  423. result << file << ":" << line;
  424. return result.str();
  425. }
  426. };
  427. /*!
  428. A small class used for reporting 'reference' errors
  429. In the library is used macro TTMATH_REFERENCE_ASSERT which
  430. can throw an exception of this type
  431. ** from version 0.9.2 this macro is removed from all methods
  432. in public interface so you don't have to worry about it **
  433. If you compile with gcc you can get a small benefit
  434. from using method Where() (it returns std::string) with
  435. the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
  436. was used)
  437. */
  438. class ReferenceError : public std::logic_error, public ExceptionInfo
  439. {
  440. public:
  441. ReferenceError() : std::logic_error("reference error")
  442. {
  443. }
  444. ReferenceError(const char * f, int l) :
  445. std::logic_error("reference error"), ExceptionInfo(f,l)
  446. {
  447. }
  448. std::string Where() const
  449. {
  450. return ExceptionInfo::Where();
  451. }
  452. };
  453. /*!
  454. a small class used for reporting errors
  455. in the library is used macro TTMATH_ASSERT which
  456. (if the condition in it is false) throw an exception
  457. of this type
  458. if you compile with gcc you can get a small benefit
  459. from using method Where() (it returns std::string) with
  460. the name and the line of a file where the macro TTMATH_ASSERT
  461. was used)
  462. */
  463. class RuntimeError : public std::runtime_error, public ExceptionInfo
  464. {
  465. public:
  466. RuntimeError() : std::runtime_error("internal error")
  467. {
  468. }
  469. RuntimeError(const char * f, int l) :
  470. std::runtime_error("internal error"), ExceptionInfo(f,l)
  471. {
  472. }
  473. std::string Where() const
  474. {
  475. return ExceptionInfo::Where();
  476. }
  477. };
  478. /*!
  479. TTMATH_DEBUG
  480. this macro enables further testing during writing your code
  481. you don't have to define it in a release mode
  482. if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
  483. are set as well and these macros can throw an exception if a condition in it
  484. is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
  485. TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined
  486. */
  487. #if defined DEBUG || defined _DEBUG
  488. #define TTMATH_DEBUG
  489. #endif
  490. #ifdef TTMATH_DEBUG
  491. #if defined(__FILE__) && defined(__LINE__)
  492. #define TTMATH_REFERENCE_ASSERT(expression) \
  493. if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
  494. #define TTMATH_ASSERT(expression) \
  495. if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
  496. #else
  497. #define TTMATH_REFERENCE_ASSERT(expression) \
  498. if( &(expression) == this ) throw ReferenceError();
  499. #define TTMATH_ASSERT(expression) \
  500. if( !(expression) ) throw RuntimeError();
  501. #endif
  502. #else
  503. #define TTMATH_REFERENCE_ASSERT(expression)
  504. #define TTMATH_ASSERT(expression)
  505. #endif
  506. #ifdef TTMATH_DEBUG_LOG
  507. #define TTMATH_LOG(msg) PrintLog(msg, std::cout);
  508. #define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout);
  509. #define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len);
  510. #define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
  511. #else
  512. #define TTMATH_LOG(msg)
  513. #define TTMATH_LOGC(msg, carry)
  514. #define TTMATH_VECTOR_LOG(msg, vector, len)
  515. #define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
  516. #endif
  517. } // namespace
  518. #endif