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