Library for big numbers from http://www.ttmath.org/

Dependents:   PIDHeater82 Conceptcontroller_v_1_0 AlarmClockApp COG4050_adxl355_tilt ... more

TTMath is a small library which allows one to perform arithmetic operations with big unsigned integer, big signed integer and big floating point numbers. It provides standard mathematical operations like adding, subtracting, multiplying, dividing.

TTMath is BSD Licensed (new/modified BSD)

For more information about ttmath see http://www.ttmath.org/

Committer:
stevep
Date:
Tue Jul 30 18:43:48 2013 +0000
Revision:
0:04a9f72bbca7
v0.9.3 of ttmath

Who changed what in which revision?

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