TTMath  0.9.4
 C++ bignum library
ttmathbig.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 #ifndef headerfilettmathbig
39 #define headerfilettmathbig
40 
41 /*!
42  \file ttmathbig.h
43  \brief A Class for representing floating point numbers
44 */
45 
46 #include "ttmathint.h"
47 #include "ttmaththreads.h"
48 
49 #include <iostream>
50 
51 #ifdef TTMATH_MULTITHREADS
52 #include <signal.h>
53 #endif
54 
55 namespace ttmath
56 {
57 
58 
59 /*!
60  \brief Big implements the floating point numbers
61 */
62 template <uint exp, uint man>
63 class Big
64 {
65 
66 /*
67  value = mantissa * 2^exponent
68 
69  - exponent - an integer value with a sign
70  - mantissa - an integer value without a sing
71 
72  mantissa must be pushed into the left side that is the highest bit from
73  mantissa must be one (of course if there's another value than zero) -- this job
74  (pushing bits into the left side) is doing by Standardizing() method
75 
76  for example:
77  if we want to store value one (1) into our Big object we must:
78  - set mantissa to 1
79  - set exponent to 0
80  - set info to 0
81  - and call method Standardizing()
82 */
83 
84 
85 public:
86 
87 Int<exp> exponent;
88 UInt<man> mantissa;
89 unsigned char info;
90 
91 
92 /*!
93  Sign
94  the mask of a bit from 'info' which means that there is a sign
95  (when the bit is set)
96 */
97 #define TTMATH_BIG_SIGN 128
98 
99 
100 /*!
101  Not a number
102  if this bit is set that there is not a valid number
103 */
104 #define TTMATH_BIG_NAN 64
105 
106 
107 /*!
108  Zero
109  if this bit is set that there is value zero
110  mantissa should be zero and exponent should be zero too
111  (the Standardizing() method does this)
112 */
113 #define TTMATH_BIG_ZERO 32
114 
115 
116  /*!
117  this method sets NaN if there was a carry (and returns 1 in such a case)
118 
119  c can be 0, 1 or other value different from zero
120  */
122  {
123  if( c != 0 )
124  {
125  SetNan();
126  return 1;
127  }
128 
129  return 0;
130  }
131 
132 public:
133 
134 
135  /*!
136  returning the string represents the currect type of the library
137  we have following types:
138  - asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits)
139  - asm_gcc_32 - with asm code designed for GCC (32 bits)
140  - asm_vc_64 - with asm for VC (64 bit)
141  - asm_gcc_64 - with asm for GCC (64 bit)
142  - no_asm_32 - pure C++ version (32 bit) - without any asm code
143  - no_asm_64 - pure C++ version (64 bit) - without any asm code
144  */
145  static const char * LibTypeStr()
146  {
147  return UInt<man>::LibTypeStr();
148  }
149 
150 
151  /*!
152  returning the currect type of the library
153  */
155  {
156  return UInt<man>::LibType();
157  }
158 
159 
160 
161  /*!
162  this method moves all bits from mantissa into its left side
163  (suitably changes the exponent) or if the mantissa is zero
164  it sets the exponent to zero as well
165  (and clears the sign bit and sets the zero bit)
166 
167  it can return a carry
168  the carry will be when we don't have enough space in the exponent
169 
170  you don't have to use this method if you don't change the mantissa
171  and exponent directly
172  */
174  {
175  if( mantissa.IsTheHighestBitSet() )
176  {
178  return 0;
179  }
180 
181  if( CorrectZero() )
182  return 0;
183 
184  uint comp = mantissa.CompensationToLeft();
185 
186  return exponent.Sub( comp );
187  }
188 
189 
190 private:
191 
192  /*!
193  if the mantissa is equal zero this method sets exponent to zero and
194  info without the sign
195 
196  it returns true if there was the correction
197  */
198  bool CorrectZero()
199  {
200  if( mantissa.IsZero() )
201  {
204  exponent.SetZero();
205 
206  return true;
207  }
208  else
209  {
211  }
212 
213  return false;
214  }
215 
216 
217 public:
218 
219  /*!
220  this method clears a specific bit in the 'info' variable
221 
222  bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
223  */
224  void ClearInfoBit(unsigned char bit)
225  {
226  info = info & (~bit);
227  }
228 
229 
230  /*!
231  this method sets a specific bit in the 'info' variable
232 
233  bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
234 
235  */
236  void SetInfoBit(unsigned char bit)
237  {
238  info = info | bit;
239  }
240 
241 
242  /*!
243  this method returns true if a specific bit in the 'info' variable is set
244 
245  bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
246  */
247  bool IsInfoBit(unsigned char bit) const
248  {
249  return (info & bit) != 0;
250  }
251 
252 
253  /*!
254  this method sets zero
255  */
256  void SetZero()
257  {
258  info = TTMATH_BIG_ZERO;
259  exponent.SetZero();
260  mantissa.SetZero();
261 
262  /*
263  we don't have to compensate zero
264  */
265  }
266 
267 
268  /*!
269  this method sets one
270  */
271  void SetOne()
272  {
273  info = 0;
274  mantissa.SetZero();
275  mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;
276  exponent = -sint(man * TTMATH_BITS_PER_UINT - 1);
277 
278  // don't have to Standardize() - the last bit from mantissa is set
279  }
280 
281 
282  /*!
283  this method sets value 0.5
284  */
285  void Set05()
286  {
287  SetOne();
288  exponent.SubOne();
289  }
290 
291 
292  /*!
293  this method sets NaN flag (Not a Number)
294  when this flag is set that means there is no a valid number
295  */
296  void SetNan()
297  {
299  }
300 
301 
302  /*!
303  this method sets NaN flag (Not a Number)
304  also clears the mantissa and exponent (similarly as it would be a zero value)
305  */
306  void SetZeroNan()
307  {
308  SetZero();
309  SetNan();
310  }
311 
312 
313  /*!
314  this method swappes this for an argument
315  */
316  void Swap(Big<exp, man> & ss2)
317  {
318  unsigned char info_temp = info;
319  info = ss2.info;
320  ss2.info = info_temp;
321 
322  exponent.Swap(ss2.exponent);
323  mantissa.Swap(ss2.mantissa);
324  }
325 
326 
327 private:
328 
329  /*!
330  this method sets the mantissa of the value of pi
331  */
332  void SetMantissaPi()
333  {
334  // this is a static table which represents the value of Pi (mantissa of it)
335  // (first is the highest word)
336  // we must define this table as 'unsigned int' because
337  // both on 32bit and 64bit platforms this table is 32bit
338  static const unsigned int temp_table[] = {
339  0xc90fdaa2, 0x2168c234, 0xc4c6628b, 0x80dc1cd1, 0x29024e08, 0x8a67cc74, 0x020bbea6, 0x3b139b22,
340  0x514a0879, 0x8e3404dd, 0xef9519b3, 0xcd3a431b, 0x302b0a6d, 0xf25f1437, 0x4fe1356d, 0x6d51c245,
341  0xe485b576, 0x625e7ec6, 0xf44c42e9, 0xa637ed6b, 0x0bff5cb6, 0xf406b7ed, 0xee386bfb, 0x5a899fa5,
342  0xae9f2411, 0x7c4b1fe6, 0x49286651, 0xece45b3d, 0xc2007cb8, 0xa163bf05, 0x98da4836, 0x1c55d39a,
343  0x69163fa8, 0xfd24cf5f, 0x83655d23, 0xdca3ad96, 0x1c62f356, 0x208552bb, 0x9ed52907, 0x7096966d,
344  0x670c354e, 0x4abc9804, 0xf1746c08, 0xca18217c, 0x32905e46, 0x2e36ce3b, 0xe39e772c, 0x180e8603,
345  0x9b2783a2, 0xec07a28f, 0xb5c55df0, 0x6f4c52c9, 0xde2bcbf6, 0x95581718, 0x3995497c, 0xea956ae5,
346  0x15d22618, 0x98fa0510, 0x15728e5a, 0x8aaac42d, 0xad33170d, 0x04507a33, 0xa85521ab, 0xdf1cba64,
347  0xecfb8504, 0x58dbef0a, 0x8aea7157, 0x5d060c7d, 0xb3970f85, 0xa6e1e4c7, 0xabf5ae8c, 0xdb0933d7,
348  0x1e8c94e0, 0x4a25619d, 0xcee3d226, 0x1ad2ee6b, 0xf12ffa06, 0xd98a0864, 0xd8760273, 0x3ec86a64,
349  0x521f2b18, 0x177b200c, 0xbbe11757, 0x7a615d6c, 0x770988c0, 0xbad946e2, 0x08e24fa0, 0x74e5ab31,
350  0x43db5bfc, 0xe0fd108e, 0x4b82d120, 0xa9210801, 0x1a723c12, 0xa787e6d7, 0x88719a10, 0xbdba5b26,
351  0x99c32718, 0x6af4e23c, 0x1a946834, 0xb6150bda, 0x2583e9ca, 0x2ad44ce8, 0xdbbbc2db, 0x04de8ef9,
352  0x2e8efc14, 0x1fbecaa6, 0x287c5947, 0x4e6bc05d, 0x99b2964f, 0xa090c3a2, 0x233ba186, 0x515be7ed,
353  0x1f612970, 0xcee2d7af, 0xb81bdd76, 0x2170481c, 0xd0069127, 0xd5b05aa9, 0x93b4ea98, 0x8d8fddc1,
354  0x86ffb7dc, 0x90a6c08f, 0x4df435c9, 0x34028492, 0x36c3fab4, 0xd27c7026, 0xc1d4dcb2, 0x602646de,
355  0xc9751e76, 0x3dba37bd, 0xf8ff9406, 0xad9e530e, 0xe5db382f, 0x413001ae, 0xb06a53ed, 0x9027d831,
356  0x179727b0, 0x865a8918, 0xda3edbeb, 0xcf9b14ed, 0x44ce6cba, 0xced4bb1b, 0xdb7f1447, 0xe6cc254b,
357  0x33205151, 0x2bd7af42, 0x6fb8f401, 0x378cd2bf, 0x5983ca01, 0xc64b92ec, 0xf032ea15, 0xd1721d03,
358  0xf482d7ce, 0x6e74fef6, 0xd55e702f, 0x46980c82, 0xb5a84031, 0x900b1c9e, 0x59e7c97f, 0xbec7e8f3,
359  0x23a97a7e, 0x36cc88be, 0x0f1d45b7, 0xff585ac5, 0x4bd407b2, 0x2b4154aa, 0xcc8f6d7e, 0xbf48e1d8,
360  0x14cc5ed2, 0x0f8037e0, 0xa79715ee, 0xf29be328, 0x06a1d58b, 0xb7c5da76, 0xf550aa3d, 0x8a1fbff0,
361  0xeb19ccb1, 0xa313d55c, 0xda56c9ec, 0x2ef29632, 0x387fe8d7, 0x6e3c0468, 0x043e8f66, 0x3f4860ee,
362  0x12bf2d5b, 0x0b7474d6, 0xe694f91e, 0x6dbe1159, 0x74a3926f, 0x12fee5e4, 0x38777cb6, 0xa932df8c,
363  0xd8bec4d0, 0x73b931ba, 0x3bc832b6, 0x8d9dd300, 0x741fa7bf, 0x8afc47ed, 0x2576f693, 0x6ba42466,
364  0x3aab639c, 0x5ae4f568, 0x3423b474, 0x2bf1c978, 0x238f16cb, 0xe39d652d, 0xe3fdb8be, 0xfc848ad9,
365  0x22222e04, 0xa4037c07, 0x13eb57a8, 0x1a23f0c7, 0x3473fc64, 0x6cea306b, 0x4bcbc886, 0x2f8385dd,
366  0xfa9d4b7f, 0xa2c087e8, 0x79683303, 0xed5bdd3a, 0x062b3cf5, 0xb3a278a6, 0x6d2a13f8, 0x3f44f82d,
367  0xdf310ee0, 0x74ab6a36, 0x4597e899, 0xa0255dc1, 0x64f31cc5, 0x0846851d, 0xf9ab4819, 0x5ded7ea1,
368  0xb1d510bd, 0x7ee74d73, 0xfaf36bc3, 0x1ecfa268, 0x359046f4, 0xeb879f92, 0x4009438b, 0x481c6cd7,
369  0x889a002e, 0xd5ee382b, 0xc9190da6, 0xfc026e47, 0x9558e447, 0x5677e9aa, 0x9e3050e2, 0x765694df,
370  0xc81f56e8, 0x80b96e71, 0x60c980dd, 0x98a573ea, 0x4472065a, 0x139cd290, 0x6cd1cb72, 0x9ec52a53 // last one was: 0x9ec52a52
371  //0x86d44014, ...
372  // (the last word 0x9ec52a52 was rounded up because the next one is 0x86d44014 -- first bit is one 0x8..)
373  // 256 32bit words for the mantissa -- about 2464 valid decimal digits
374  };
375  // the value of PI is comming from the website http://zenwerx.com/pi.php
376  // 3101 digits were taken from this website
377  // (later the digits were compared with:
378  // http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
379  // and they were set into Big<1,400> type (using operator=(const char*) on a 32bit platform)
380  // and then the first 256 words were taken into this table
381  // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
382  // and on 64bit platform value 128 (256/2=128))
383 
384  mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
385  }
386 
387 public:
388 
389 
390  /*!
391  this method sets the value of pi
392  */
393  void SetPi()
394  {
395  // IMPROVE ME
396  // give some compiler-time warning when the size of mantissa is greater than the builtin size of the mantissa pi
397  SetMantissaPi();
398  info = 0;
399  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
400  }
401 
402 
403  /*!
404  this method sets the value of 0.5 * pi
405  */
406  void Set05Pi()
407  {
408  // IMPROVE ME
409  // give some compiler-time warning when the size of mantissa is greater than the builtin size of the mantissa pi
410  SetMantissaPi();
411  info = 0;
412  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
413  }
414 
415 
416  /*!
417  this method sets the value of 2 * pi
418  */
419  void Set2Pi()
420  {
421  // IMPROVE ME
422  // give some compiler-time warning when the size of mantissa is greater than the builtin size of the mantissa pi
423  SetMantissaPi();
424  info = 0;
425  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
426  }
427 
428 
429  /*!
430  this method sets the value of e
431  (the base of the natural logarithm)
432  */
433  void SetE()
434  {
435  static const unsigned int temp_table[] = {
436  0xadf85458, 0xa2bb4a9a, 0xafdc5620, 0x273d3cf1, 0xd8b9c583, 0xce2d3695, 0xa9e13641, 0x146433fb,
437  0xcc939dce, 0x249b3ef9, 0x7d2fe363, 0x630c75d8, 0xf681b202, 0xaec4617a, 0xd3df1ed5, 0xd5fd6561,
438  0x2433f51f, 0x5f066ed0, 0x85636555, 0x3ded1af3, 0xb557135e, 0x7f57c935, 0x984f0c70, 0xe0e68b77,
439  0xe2a689da, 0xf3efe872, 0x1df158a1, 0x36ade735, 0x30acca4f, 0x483a797a, 0xbc0ab182, 0xb324fb61,
440  0xd108a94b, 0xb2c8e3fb, 0xb96adab7, 0x60d7f468, 0x1d4f42a3, 0xde394df4, 0xae56ede7, 0x6372bb19,
441  0x0b07a7c8, 0xee0a6d70, 0x9e02fce1, 0xcdf7e2ec, 0xc03404cd, 0x28342f61, 0x9172fe9c, 0xe98583ff,
442  0x8e4f1232, 0xeef28183, 0xc3fe3b1b, 0x4c6fad73, 0x3bb5fcbc, 0x2ec22005, 0xc58ef183, 0x7d1683b2,
443  0xc6f34a26, 0xc1b2effa, 0x886b4238, 0x611fcfdc, 0xde355b3b, 0x6519035b, 0xbc34f4de, 0xf99c0238,
444  0x61b46fc9, 0xd6e6c907, 0x7ad91d26, 0x91f7f7ee, 0x598cb0fa, 0xc186d91c, 0xaefe1309, 0x85139270,
445  0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x64f2e21e, 0x71f54bff, 0x5cae82ab, 0x9c9df69e,
446  0xe86d2bc5, 0x22363a0d, 0xabc52197, 0x9b0deada, 0x1dbf9a42, 0xd5c4484e, 0x0abcd06b, 0xfa53ddef,
447  0x3c1b20ee, 0x3fd59d7c, 0x25e41d2b, 0x669e1ef1, 0x6e6f52c3, 0x164df4fb, 0x7930e9e4, 0xe58857b6,
448  0xac7d5f42, 0xd69f6d18, 0x7763cf1d, 0x55034004, 0x87f55ba5, 0x7e31cc7a, 0x7135c886, 0xefb4318a,
449  0xed6a1e01, 0x2d9e6832, 0xa907600a, 0x918130c4, 0x6dc778f9, 0x71ad0038, 0x092999a3, 0x33cb8b7a,
450  0x1a1db93d, 0x7140003c, 0x2a4ecea9, 0xf98d0acc, 0x0a8291cd, 0xcec97dcf, 0x8ec9b55a, 0x7f88a46b,
451  0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a,
452  0x23ba4442, 0xcaf53ea6, 0x3bb45432, 0x9b7624c8, 0x917bdd64, 0xb1c0fd4c, 0xb38e8c33, 0x4c701c3a,
453  0xcdad0657, 0xfccfec71, 0x9b1f5c3e, 0x4e46041f, 0x388147fb, 0x4cfdb477, 0xa52471f7, 0xa9a96910,
454  0xb855322e, 0xdb6340d8, 0xa00ef092, 0x350511e3, 0x0abec1ff, 0xf9e3a26e, 0x7fb29f8c, 0x183023c3,
455  0x587e38da, 0x0077d9b4, 0x763e4e4b, 0x94b2bbc1, 0x94c6651e, 0x77caf992, 0xeeaac023, 0x2a281bf6,
456  0xb3a739c1, 0x22611682, 0x0ae8db58, 0x47a67cbe, 0xf9c9091b, 0x462d538c, 0xd72b0374, 0x6ae77f5e,
457  0x62292c31, 0x1562a846, 0x505dc82d, 0xb854338a, 0xe49f5235, 0xc95b9117, 0x8ccf2dd5, 0xcacef403,
458  0xec9d1810, 0xc6272b04, 0x5b3b71f9, 0xdc6b80d6, 0x3fdd4a8e, 0x9adb1e69, 0x62a69526, 0xd43161c1,
459  0xa41d570d, 0x7938dad4, 0xa40e329c, 0xcff46aaa, 0x36ad004c, 0xf600c838, 0x1e425a31, 0xd951ae64,
460  0xfdb23fce, 0xc9509d43, 0x687feb69, 0xedd1cc5e, 0x0b8cc3bd, 0xf64b10ef, 0x86b63142, 0xa3ab8829,
461  0x555b2f74, 0x7c932665, 0xcb2c0f1c, 0xc01bd702, 0x29388839, 0xd2af05e4, 0x54504ac7, 0x8b758282,
462  0x2846c0ba, 0x35c35f5c, 0x59160cc0, 0x46fd8251, 0x541fc68c, 0x9c86b022, 0xbb709987, 0x6a460e74,
463  0x51a8a931, 0x09703fee, 0x1c217e6c, 0x3826e52c, 0x51aa691e, 0x0e423cfc, 0x99e9e316, 0x50c1217b,
464  0x624816cd, 0xad9a95f9, 0xd5b80194, 0x88d9c0a0, 0xa1fe3075, 0xa577e231, 0x83f81d4a, 0x3f2fa457,
465  0x1efc8ce0, 0xba8a4fe8, 0xb6855dfe, 0x72b0a66e, 0xded2fbab, 0xfbe58a30, 0xfafabe1c, 0x5d71a87e,
466  0x2f741ef8, 0xc1fe86fe, 0xa6bbfde5, 0x30677f0d, 0x97d11d49, 0xf7a8443d, 0x0822e506, 0xa9f4614e,
467  0x011e2a94, 0x838ff88c, 0xd68c8bb7, 0xc51eef6d, 0x49ea8ab4, 0xf2c3df5b, 0xb4e0735a, 0xb0d68749
468  // 0x2fe26dd4, ...
469  // 256 32bit words for the mantissa -- about 2464 valid decimal digits
470  };
471 
472  // above value was calculated using Big<1,400> type on a 32bit platform
473  // and then the first 256 words were taken,
474  // the calculating was made by using ExpSurrounding0(1) method
475  // which took 1420 iterations
476  // (the result was compared with e taken from http://antwrp.gsfc.nasa.gov/htmltest/gifcity/e.2mil)
477  // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
478  // and on 64bit platform value 128 (256/2=128))
479 
480  mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
481  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
482  info = 0;
483  }
484 
485 
486  /*!
487  this method sets the value of ln(2)
488  the natural logarithm from 2
489  */
490  void SetLn2()
491  {
492  static const unsigned int temp_table[] = {
493  0xb17217f7, 0xd1cf79ab, 0xc9e3b398, 0x03f2f6af, 0x40f34326, 0x7298b62d, 0x8a0d175b, 0x8baafa2b,
494  0xe7b87620, 0x6debac98, 0x559552fb, 0x4afa1b10, 0xed2eae35, 0xc1382144, 0x27573b29, 0x1169b825,
495  0x3e96ca16, 0x224ae8c5, 0x1acbda11, 0x317c387e, 0xb9ea9bc3, 0xb136603b, 0x256fa0ec, 0x7657f74b,
496  0x72ce87b1, 0x9d6548ca, 0xf5dfa6bd, 0x38303248, 0x655fa187, 0x2f20e3a2, 0xda2d97c5, 0x0f3fd5c6,
497  0x07f4ca11, 0xfb5bfb90, 0x610d30f8, 0x8fe551a2, 0xee569d6d, 0xfc1efa15, 0x7d2e23de, 0x1400b396,
498  0x17460775, 0xdb8990e5, 0xc943e732, 0xb479cd33, 0xcccc4e65, 0x9393514c, 0x4c1a1e0b, 0xd1d6095d,
499  0x25669b33, 0x3564a337, 0x6a9c7f8a, 0x5e148e82, 0x074db601, 0x5cfe7aa3, 0x0c480a54, 0x17350d2c,
500  0x955d5179, 0xb1e17b9d, 0xae313cdb, 0x6c606cb1, 0x078f735d, 0x1b2db31b, 0x5f50b518, 0x5064c18b,
501  0x4d162db3, 0xb365853d, 0x7598a195, 0x1ae273ee, 0x5570b6c6, 0x8f969834, 0x96d4e6d3, 0x30af889b,
502  0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef9, 0x8d6f5177, 0xfbcf0755, 0x268a5c1f, 0x9538b982,
503  0x61affd44, 0x6b1ca3cf, 0x5e9222b8, 0x8c66d3c5, 0x422183ed, 0xc9942109, 0x0bbb16fa, 0xf3d949f2,
504  0x36e02b20, 0xcee886b9, 0x05c128d5, 0x3d0bd2f9, 0x62136319, 0x6af50302, 0x0060e499, 0x08391a0c,
505  0x57339ba2, 0xbeba7d05, 0x2ac5b61c, 0xc4e9207c, 0xef2f0ce2, 0xd7373958, 0xd7622658, 0x901e646a,
506  0x95184460, 0xdc4e7487, 0x156e0c29, 0x2413d5e3, 0x61c1696d, 0xd24aaebd, 0x473826fd, 0xa0c238b9,
507  0x0ab111bb, 0xbd67c724, 0x972cd18b, 0xfbbd9d42, 0x6c472096, 0xe76115c0, 0x5f6f7ceb, 0xac9f45ae,
508  0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd8,
509  0x85db6ab0, 0x3a49bd0d, 0xc0b1b31d, 0x8a0e23fa, 0xc5e5767d, 0xf95884e0, 0x6425a415, 0x26fac51c,
510  0x3ea8449f, 0xe8f70edd, 0x062b1a63, 0xa6c4c60c, 0x52ab3316, 0x1e238438, 0x897a39ce, 0x78b63c9f,
511  0x364f5b8a, 0xef22ec2f, 0xee6e0850, 0xeca42d06, 0xfb0c75df, 0x5497e00c, 0x554b03d7, 0xd2874a00,
512  0x0ca8f58d, 0x94f0341c, 0xbe2ec921, 0x56c9f949, 0xdb4a9316, 0xf281501e, 0x53daec3f, 0x64f1b783,
513  0x154c6032, 0x0e2ff793, 0x33ce3573, 0xfacc5fdc, 0xf1178590, 0x3155bbd9, 0x0f023b22, 0x0224fcd8,
514  0x471bf4f4, 0x45f0a88a, 0x14f0cd97, 0x6ea354bb, 0x20cdb5cc, 0xb3db2392, 0x88d58655, 0x4e2a0e8a,
515  0x6fe51a8c, 0xfaa72ef2, 0xad8a43dc, 0x4212b210, 0xb779dfe4, 0x9d7307cc, 0x846532e4, 0xb9694eda,
516  0xd162af05, 0x3b1751f3, 0xa3d091f6, 0x56658154, 0x12b5e8c2, 0x02461069, 0xac14b958, 0x784934b8,
517  0xd6cce1da, 0xa5053701, 0x1aa4fb42, 0xb9a3def4, 0x1bda1f85, 0xef6fdbf2, 0xf2d89d2a, 0x4b183527,
518  0x8fd94057, 0x89f45681, 0x2b552879, 0xa6168695, 0xc12963b0, 0xff01eaab, 0x73e5b5c1, 0x585318e7,
519  0x624f14a5, 0x1a4a026b, 0x68082920, 0x57fd99b6, 0x6dc085a9, 0x8ac8d8ca, 0xf9eeeea9, 0x8a2400ca,
520  0xc95f260f, 0xd10036f9, 0xf91096ac, 0x3195220a, 0x1a356b2a, 0x73b7eaad, 0xaf6d6058, 0x71ef7afb,
521  0x80bc4234, 0x33562e94, 0xb12dfab4, 0x14451579, 0xdf59eae0, 0x51707062, 0x4012a829, 0x62c59cab,
522  0x347f8304, 0xd889659e, 0x5a9139db, 0x14efcc30, 0x852be3e8, 0xfc99f14d, 0x1d822dd6, 0xe2f76797,
523  0xe30219c8, 0xaa9ce884, 0x8a886eb3, 0xc87b7295, 0x988012e8, 0x314186ed, 0xbaf86856, 0xccd3c3b6,
524  0xee94e62f, 0x110a6783, 0xd2aae89c, 0xcc3b76fc, 0x435a0ce1, 0x34c2838f, 0xd571ec6c, 0x1366a993 // last one was: 0x1366a992
525  //0xcbb9ac40, ...
526  // (the last word 0x1366a992 was rounded up because the next one is 0xcbb9ac40 -- first bit is one 0xc..)
527  // 256 32bit words for the mantissa -- about 2464 valid decimal digits
528  };
529 
530  // above value was calculated using Big<1,400> type on a 32bit platform
531  // and then the first 256 words were taken,
532  // the calculating was made by using LnSurrounding1(2) method
533  // which took 4035 iterations
534  // (the result was compared with ln(2) taken from http://ja0hxv.calico.jp/pai/estart.html)
535  // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
536  // and on 64bit platform value 128 (256/2=128))
537 
538  mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
539  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
540  info = 0;
541  }
542 
543 
544  /*!
545  this method sets the value of ln(10)
546  the natural logarithm from 10
547 
548  I introduced this constant especially to make the conversion ToString()
549  being faster. In fact the method ToString() is keeping values of logarithms
550  it has calculated but it must calculate the logarithm at least once.
551  If a program, which uses this library, is running for a long time this
552  would be ok, but for programs which are running shorter, for example for
553  CGI applications which only once are printing values, this would be much
554  inconvenience. Then if we're printing with base (radix) 10 and the mantissa
555  of our value is smaller than or equal to TTMATH_BUILTIN_VARIABLES_SIZE
556  we don't calculate the logarithm but take it from this constant.
557  */
558  void SetLn10()
559  {
560  static const unsigned int temp_table[] = {
561  0x935d8ddd, 0xaaa8ac16, 0xea56d62b, 0x82d30a28, 0xe28fecf9, 0xda5df90e, 0x83c61e82, 0x01f02d72,
562  0x962f02d7, 0xb1a8105c, 0xcc70cbc0, 0x2c5f0d68, 0x2c622418, 0x410be2da, 0xfb8f7884, 0x02e516d6,
563  0x782cf8a2, 0x8a8c911e, 0x765aa6c3, 0xb0d831fb, 0xef66ceb0, 0x4ab3c6fa, 0x5161bb49, 0xd219c7bb,
564  0xca67b35b, 0x23605085, 0x8e93368d, 0x44789c4f, 0x5b08b057, 0xd5ede20f, 0x469ea58e, 0x9305e981,
565  0xe2478fca, 0xad3aee98, 0x9cd5b42e, 0x6a271619, 0xa47ecb26, 0x978c5d4f, 0xdb1d28ea, 0x57d4fdc0,
566  0xe40bf3cc, 0x1e14126a, 0x45765cde, 0x268339db, 0xf47fa96d, 0xeb271060, 0xaf88486e, 0xa9b7401e,
567  0x3dfd3c51, 0x748e6d6e, 0x3848c8d2, 0x5faf1bca, 0xe88047f1, 0x7b0d9b50, 0xa949eaaa, 0xdf69e8a5,
568  0xf77e3760, 0x4e943960, 0xe38a5700, 0xffde2db1, 0xad6bfbff, 0xd821ba0a, 0x4cb0466d, 0x61ba648e,
569  0xef99c8e5, 0xf6974f36, 0x3982a78c, 0xa45ddfc8, 0x09426178, 0x19127a6e, 0x3b70fcda, 0x2d732d47,
570  0xb5e4b1c8, 0xc0e5a10a, 0xaa6604a5, 0x324ec3dc, 0xbc64ea80, 0x6e198566, 0x1f1d366c, 0x20663834,
571  0x4d5e843f, 0x20642b97, 0x0a62d18e, 0x478f7bd5, 0x8fcd0832, 0x4a7b32a6, 0xdef85a05, 0xeb56323a,
572  0x421ef5e0, 0xb00410a0, 0xa0d9c260, 0x794a976f, 0xf6ff363d, 0xb00b6b33, 0xf42c58de, 0xf8a3c52d,
573  0xed69b13d, 0xc1a03730, 0xb6524dc1, 0x8c167e86, 0x99d6d20e, 0xa2defd2b, 0xd006f8b4, 0xbe145a2a,
574  0xdf3ccbb3, 0x189da49d, 0xbc1261c8, 0xb3e4daad, 0x6a36cecc, 0xb2d5ae5b, 0x89bf752f, 0xb5dfb353,
575  0xff3065c4, 0x0cfceec8, 0x1be5a9a9, 0x67fddc57, 0xc4b83301, 0x006bf062, 0x4b40ed7a, 0x56c6cdcd,
576  0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f8,
577  0xfb5f06c3, 0x58ac8f70, 0xfa9d8c59, 0x8c574502, 0xbaf54c96, 0xc84911f0, 0x0482d095, 0x1a0af022,
578  0xabbab080, 0xec97efd3, 0x671e4e0e, 0x52f166b6, 0xcd5cd226, 0x0dc67795, 0x2e1e34a3, 0xf799677f,
579  0x2c1d48f1, 0x2944b6c5, 0x2ba1307e, 0x704d67f9, 0x1c1035e4, 0x4e927c63, 0x03cf12bf, 0xe2cd2e31,
580  0xf8ee4843, 0x344d51b0, 0xf37da42b, 0x9f0b0fd9, 0x134fb2d9, 0xf815e490, 0xd966283f, 0x23962766,
581  0xeceab1e4, 0xf3b5fc86, 0x468127e2, 0xb606d10d, 0x3a45f4b6, 0xb776102d, 0x2fdbb420, 0x80c8fa84,
582  0xd0ff9f45, 0xc58aef38, 0xdb2410fd, 0x1f1cebad, 0x733b2281, 0x52ca5f36, 0xddf29daa, 0x544334b8,
583  0xdeeaf659, 0x4e462713, 0x1ed485b4, 0x6a0822e1, 0x28db471c, 0xa53938a8, 0x44c3bef7, 0xf35215c8,
584  0xb382bc4e, 0x3e4c6f15, 0x6285f54c, 0x17ab408e, 0xccbf7f5e, 0xd16ab3f6, 0xced2846d, 0xf457e14f,
585  0xbb45d9c5, 0x646ad497, 0xac697494, 0x145de32e, 0x93907128, 0xd263d521, 0x79efb424, 0xd64651d6,
586  0xebc0c9f0, 0xbb583a44, 0xc6412c84, 0x85bb29a6, 0x4d31a2cd, 0x92954469, 0xa32b1abd, 0xf7f5202c,
587  0xa4aa6c93, 0x2e9b53cf, 0x385ab136, 0x2741f356, 0x5de9c065, 0x6009901c, 0x88abbdd8, 0x74efcf73,
588  0x3f761ad4, 0x35f3c083, 0xfd6b8ee0, 0x0bef11c7, 0xc552a89d, 0x58ce4a21, 0xd71e54f2, 0x4157f6c7,
589  0xd4622316, 0xe98956d7, 0x450027de, 0xcbd398d8, 0x4b98b36a, 0x0724c25c, 0xdb237760, 0xe9324b68,
590  0x7523e506, 0x8edad933, 0x92197f00, 0xb853a326, 0xb330c444, 0x65129296, 0x34bc0670, 0xe177806d,
591  0xe338dac4, 0x5537492a, 0xe19add83, 0xcf45000f, 0x5b423bce, 0x6497d209, 0xe30e18a1, 0x3cbf0687,
592  0x67973103, 0xd9485366, 0x81506bba, 0x2e93a9a4, 0x7dd59d3f, 0xf17cd746, 0x8c2075be, 0x552a4348 // last one was: 0x552a4347
593  // 0xb4a638ef, ...
594  //(the last word 0x552a4347 was rounded up because the next one is 0xb4a638ef -- first bit is one 0xb..)
595  // 256 32bit words for the mantissa -- about 2464 valid digits (decimal)
596  };
597 
598  // above value was calculated using Big<1,400> type on a 32bit platform
599  // and then the first 256 32bit words were taken,
600  // the calculating was made by using LnSurrounding1(10) method
601  // which took 22080 iterations
602  // (the result was compared with ln(10) taken from http://ja0hxv.calico.jp/pai/estart.html)
603  // (the formula used in LnSurrounding1(x) converges badly when
604  // the x is greater than one but in fact we can use it, only the
605  // number of iterations will be greater)
606  // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
607  // and on 64bit platform value 128 (256/2=128))
608 
609  mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
610  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
611  info = 0;
612  }
613 
614 
615  /*!
616  this method sets the maximum value which can be held in this type
617  */
618  void SetMax()
619  {
620  info = 0;
621  mantissa.SetMax();
622  exponent.SetMax();
623 
624  // we don't have to use 'Standardizing()' because the last bit from
625  // the mantissa is set
626  }
627 
628 
629  /*!
630  this method sets the minimum value which can be held in this type
631  */
632  void SetMin()
633  {
634  info = 0;
635 
636  mantissa.SetMax();
637  exponent.SetMax();
638  SetSign();
639 
640  // we don't have to use 'Standardizing()' because the last bit from
641  // the mantissa is set
642  }
643 
644 
645  /*!
646  testing whether there is a value zero or not
647  */
648  bool IsZero() const
649  {
650  return IsInfoBit(TTMATH_BIG_ZERO);
651  }
652 
653 
654  /*!
655  this method returns true when there's the sign set
656  also we don't check the NaN flag
657  */
658  bool IsSign() const
659  {
660  return IsInfoBit(TTMATH_BIG_SIGN);
661  }
662 
663 
664  /*!
665  this method returns true when there is not a valid number
666  */
667  bool IsNan() const
668  {
669  return IsInfoBit(TTMATH_BIG_NAN);
670  }
671 
672 
673 
674  /*!
675  this method clears the sign
676  (there'll be an absolute value)
677 
678  samples
679  - -1 -> 1
680  - 2 -> 2
681  */
682  void Abs()
683  {
685  }
686 
687 
688  /*!
689  this method remains the 'sign' of the value
690 
691  samples
692  - -2 = -1
693  - 0 = 0
694  - 10 = 1
695  */
696  void Sgn()
697  {
698  // we have to check the NaN flag, because the next SetOne() method would clear it
699  if( IsNan() )
700  return;
701 
702  if( IsSign() )
703  {
704  SetOne();
705  SetSign();
706  }
707  else
708  if( IsZero() )
709  SetZero(); // !! is nedeed here?
710  else
711  SetOne();
712  }
713 
714 
715 
716  /*!
717  this method sets the sign
718 
719  samples
720  - -1 -> -1
721  - 2 -> -2
722 
723  we do not check whether there is a zero or not, if you're using this method
724  you must be sure that the value is (or will be afterwards) different from zero
725  */
726  void SetSign()
727  {
729  }
730 
731 
732  /*!
733  this method changes the sign
734  when there is a value of zero then the sign is not changed
735 
736  samples
737  - -1 -> 1
738  - 2 -> -2
739  */
740  void ChangeSign()
741  {
742  // we don't have to check the NaN flag here
743 
744  if( IsZero() )
745  return;
746 
747  if( IsSign() )
749  else
751  }
752 
753 
754 
755 private:
756 
757  /*!
758  this method does the half-to-even rounding (banker's rounding)
759 
760  if is_half is:
761  - true - that means the rest was equal the half (0.5 decimal)
762  - false - that means the rest was greater than a half (greater than 0.5 decimal)
763 
764  if the rest was less than a half then don't call this method
765  (the rounding should does nothing then)
766  */
767  uint RoundHalfToEven(bool is_half, bool rounding_up = true)
768  {
769  uint c = 0;
770 
771  if( !is_half || mantissa.IsTheLowestBitSet() )
772  {
773  if( rounding_up )
774  {
775  if( mantissa.AddOne() )
776  {
777  mantissa.Rcr(1, 1);
778  c = exponent.AddOne();
779  }
780  }
781  else
782  {
783  #ifdef TTMATH_DEBUG
784  uint c_from_zero =
785  #endif
786  mantissa.SubOne();
787 
788  // we're using rounding_up=false in Add() when the mantissas have different signs
789  // mantissa can be zero only when previous mantissa was equal to ss2.mantissa
790  // but in such a case 'last_bit_set' will not be set and consequently 'do_rounding' will be false
791  TTMATH_ASSERT( c_from_zero == 0 )
792  }
793  }
794 
795  return c;
796  }
797 
798 
799 
800 
801 
802  /*!
803  *
804  * basic mathematic functions
805  *
806  */
807 
808 
809  /*!
810  this method adds one to the existing value
811  */
812  uint AddOne()
813  {
814  Big<exp, man> one;
815 
816  one.SetOne();
817 
818  return Add(one);
819  }
820 
821 
822  /*!
823  this method subtracts one from the existing value
824  */
825  uint SubOne()
826  {
827  Big<exp, man> one;
828 
829  one.SetOne();
830 
831  return Sub(one);
832  }
833 
834 
835 private:
836 
837 
838  /*!
839  an auxiliary method for adding
840  */
841  void AddCheckExponents( Big<exp, man> & ss2,
842  Int<exp> & exp_offset,
843  bool & last_bit_set,
844  bool & rest_zero,
845  bool & do_adding,
846  bool & do_rounding)
847  {
848  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
849 
850  if( exp_offset == mantissa_size_in_bits )
851  {
852  last_bit_set = ss2.mantissa.IsTheHighestBitSet();
853  rest_zero = ss2.mantissa.AreFirstBitsZero(man*TTMATH_BITS_PER_UINT - 1);
854  do_rounding = true; // we'are only rounding
855  }
856  else
857  if( exp_offset < mantissa_size_in_bits )
858  {
859  uint moved = exp_offset.ToInt(); // how many times we must move ss2.mantissa
860  rest_zero = true;
861 
862  if( moved > 0 )
863  {
864  last_bit_set = static_cast<bool>( ss2.mantissa.GetBit(moved-1) );
865 
866  if( moved > 1 )
867  rest_zero = ss2.mantissa.AreFirstBitsZero(moved - 1);
868 
869  // (2) moving 'exp_offset' times
870  ss2.mantissa.Rcr(moved, 0);
871  }
872 
873  do_adding = true;
874  do_rounding = true;
875  }
876 
877  // if exp_offset is greater than mantissa_size_in_bits then we do nothing
878  // ss2 is too small for taking into consideration in the sum
879  }
880 
881 
882  /*!
883  an auxiliary method for adding
884  */
885  uint AddMantissas( Big<exp, man> & ss2,
886  bool & last_bit_set,
887  bool & rest_zero)
888  {
889  uint c = 0;
890 
891  if( IsSign() == ss2.IsSign() )
892  {
893  // values have the same signs
894  if( mantissa.Add(ss2.mantissa) )
895  {
896  // we have one bit more from addition (carry)
897  // now rest_zero means the old rest_zero with the old last_bit_set
898  rest_zero = (!last_bit_set && rest_zero);
899  last_bit_set = mantissa.Rcr(1,1);
900  c += exponent.AddOne();
901  }
902  }
903  else
904  {
905  // values have different signs
906  // there shouldn't be a carry here because
907  // (1) (2) guarantee that the mantissa of this
908  // is greater than or equal to the mantissa of the ss2
909 
910  #ifdef TTMATH_DEBUG
911  uint c_temp =
912  #endif
913  mantissa.Sub(ss2.mantissa);
914 
915  TTMATH_ASSERT( c_temp == 0 )
916  }
917 
918  return c;
919  }
920 
921 
922 public:
923 
924 
925  /*!
926  Addition this = this + ss2
927 
928  it returns carry if the sum is too big
929  */
930  uint Add(Big<exp, man> ss2, bool round = true, bool adding = true)
931  {
932  bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
933  Int<exp> exp_offset( exponent );
934  uint c = 0;
935 
936  if( IsNan() || ss2.IsNan() )
937  return CheckCarry(1);
938 
939  if( !adding )
940  ss2.ChangeSign(); // subtracting
941 
942  exp_offset.Sub( ss2.exponent );
943  exp_offset.Abs();
944 
945  // (1) abs(this) will be >= abs(ss2)
946  if( SmallerWithoutSignThan(ss2) )
947  Swap(ss2);
948 
949  if( ss2.IsZero() )
950  return 0;
951 
952  last_bit_set = rest_zero = do_adding = do_rounding = false;
953  rounding_up = (IsSign() == ss2.IsSign());
954 
955  AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
956 
957  if( do_adding )
958  c += AddMantissas(ss2, last_bit_set, rest_zero);
959 
960  if( !round || !last_bit_set )
961  do_rounding = false;
962 
963  if( do_rounding )
964  c += RoundHalfToEven(rest_zero, rounding_up);
965 
966  if( do_adding || do_rounding )
967  c += Standardizing();
968 
969  return CheckCarry(c);
970  }
971 
972 
973  /*!
974  Subtraction this = this - ss2
975 
976  it returns carry if the result is too big
977  */
978  uint Sub(const Big<exp, man> & ss2, bool round = true)
979  {
980  return Add(ss2, round, false);
981  }
982 
983 
984  /*!
985  bitwise AND
986 
987  this and ss2 must be >= 0
988 
989  return values:
990  - 0 - ok
991  - 1 - carry
992  - 2 - this or ss2 was negative
993  */
995  {
996  if( IsNan() || ss2.IsNan() )
997  return CheckCarry(1);
998 
999  if( IsSign() || ss2.IsSign() )
1000  {
1001  SetNan();
1002  return 2;
1003  }
1004 
1005  if( IsZero() )
1006  return 0;
1007 
1008  if( ss2.IsZero() )
1009  {
1010  SetZero();
1011  return 0;
1012  }
1013 
1014  Int<exp> exp_offset( exponent );
1015  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
1016 
1017  uint c = 0;
1018 
1019  exp_offset.Sub( ss2.exponent );
1020  exp_offset.Abs();
1021 
1022  // abs(this) will be >= abs(ss2)
1023  if( SmallerWithoutSignThan(ss2) )
1024  Swap(ss2);
1025 
1026  if( exp_offset >= mantissa_size_in_bits )
1027  {
1028  // the second value is too small
1029  SetZero();
1030  return 0;
1031  }
1032 
1033  // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
1034  ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
1035  mantissa.BitAnd(ss2.mantissa);
1036 
1037  c += Standardizing();
1038 
1039  return CheckCarry(c);
1040  }
1041 
1042 
1043  /*!
1044  bitwise OR
1045 
1046  this and ss2 must be >= 0
1047  return values:
1048 
1049  - 0 - ok
1050  - 1 - carry
1051  - 2 - this or ss2 was negative
1052  */
1054  {
1055  if( IsNan() || ss2.IsNan() )
1056  return CheckCarry(1);
1057 
1058  if( IsSign() || ss2.IsSign() )
1059  {
1060  SetNan();
1061  return 2;
1062  }
1063 
1064  if( IsZero() )
1065  {
1066  *this = ss2;
1067  return 0;
1068  }
1069 
1070  if( ss2.IsZero() )
1071  return 0;
1072 
1073  Int<exp> exp_offset( exponent );
1074  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
1075 
1076  uint c = 0;
1077 
1078  exp_offset.Sub( ss2.exponent );
1079  exp_offset.Abs();
1080 
1081  // abs(this) will be >= abs(ss2)
1082  if( SmallerWithoutSignThan(ss2) )
1083  Swap(ss2);
1084 
1085  if( exp_offset >= mantissa_size_in_bits )
1086  // the second value is too small
1087  return 0;
1088 
1089  // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
1090  ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
1091  mantissa.BitOr(ss2.mantissa);
1092 
1093  c += Standardizing();
1094 
1095  return CheckCarry(c);
1096  }
1097 
1098 
1099  /*!
1100  bitwise XOR
1101 
1102  this and ss2 must be >= 0
1103  return values:
1104 
1105  - 0 - ok
1106  - 1 - carry
1107  - 2 - this or ss2 was negative
1108  */
1110  {
1111  if( IsNan() || ss2.IsNan() )
1112  return CheckCarry(1);
1113 
1114  if( IsSign() || ss2.IsSign() )
1115  {
1116  SetNan();
1117  return 2;
1118  }
1119 
1120  if( ss2.IsZero() )
1121  return 0;
1122 
1123  if( IsZero() )
1124  {
1125  *this = ss2;
1126  return 0;
1127  }
1128 
1129  Int<exp> exp_offset( exponent );
1130  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
1131 
1132  uint c = 0;
1133 
1134  exp_offset.Sub( ss2.exponent );
1135  exp_offset.Abs();
1136 
1137  // abs(this) will be >= abs(ss2)
1138  if( SmallerWithoutSignThan(ss2) )
1139  Swap(ss2);
1140 
1141  if( exp_offset >= mantissa_size_in_bits )
1142  // the second value is too small
1143  return 0;
1144 
1145  // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
1146  ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
1147  mantissa.BitXor(ss2.mantissa);
1148 
1149  c += Standardizing();
1150 
1151  return CheckCarry(c);
1152  }
1153 
1154 
1155 
1156  /*!
1157  Multiplication this = this * ss2 (ss2 is uint)
1158 
1159  ss2 without a sign
1160  */
1162  {
1163  UInt<man+1> man_result;
1164  uint i,c = 0;
1165 
1166  if( IsNan() )
1167  return 1;
1168 
1169  if( IsZero() )
1170  return 0;
1171 
1172  if( ss2 == 0 )
1173  {
1174  SetZero();
1175  return 0;
1176  }
1177 
1178  // man_result = mantissa * ss2.mantissa
1179  mantissa.MulInt(ss2, man_result);
1180 
1181  sint bit = UInt<man>::FindLeadingBitInWord(man_result.table[man]); // man - last word
1182 
1183  if( bit!=-1 && uint(bit) > (TTMATH_BITS_PER_UINT/2) )
1184  {
1185  // 'i' will be from 0 to TTMATH_BITS_PER_UINT
1186  i = man_result.CompensationToLeft();
1187  c = exponent.Add( TTMATH_BITS_PER_UINT - i );
1188 
1189  for(i=0 ; i<man ; ++i)
1190  mantissa.table[i] = man_result.table[i+1];
1191  }
1192  else
1193  {
1194  if( bit != -1 )
1195  {
1196  man_result.Rcr(bit+1, 0);
1197  c += exponent.Add(bit+1);
1198  }
1199 
1200  for(i=0 ; i<man ; ++i)
1201  mantissa.table[i] = man_result.table[i];
1202  }
1203 
1204  c += Standardizing();
1205 
1206  return CheckCarry(c);
1207  }
1208 
1209 
1210  /*!
1211  Multiplication this = this * ss2 (ss2 is sint)
1212 
1213  ss2 with a sign
1214  */
1216  {
1217  if( IsNan() )
1218  return 1;
1219 
1220  if( ss2 == 0 )
1221  {
1222  SetZero();
1223  return 0;
1224  }
1225 
1226  if( IsZero() )
1227  return 0;
1228 
1229  if( IsSign() == (ss2<0) )
1230  {
1231  // the signs are the same (both are either - or +), the result is positive
1232  Abs();
1233  }
1234  else
1235  {
1236  // the signs are different, the result is negative
1237  SetSign();
1238  }
1239 
1240  if( ss2<0 )
1241  ss2 = -ss2;
1242 
1243 
1244  return MulUInt( uint(ss2) );
1245  }
1246 
1247 
1248 private:
1249 
1250 
1251  /*!
1252  this method checks whether a table pointed by 'tab' and 'len'
1253  has the value 0.5 decimal
1254  (it is treated as the comma operator would be before the highest bit)
1255  call this method only if the highest bit is set - you have to test it beforehand
1256 
1257  return:
1258  - true - tab was equal the half (0.5 decimal)
1259  - false - tab was greater than a half (greater than 0.5 decimal)
1260 
1261  */
1262  bool CheckGreaterOrEqualHalf(uint * tab, uint len)
1263  {
1264  uint i;
1265 
1266  TTMATH_ASSERT( len>0 && (tab[len-1] & TTMATH_UINT_HIGHEST_BIT)!=0 )
1267 
1268  for(i=0 ; i<len-1 ; ++i)
1269  if( tab[i] != 0 )
1270  return false;
1271 
1272  if( tab[i] != TTMATH_UINT_HIGHEST_BIT )
1273  return false;
1274 
1275  return true;
1276  }
1277 
1278 
1279 private:
1280 
1281  /*!
1282  multiplication this = this * ss2
1283  this method returns a carry
1284  */
1285  uint MulRef(const Big<exp, man> & ss2, bool round = true)
1286  {
1288 
1289  UInt<man*2> man_result;
1290  uint c = 0;
1291  uint i;
1292 
1293  if( IsNan() || ss2.IsNan() )
1294  return CheckCarry(1);
1295 
1296  if( IsZero() )
1297  return 0;
1298 
1299  if( ss2.IsZero() )
1300  {
1301  SetZero();
1302  return 0;
1303  }
1304 
1305  // man_result = mantissa * ss2.mantissa
1306  mantissa.MulBig(ss2.mantissa, man_result);
1307 
1308  // 'i' will be from 0 to man*TTMATH_BITS_PER_UINT
1309  // because mantissa and ss2.mantissa are standardized
1310  // (the highest bit in man_result is set to 1 or
1311  // if there is a zero value in man_result the method CompensationToLeft()
1312  // returns 0 but we'll correct this at the end in Standardizing() method)
1313  i = man_result.CompensationToLeft();
1314  uint exp_add = man * TTMATH_BITS_PER_UINT - i;
1315 
1316  if( exp_add )
1317  c += exponent.Add( exp_add );
1318 
1319  c += exponent.Add( ss2.exponent );
1320 
1321  for(i=0 ; i<man ; ++i)
1322  mantissa.table[i] = man_result.table[i+man];
1323 
1324  if( round && (man_result.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
1325  {
1326  bool is_half = CheckGreaterOrEqualHalf(man_result.table, man);
1327  c += RoundHalfToEven(is_half);
1328  }
1329 
1330  if( IsSign() == ss2.IsSign() )
1331  {
1332  // the signs are the same, the result is positive
1333  Abs();
1334  }
1335  else
1336  {
1337  // the signs are different, the result is negative
1338  // if the value is zero it will be corrected later in Standardizing method
1339  SetSign();
1340  }
1341 
1342  c += Standardizing();
1343 
1344  return CheckCarry(c);
1345  }
1346 
1347 
1348 public:
1349 
1350 
1351  /*!
1352  multiplication this = this * ss2
1353  this method returns a carry
1354  */
1355  uint Mul(const Big<exp, man> & ss2, bool round = true)
1356  {
1357  if( this == &ss2 )
1358  {
1359  Big<exp, man> copy_ss2(ss2);
1360  return MulRef(copy_ss2, round);
1361  }
1362  else
1363  {
1364  return MulRef(ss2, round);
1365  }
1366  }
1367 
1368 
1369 private:
1370 
1371  /*!
1372  division this = this / ss2
1373 
1374  return value:
1375  - 0 - ok
1376  - 1 - carry (in a division carry can be as well)
1377  - 2 - improper argument (ss2 is zero)
1378  */
1379  uint DivRef(const Big<exp, man> & ss2, bool round = true)
1380  {
1382 
1383  UInt<man*2> man1;
1384  UInt<man*2> man2;
1385  uint i,c = 0;
1386 
1387  if( IsNan() || ss2.IsNan() )
1388  return CheckCarry(1);
1389 
1390  if( ss2.IsZero() )
1391  {
1392  SetNan();
1393  return 2;
1394  }
1395 
1396  if( IsZero() )
1397  return 0;
1398 
1399  // !! this two loops can be joined together
1400 
1401  for(i=0 ; i<man ; ++i)
1402  {
1403  man1.table[i+man] = mantissa.table[i];
1404  man2.table[i] = ss2.mantissa.table[i];
1405  }
1406 
1407  for(i=0 ; i<man ; ++i)
1408  {
1409  man1.table[i] = 0;
1410  man2.table[i+man] = 0;
1411  }
1412 
1413  man1.Div(man2);
1414 
1415  i = man1.CompensationToLeft();
1416 
1417  if( i )
1418  c += exponent.Sub(i);
1419 
1420  c += exponent.Sub(ss2.exponent);
1421 
1422  for(i=0 ; i<man ; ++i)
1423  mantissa.table[i] = man1.table[i+man];
1424 
1425  if( round && (man1.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
1426  {
1427  bool is_half = CheckGreaterOrEqualHalf(man1.table, man);
1428  c += RoundHalfToEven(is_half);
1429  }
1430 
1431  if( IsSign() == ss2.IsSign() )
1432  Abs();
1433  else
1434  SetSign(); // if there is a zero it will be corrected in Standardizing()
1435 
1436  c += Standardizing();
1437 
1438  return CheckCarry(c);
1439  }
1440 
1441 
1442 public:
1443 
1444  /*!
1445  division this = this / ss2
1446 
1447  return value:
1448  - 0 - ok
1449  - 1 - carry (in a division carry can be as well)
1450  - 2 - improper argument (ss2 is zero)
1451  */
1452  uint Div(const Big<exp, man> & ss2, bool round = true)
1453  {
1454  if( this == &ss2 )
1455  {
1456  Big<exp, man> copy_ss2(ss2);
1457  return DivRef(copy_ss2, round);
1458  }
1459  else
1460  {
1461  return DivRef(ss2, round);
1462  }
1463  }
1464 
1465 
1466 private:
1467 
1468  /*!
1469  the remainder from a division
1470  */
1471  uint ModRef(const Big<exp, man> & ss2)
1472  {
1474 
1475  uint c = 0;
1476 
1477  if( IsNan() || ss2.IsNan() )
1478  return CheckCarry(1);
1479 
1480  if( ss2.IsZero() )
1481  {
1482  SetNan();
1483  return 2;
1484  }
1485 
1486  if( !SmallerWithoutSignThan(ss2) )
1487  {
1488  Big<exp, man> temp(*this);
1489 
1490  c = temp.Div(ss2);
1491  temp.SkipFraction();
1492  c += temp.Mul(ss2);
1493  c += Sub(temp);
1494 
1495  if( !SmallerWithoutSignThan( ss2 ) )
1496  c += 1;
1497  }
1498 
1499  return CheckCarry(c);
1500  }
1501 
1502 
1503 public:
1504 
1505  /*!
1506  caltulate the remainder from a division
1507 
1508  samples
1509  - 12.6 mod 3 = 0.6 because 12.6 = 3*4 + 0.6
1510  - -12.6 mod 3 = -0.6 bacause -12.6 = 3*(-4) + (-0.6)
1511  - 12.6 mod -3 = 0.6
1512  - -12.6 mod -3 = -0.6
1513 
1514  in other words: this(old) = ss2 * q + this(new)
1515 
1516  return value:
1517  - 0 - ok
1518  - 1 - carry
1519  - 2 - improper argument (ss2 is zero)
1520  */
1521  uint Mod(const Big<exp, man> & ss2)
1522  {
1523  if( this == &ss2 )
1524  {
1525  Big<exp, man> copy_ss2(ss2);
1526  return ModRef(copy_ss2);
1527  }
1528  else
1529  {
1530  return ModRef(ss2);
1531  }
1532  }
1533 
1534 
1535  /*!
1536  this method returns: 'this' mod 2
1537  (either zero or one)
1538 
1539  this method is much faster than using Mod( object_with_value_two )
1540  */
1541  uint Mod2() const
1542  {
1543  if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
1544  return 0;
1545 
1546  sint exp_int = exponent.ToInt();
1547  // 'exp_int' is negative (or zero), we set it as positive
1548  exp_int = -exp_int;
1549 
1550  return mantissa.GetBit(exp_int);
1551  }
1552 
1553 
1554  /*!
1555  power this = this ^ pow
1556  (pow without a sign)
1557 
1558  binary algorithm (r-to-l)
1559 
1560  return values:
1561  - 0 - ok
1562  - 1 - carry
1563  - 2 - incorrect arguments (0^0)
1564  */
1565  template<uint pow_size>
1567  {
1568  if( IsNan() )
1569  return 1;
1570 
1571  if( IsZero() )
1572  {
1573  if( pow.IsZero() )
1574  {
1575  // we don't define zero^zero
1576  SetNan();
1577  return 2;
1578  }
1579 
1580  // 0^(+something) is zero
1581  return 0;
1582  }
1583 
1584  Big<exp, man> start(*this);
1585  Big<exp, man> result;
1586  result.SetOne();
1587  uint c = 0;
1588 
1589  while( !c )
1590  {
1591  if( pow.table[0] & 1 )
1592  c += result.Mul(start);
1593 
1594  pow.Rcr(1);
1595 
1596  if( pow.IsZero() )
1597  break;
1598 
1599  c += start.Mul(start);
1600  }
1601 
1602  *this = result;
1603 
1604  return CheckCarry(c);
1605  }
1606 
1607 
1608  /*!
1609  power this = this ^ pow
1610  p can be negative
1611 
1612  return values:
1613  - 0 - ok
1614  - 1 - carry
1615  - 2 - incorrect arguments 0^0 or 0^(-something)
1616  */
1617  template<uint pow_size>
1619  {
1620  if( IsNan() )
1621  return 1;
1622 
1623  if( !pow.IsSign() )
1624  return Pow( UInt<pow_size>(pow) );
1625 
1626  if( IsZero() )
1627  {
1628  // if 'p' is negative then
1629  // 'this' must be different from zero
1630  SetNan();
1631  return 2;
1632  }
1633 
1634  uint c = pow.ChangeSign();
1635 
1636  Big<exp, man> t(*this);
1637  c += t.Pow( UInt<pow_size>(pow) ); // here can only be a carry (return:1)
1638 
1639  SetOne();
1640  c += Div(t);
1641 
1642  return CheckCarry(c);
1643  }
1644 
1645 
1646  /*!
1647  power this = this ^ abs([pow])
1648  pow is treated as a value without a sign and without a fraction
1649  if pow has a sign then the method pow.Abs() is used
1650  if pow has a fraction the fraction is skipped (not used in calculation)
1651 
1652  return values:
1653  - 0 - ok
1654  - 1 - carry
1655  - 2 - incorrect arguments (0^0)
1656  */
1658  {
1659  if( IsNan() || pow.IsNan() )
1660  return CheckCarry(1);
1661 
1662  if( IsZero() )
1663  {
1664  if( pow.IsZero() )
1665  {
1666  SetNan();
1667  return 2;
1668  }
1669 
1670  // 0^(+something) is zero
1671  return 0;
1672  }
1673 
1674  if( pow.IsSign() )
1675  pow.Abs();
1676 
1677  Big<exp, man> start(*this);
1678  Big<exp, man> result;
1679  Big<exp, man> one;
1680  uint c = 0;
1681  one.SetOne();
1682  result = one;
1683 
1684  while( !c )
1685  {
1686  if( pow.Mod2() )
1687  c += result.Mul(start);
1688 
1689  c += pow.exponent.SubOne();
1690 
1691  if( pow < one )
1692  break;
1693 
1694  c += start.Mul(start);
1695  }
1696 
1697  *this = result;
1698 
1699  return CheckCarry(c);
1700  }
1701 
1702 
1703  /*!
1704  power this = this ^ [pow]
1705  pow is treated as a value without a fraction
1706  pow can be negative
1707 
1708  return values:
1709  - 0 - ok
1710  - 1 - carry
1711  - 2 - incorrect arguments 0^0 or 0^(-something)
1712  */
1714  {
1715  if( IsNan() || pow.IsNan() )
1716  return CheckCarry(1);
1717 
1718  if( !pow.IsSign() )
1719  return PowUInt(pow);
1720 
1721  if( IsZero() )
1722  {
1723  // if 'pow' is negative then
1724  // 'this' must be different from zero
1725  SetNan();
1726  return 2;
1727  }
1728 
1729  Big<exp, man> temp(*this);
1730  uint c = temp.PowUInt(pow); // here can only be a carry (result:1)
1731 
1732  SetOne();
1733  c += Div(temp);
1734 
1735  return CheckCarry(c);
1736  }
1737 
1738 
1739  /*!
1740  power this = this ^ pow
1741  this must be greater than zero (this > 0)
1742  pow can be negative and with fraction
1743 
1744  return values:
1745  - 0 - ok
1746  - 1 - carry
1747  - 2 - incorrect argument ('this' <= 0)
1748  */
1750  {
1751  if( IsNan() || pow.IsNan() )
1752  return CheckCarry(1);
1753 
1754  Big<exp, man> temp;
1755  uint c = temp.Ln(*this);
1756 
1757  if( c != 0 ) // can be 2 from Ln()
1758  {
1759  SetNan();
1760  return c;
1761  }
1762 
1763  c += temp.Mul(pow);
1764  c += Exp(temp);
1765 
1766  return CheckCarry(c);
1767  }
1768 
1769 
1770  /*!
1771  power this = this ^ pow
1772  pow can be negative and with fraction
1773 
1774  return values:
1775  - 0 - ok
1776  - 1 - carry
1777  - 2 - incorrect argument ('this' or 'pow')
1778  */
1779  uint Pow(const Big<exp, man> & pow)
1780  {
1781  if( IsNan() || pow.IsNan() )
1782  return CheckCarry(1);
1783 
1784  if( IsZero() )
1785  {
1786  // 0^pow will be 0 only for pow>0
1787  if( pow.IsSign() || pow.IsZero() )
1788  {
1789  SetNan();
1790  return 2;
1791  }
1792 
1793  SetZero();
1794 
1795  return 0;
1796  }
1797 
1798  if( pow.exponent>-sint(man*TTMATH_BITS_PER_UINT) && pow.exponent<=0 )
1799  {
1800  if( pow.IsInteger() )
1801  return PowInt( pow );
1802  }
1803 
1804  return PowFrac(pow);
1805  }
1806 
1807 
1808  /*!
1809  this function calculates the square root
1810  e.g. let this=9 then this.Sqrt() gives 3
1811 
1812  return:
1813  - 0 - ok
1814  - 1 - carry
1815  - 2 - improper argument (this<0 or NaN)
1816  */
1818  {
1819  if( IsNan() || IsSign() )
1820  {
1821  SetNan();
1822  return 2;
1823  }
1824 
1825  if( IsZero() )
1826  return 0;
1827 
1828  Big<exp, man> old(*this);
1829  Big<exp, man> ln;
1830  uint c = 0;
1831 
1832  // we're using the formula: sqrt(x) = e ^ (ln(x) / 2)
1833  c += ln.Ln(*this);
1834  c += ln.exponent.SubOne(); // ln = ln / 2
1835  c += Exp(ln);
1836 
1837  // above formula doesn't give accurate results for some integers
1838  // e.g. Sqrt(81) would not be 9 but a value very closed to 9
1839  // we're rounding the result, calculating result*result and comparing
1840  // with the old value, if they are equal then the result is an integer too
1841 
1842  if( !c && old.IsInteger() && !IsInteger() )
1843  {
1844  Big<exp, man> temp(*this);
1845  c += temp.Round();
1846 
1847  Big<exp, man> temp2(temp);
1848  c += temp.Mul(temp2);
1849 
1850  if( temp == old )
1851  *this = temp2;
1852  }
1853 
1854  return CheckCarry(c);
1855  }
1856 
1857 
1858 private:
1859 
1860 #ifdef TTMATH_CONSTANTSGENERATOR
1861 public:
1862 #endif
1863 
1864  /*!
1865  Exponent this = exp(x) = e^x where x is in (-1,1)
1866 
1867  we're using the formula exp(x) = 1 + (x)/(1!) + (x^2)/(2!) + (x^3)/(3!) + ...
1868  */
1869  void ExpSurrounding0(const Big<exp,man> & x, uint * steps = 0)
1870  {
1872 
1873  Big<exp,man> denominator, denominator_i;
1874  Big<exp,man> one, old_value, next_part;
1875  Big<exp,man> numerator = x;
1876 
1877  SetOne();
1878  one.SetOne();
1879  denominator.SetOne();
1880  denominator_i.SetOne();
1881 
1882  uint i;
1883  old_value = *this;
1884 
1885  // we begin from 1 in order to not test at the beginning
1886  #ifdef TTMATH_CONSTANTSGENERATOR
1887  for(i=1 ; true ; ++i)
1888  #else
1889  for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
1890  #endif
1891  {
1892  bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
1893 
1894  next_part = numerator;
1895 
1896  if( next_part.Div( denominator ) )
1897  // if there is a carry here we only break the loop
1898  // however the result we return as good
1899  // it means there are too many parts of the formula
1900  break;
1901 
1902  // there shouldn't be a carry here
1903  Add( next_part );
1904 
1905  if( testing )
1906  {
1907  if( old_value == *this )
1908  // we've added next few parts of the formula but the result
1909  // is still the same then we break the loop
1910  break;
1911  else
1912  old_value = *this;
1913  }
1914 
1915  // we set the denominator and the numerator for a next part of the formula
1916  if( denominator_i.Add(one) )
1917  // if there is a carry here the result we return as good
1918  break;
1919 
1920  if( denominator.Mul(denominator_i) )
1921  break;
1922 
1923  if( numerator.Mul(x) )
1924  break;
1925  }
1926 
1927  if( steps )
1928  *steps = i;
1929  }
1930 
1931 public:
1932 
1933 
1934  /*!
1935  Exponent this = exp(x) = e^x
1936 
1937  we're using the fact that our value is stored in form of:
1938 
1939  x = mantissa * 2^exponent
1940 
1941  then
1942 
1943  e^x = e^(mantissa* 2^exponent) or
1944  e^x = (e^mantissa)^(2^exponent)
1945 
1946  'Exp' returns a carry if we can't count the result ('x' is too big)
1947  */
1948  uint Exp(const Big<exp,man> & x)
1949  {
1950  uint c = 0;
1951 
1952  if( x.IsNan() )
1953  return CheckCarry(1);
1954 
1955  if( x.IsZero() )
1956  {
1957  SetOne();
1958  return 0;
1959  }
1960 
1961  // m will be the value of the mantissa in range (-1,1)
1962  Big<exp,man> m(x);
1963  m.exponent = -sint(man*TTMATH_BITS_PER_UINT);
1964 
1965  // 'e_' will be the value of '2^exponent'
1966  // e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT; and
1967  // e_.exponent.Add(1) mean:
1968  // e_.mantissa.table[0] = 1;
1969  // e_.Standardizing();
1970  // e_.exponent.Add(man*TTMATH_BITS_PER_UINT)
1971  // (we must add 'man*TTMATH_BITS_PER_UINT' because we've taken it from the mantissa)
1972  Big<exp,man> e_(x);
1973  e_.mantissa.SetZero();
1974  e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;
1975  c += e_.exponent.Add(1);
1976  e_.Abs();
1977 
1978  /*
1979  now we've got:
1980  m - the value of the mantissa in range (-1,1)
1981  e_ - 2^exponent
1982 
1983  e_ can be as:
1984  ...2^-2, 2^-1, 2^0, 2^1, 2^2 ...
1985  ...1/4 , 1/2 , 1 , 2 , 4 ...
1986 
1987  above one e_ is integer
1988 
1989  if e_ is greater than 1 we calculate the exponent as:
1990  e^(m * e_) = ExpSurrounding0(m) ^ e_
1991  and if e_ is smaller or equal one we calculate the exponent in this way:
1992  e^(m * e_) = ExpSurrounding0(m* e_)
1993  because if e_ is smaller or equal 1 then the product of m*e_ is smaller or equal m
1994  */
1995 
1996  if( e_ <= 1 )
1997  {
1998  m.Mul(e_);
1999  ExpSurrounding0(m);
2000  }
2001  else
2002  {
2003  ExpSurrounding0(m);
2004  c += PowUInt(e_);
2005  }
2006 
2007  return CheckCarry(c);
2008  }
2009 
2010 
2011 
2012 
2013 private:
2014 
2015 #ifdef TTMATH_CONSTANTSGENERATOR
2016 public:
2017 #endif
2018 
2019  /*!
2020  Natural logarithm this = ln(x) where x in range <1,2)
2021 
2022  we're using the formula:
2023  ln x = 2 * [ (x-1)/(x+1) + (1/3)((x-1)/(x+1))^3 + (1/5)((x-1)/(x+1))^5 + ... ]
2024  */
2025  void LnSurrounding1(const Big<exp,man> & x, uint * steps = 0)
2026  {
2027  Big<exp,man> old_value, next_part, denominator, one, two, x1(x), x2(x);
2028 
2029  one.SetOne();
2030 
2031  if( x == one )
2032  {
2033  // LnSurrounding1(1) is 0
2034  SetZero();
2035  return;
2036  }
2037 
2038  two = 2;
2039 
2040  x1.Sub(one);
2041  x2.Add(one);
2042 
2043  x1.Div(x2);
2044  x2 = x1;
2045  x2.Mul(x1);
2046 
2047  denominator.SetOne();
2048  SetZero();
2049 
2050  old_value = *this;
2051  uint i;
2052 
2053 
2054  #ifdef TTMATH_CONSTANTSGENERATOR
2055  for(i=1 ; true ; ++i)
2056  #else
2057  // we begin from 1 in order to not test at the beginning
2058  for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
2059  #endif
2060  {
2061  bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
2062 
2063  next_part = x1;
2064 
2065  if( next_part.Div(denominator) )
2066  // if there is a carry here we only break the loop
2067  // however the result we return as good
2068  // it means there are too many parts of the formula
2069  break;
2070 
2071  // there shouldn't be a carry here
2072  Add(next_part);
2073 
2074  if( testing )
2075  {
2076  if( old_value == *this )
2077  // we've added next (step_test) parts of the formula but the result
2078  // is still the same then we break the loop
2079  break;
2080  else
2081  old_value = *this;
2082  }
2083 
2084  if( x1.Mul(x2) )
2085  // if there is a carry here the result we return as good
2086  break;
2087 
2088  if( denominator.Add(two) )
2089  break;
2090  }
2091 
2092  // this = this * 2
2093  // ( there can't be a carry here because we calculate the logarithm between <1,2) )
2094  exponent.AddOne();
2095 
2096  if( steps )
2097  *steps = i;
2098  }
2099 
2100 
2101 
2102 
2103 public:
2104 
2105 
2106  /*!
2107  Natural logarithm this = ln(x)
2108  (a logarithm with the base equal 'e')
2109 
2110  we're using the fact that our value is stored in form of:
2111 
2112  x = mantissa * 2^exponent
2113 
2114  then
2115 
2116  ln(x) = ln (mantissa * 2^exponent) = ln (mantissa) + (exponent * ln (2))
2117 
2118  the mantissa we'll show as a value from range <1,2) because the logarithm
2119  is decreasing too fast when 'x' is going to 0
2120 
2121  return values:
2122  - 0 - ok
2123  - 1 - overflow (carry)
2124  - 2 - incorrect argument (x<=0)
2125  */
2126  uint Ln(const Big<exp,man> & x)
2127  {
2128  if( x.IsNan() )
2129  return CheckCarry(1);
2130 
2131  if( x.IsSign() || x.IsZero() )
2132  {
2133  SetNan();
2134  return 2;
2135  }
2136 
2137  Big<exp,man> exponent_temp;
2138  exponent_temp.FromInt( x.exponent );
2139 
2140  // m will be the value of the mantissa in range <1,2)
2141  Big<exp,man> m(x);
2142  m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1);
2143 
2144  // we must add 'man*TTMATH_BITS_PER_UINT-1' because we've taken it from the mantissa
2145  uint c = exponent_temp.Add(man*TTMATH_BITS_PER_UINT-1);
2146 
2147  LnSurrounding1(m);
2148 
2149  Big<exp,man> ln2;
2150  ln2.SetLn2();
2151  c += exponent_temp.Mul(ln2);
2152  c += Add(exponent_temp);
2153 
2154  return CheckCarry(c);
2155  }
2156 
2157 
2158  /*!
2159  Logarithm from 'x' with a 'base'
2160 
2161  we're using the formula:
2162 
2163  Log(x) with 'base' = ln(x) / ln(base)
2164 
2165  return values:
2166  - 0 - ok
2167  - 1 - overflow
2168  - 2 - incorrect argument (x<=0)
2169  - 3 - incorrect base (a<=0 or a=1)
2170  */
2171  uint Log(const Big<exp,man> & x, const Big<exp,man> & base)
2172  {
2173  if( x.IsNan() || base.IsNan() )
2174  return CheckCarry(1);
2175 
2176  if( x.IsSign() || x.IsZero() )
2177  {
2178  SetNan();
2179  return 2;
2180  }
2181 
2182  Big<exp,man> denominator;;
2183  denominator.SetOne();
2184 
2185  if( base.IsSign() || base.IsZero() || base==denominator )
2186  {
2187  SetNan();
2188  return 3;
2189  }
2190 
2191  if( x == denominator ) // (this is: if x == 1)
2192  {
2193  // log(1) is 0
2194  SetZero();
2195  return 0;
2196  }
2197 
2198  // another error values we've tested at the beginning
2199  // there can only be a carry
2200  uint c = Ln(x);
2201 
2202  c += denominator.Ln(base);
2203  c += Div(denominator);
2204 
2205  return CheckCarry(c);
2206  }
2207 
2208 
2209 
2210 
2211  /*!
2212  *
2213  * converting methods
2214  *
2215  */
2216 
2217 
2218  /*!
2219  converting from another type of a Big object
2220  */
2221  template<uint another_exp, uint another_man>
2223  {
2224  info = another.info;
2225 
2226  if( IsNan() )
2227  return 1;
2228 
2229  if( exponent.FromInt(another.exponent) )
2230  {
2231  SetNan();
2232  return 1;
2233  }
2234 
2235  uint man_len_min = (man < another_man)? man : another_man;
2236  uint i;
2237  uint c = 0;
2238 
2239  for( i = 0 ; i<man_len_min ; ++i )
2240  mantissa.table[man-1-i] = another.mantissa.table[another_man-1-i];
2241 
2242  for( ; i<man ; ++i )
2243  mantissa.table[man-1-i] = 0;
2244 
2245 
2246  // MS Visual Express 2005 reports a warning (in the lines with 'uint man_diff = ...'):
2247  // warning C4307: '*' : integral constant overflow
2248  // but we're using 'if( man > another_man )' and 'if( man < another_man )' and there'll be no such situation here
2249  #ifdef _MSC_VER
2250  #pragma warning( disable: 4307 )
2251  #endif
2252 
2253  if( man > another_man )
2254  {
2255  uint man_diff = (man - another_man) * TTMATH_BITS_PER_UINT;
2256  c += exponent.SubInt(man_diff, 0);
2257  }
2258  else
2259  if( man < another_man )
2260  {
2261  uint man_diff = (another_man - man) * TTMATH_BITS_PER_UINT;
2262  c += exponent.AddInt(man_diff, 0);
2263  }
2264 
2265  #ifdef _MSC_VER
2266  #pragma warning( default: 4307 )
2267  #endif
2268 
2269  // mantissa doesn't have to be standardized (either the highest bit is set or all bits are equal zero)
2270  CorrectZero();
2271 
2272  return CheckCarry(c);
2273  }
2274 
2275 
2276 private:
2277 
2278  /*!
2279  an auxiliary method for converting 'this' into 'result'
2280  if the value is too big this method returns a carry (1)
2281  */
2282  uint ToUIntOrInt(uint & result) const
2283  {
2284  result = 0;
2285 
2286  if( IsZero() )
2287  return 0;
2288 
2289  sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
2290 
2291  if( exponent > maxbit + sint(TTMATH_BITS_PER_UINT) )
2292  // if exponent > (maxbit + sint(TTMATH_BITS_PER_UINT)) the value can't be passed
2293  // into the 'sint' type (it's too big)
2294  return 1;
2295 
2296  if( exponent <= maxbit )
2297  // our value is from the range of (-1,1) and we return zero
2298  return 0;
2299 
2300  // exponent is from a range of (maxbit, maxbit + sint(TTMATH_BITS_PER_UINT) >
2301  // and [maxbit + sint(TTMATH_BITS_PER_UINT] <= 0
2302  sint how_many_bits = exponent.ToInt();
2303 
2304  // how_many_bits is negative, we'll make it positive
2305  how_many_bits = -how_many_bits;
2306 
2307  result = (mantissa.table[man-1] >> (how_many_bits % TTMATH_BITS_PER_UINT));
2308 
2309  return 0;
2310  }
2311 
2312 
2313 public:
2314 
2315  /*!
2316  this method converts 'this' into uint
2317  */
2318  uint ToUInt() const
2319  {
2320  uint result;
2321 
2322  ToUInt(result);
2323 
2324  return result;
2325  }
2326 
2327 
2328  /*!
2329  this method converts 'this' into 'result'
2330 
2331  if the value is too big this method returns a carry (1)
2332  */
2333  uint ToUInt(uint & result) const
2334  {
2335  if( ToUIntOrInt(result) )
2336  return 1;
2337 
2338  if( IsSign() )
2339  return 1;
2340 
2341  return 0;
2342  }
2343 
2344 
2345  /*!
2346  this method converts 'this' into sint
2347  */
2348  sint ToInt() const
2349  {
2350  sint result;
2351 
2352  ToInt(result);
2353 
2354  return result;
2355  }
2356 
2357 
2358  /*!
2359  this method converts 'this' into 'result'
2360 
2361  if the value is too big this method returns a carry (1)
2362  */
2363  uint ToInt(uint & result) const
2364  {
2365  return ToUInt(result);
2366  }
2367 
2368 
2369  /*!
2370  this method converts 'this' into 'result'
2371 
2372  if the value is too big this method returns a carry (1)
2373  */
2374  uint ToInt(sint & result) const
2375  {
2376  uint result_uint;
2377 
2378  uint c = ToUIntOrInt(result_uint);
2379  result = sint(result_uint);
2380 
2381  if( c )
2382  return 1;
2383 
2384  uint mask = 0;
2385 
2386  if( IsSign() )
2387  {
2388  mask = TTMATH_UINT_MAX_VALUE;
2389  result = -result;
2390  }
2391 
2392  return ((result & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
2393  }
2394 
2395 
2396 private:
2397 
2398  /*!
2399  an auxiliary method for converting 'this' into 'result'
2400 
2401  if the value is too big this method returns a carry (1)
2402  */
2403  template<uint int_size>
2404  uint ToUIntOrInt(UInt<int_size> & result) const
2405  {
2406  result.SetZero();
2407 
2408  if( IsZero() )
2409  return 0;
2410 
2411  sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
2412 
2413  if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )
2414  // if exponent > (maxbit + sint(int_size*TTMATH_BITS_PER_UINT)) the value can't be passed
2415  // into the 'UInt<int_size>' type (it's too big)
2416  return 1;
2417 
2418  if( exponent <= maxbit )
2419  // our value is from range (-1,1) and we return zero
2420  return 0;
2421 
2422  sint how_many_bits = exponent.ToInt();
2423 
2424  if( how_many_bits < 0 )
2425  {
2426  how_many_bits = -how_many_bits;
2427  uint index = how_many_bits / TTMATH_BITS_PER_UINT;
2428 
2429  UInt<man> mantissa_temp(mantissa);
2430  mantissa_temp.Rcr( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
2431 
2432  for(uint i=index, a=0 ; i<man ; ++i,++a)
2433  result.table[a] = mantissa_temp.table[i];
2434  }
2435  else
2436  {
2437  uint index = how_many_bits / TTMATH_BITS_PER_UINT;
2438 
2439  if( index + (man-1) < int_size )
2440  {
2441  // above 'if' is always true
2442  // this is only to get rid of a warning "warning: array subscript is above array bounds"
2443  // (from gcc)
2444  // we checked the condition there: "if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )"
2445  // but gcc doesn't understand our types - exponent is Int<>
2446 
2447  for(uint i=0 ; i<man ; ++i)
2448  result.table[index+i] = mantissa.table[i];
2449  }
2450 
2451  result.Rcl( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
2452  }
2453 
2454  return 0;
2455  }
2456 
2457 
2458 public:
2459 
2460  /*!
2461  this method converts 'this' into 'result'
2462 
2463  if the value is too big this method returns a carry (1)
2464  */
2465  template<uint int_size>
2466  uint ToUInt(UInt<int_size> & result) const
2467  {
2468  uint c = ToUIntOrInt(result);
2469 
2470  if( c )
2471  return 1;
2472 
2473  if( IsSign() )
2474  return 1;
2475 
2476  return 0;
2477  }
2478 
2479 
2480  /*!
2481  this method converts 'this' into 'result'
2482 
2483  if the value is too big this method returns a carry (1)
2484  */
2485  template<uint int_size>
2486  uint ToInt(UInt<int_size> & result) const
2487  {
2488  return ToUInt(result);
2489  }
2490 
2491 
2492  /*!
2493  this method converts 'this' into 'result'
2494 
2495  if the value is too big this method returns a carry (1)
2496  */
2497  template<uint int_size>
2498  uint ToInt(Int<int_size> & result) const
2499  {
2500  uint c = ToUIntOrInt(result);
2501 
2502  if( c )
2503  return 1;
2504 
2505  uint mask = 0;
2506 
2507  if( IsSign() )
2508  {
2509  result.ChangeSign();
2510  mask = TTMATH_UINT_MAX_VALUE;
2511  }
2512 
2513  return ((result.table[int_size-1] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT))? 0 : 1;
2514  }
2515 
2516 
2517  /*!
2518  a method for converting 'uint' to this class
2519  */
2521  {
2522  if( value == 0 )
2523  {
2524  SetZero();
2525  return 0;
2526  }
2527 
2528  info = 0;
2529 
2530  for(uint i=0 ; i<man-1 ; ++i)
2531  mantissa.table[i] = 0;
2532 
2533  mantissa.table[man-1] = value;
2534  exponent = -sint(man-1) * sint(TTMATH_BITS_PER_UINT);
2535 
2536  // there shouldn't be a carry because 'value' has the 'uint' type
2537  Standardizing();
2538 
2539  return 0;
2540  }
2541 
2542 
2543  /*!
2544  a method for converting 'uint' to this class
2545  */
2547  {
2548  return FromUInt(value);
2549  }
2550 
2551 
2552  /*!
2553  a method for converting 'sint' to this class
2554  */
2556  {
2557  bool is_sign = false;
2558 
2559  if( value < 0 )
2560  {
2561  value = -value;
2562  is_sign = true;
2563  }
2564 
2565  FromUInt(uint(value));
2566 
2567  if( is_sign )
2568  SetSign();
2569 
2570  return 0;
2571  }
2572 
2573 
2574 
2575  /*!
2576  this method converts from standard double into this class
2577 
2578  standard double means IEEE-754 floating point value with 64 bits
2579  it is as follows (from http://www.psc.edu/general/software/packages/ieee/ieee.html):
2580 
2581  The IEEE double precision floating point standard representation requires
2582  a 64 bit word, which may be represented as numbered from 0 to 63, left to
2583  right. The first bit is the sign bit, S, the next eleven bits are the
2584  exponent bits, 'E', and the final 52 bits are the fraction 'F':
2585 
2586  S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
2587  0 1 11 12 63
2588 
2589  The value V represented by the word may be determined as follows:
2590 
2591  - If E=2047 and F is nonzero, then V=NaN ("Not a number")
2592  - If E=2047 and F is zero and S is 1, then V=-Infinity
2593  - If E=2047 and F is zero and S is 0, then V=Infinity
2594  - If 0<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
2595  to represent the binary number created by prefixing F with an implicit
2596  leading 1 and a binary point.
2597  - If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
2598  "unnormalized" values.
2599  - If E=0 and F is zero and S is 1, then V=-0
2600  - If E=0 and F is zero and S is 0, then V=0
2601  */
2602 
2603 #ifdef TTMATH_PLATFORM32
2604 
2605  uint FromDouble(double value)
2606  {
2607  // I am not sure what will be on a platform which has
2608  // a different endianness... but we use this library only
2609  // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
2610  union
2611  {
2612  double d;
2613  uint u[2]; // two 32bit words
2614  } temp;
2615 
2616  temp.d = value;
2617 
2618  sint e = ( temp.u[1] & 0x7FF00000u) >> 20;
2619  uint m1 = ((temp.u[1] & 0xFFFFFu) << 11) | (temp.u[0] >> 21);
2620  uint m2 = temp.u[0] << 11;
2621 
2622  if( e == 2047 )
2623  {
2624  // If E=2047 and F is nonzero, then V=NaN ("Not a number")
2625  // If E=2047 and F is zero and S is 1, then V=-Infinity
2626  // If E=2047 and F is zero and S is 0, then V=Infinity
2627 
2628  // we do not support -Infinity and +Infinity
2629  // we assume that there is always NaN
2630 
2631  SetNan();
2632  }
2633  else
2634  if( e > 0 )
2635  {
2636  // If 0<E<2047 then
2637  // V=(-1)**S * 2 ** (E-1023) * (1.F)
2638  // where "1.F" is intended to represent the binary number
2639  // created by prefixing F with an implicit leading 1 and a binary point.
2640 
2641  FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
2642  e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
2643  m1, m2);
2644 
2645  // we do not have to call Standardizing() here
2646  // because the mantissa will have the highest bit set
2647  }
2648  else
2649  {
2650  // e == 0
2651 
2652  if( m1 != 0 || m2 != 0 )
2653  {
2654  // If E=0 and F is nonzero,
2655  // then V=(-1)**S * 2 ** (-1022) * (0.F)
2656  // These are "unnormalized" values.
2657 
2658  UInt<2> m;
2659  m.table[1] = m1;
2660  m.table[0] = m2;
2661  uint moved = m.CompensationToLeft();
2662 
2663  FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
2664  e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
2665  m.table[1], m.table[0]);
2666  }
2667  else
2668  {
2669  // If E=0 and F is zero and S is 1, then V=-0
2670  // If E=0 and F is zero and S is 0, then V=0
2671 
2672  // we do not support -0 or 0, only is one 0
2673  SetZero();
2674  }
2675  }
2676 
2677  return 0; // never be a carry
2678  }
2679 
2680 
2681 private:
2682 
2683  void FromDouble_SetExpAndMan(bool is_sign, int e, uint mhighest, uint m1, uint m2)
2684  {
2685  exponent = e;
2686 
2687  if( man > 1 )
2688  {
2689  mantissa.table[man-1] = m1 | mhighest;
2690  mantissa.table[sint(man-2)] = m2;
2691  // although man>1 we're using casting into sint
2692  // to get rid from a warning which generates Microsoft Visual:
2693  // warning C4307: '*' : integral constant overflow
2694 
2695  for(uint i=0 ; i<man-2 ; ++i)
2696  mantissa.table[i] = 0;
2697  }
2698  else
2699  {
2700  mantissa.table[0] = m1 | mhighest;
2701  }
2702 
2703  info = 0;
2704 
2705  // the value should be different from zero
2706  TTMATH_ASSERT( mantissa.IsZero() == false )
2707 
2708  if( is_sign )
2709  SetSign();
2710  }
2711 
2712 
2713 #else
2714 
2715 public:
2716 
2717  // 64bit platforms
2718  uint FromDouble(double value)
2719  {
2720  // I am not sure what will be on a plaltform which has
2721  // a different endianness... but we use this library only
2722  // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
2723  union
2724  {
2725  double d;
2726  uint u; // one 64bit word
2727  } temp;
2728 
2729  temp.d = value;
2730 
2731  sint e = (temp.u & 0x7FF0000000000000ul) >> 52;
2732  uint m = (temp.u & 0xFFFFFFFFFFFFFul) << 11;
2733 
2734  if( e == 2047 )
2735  {
2736  // If E=2047 and F is nonzero, then V=NaN ("Not a number")
2737  // If E=2047 and F is zero and S is 1, then V=-Infinity
2738  // If E=2047 and F is zero and S is 0, then V=Infinity
2739 
2740  // we do not support -Infinity and +Infinity
2741  // we assume that there is always NaN
2742 
2743  SetNan();
2744  }
2745  else
2746  if( e > 0 )
2747  {
2748  // If 0<E<2047 then
2749  // V=(-1)**S * 2 ** (E-1023) * (1.F)
2750  // where "1.F" is intended to represent the binary number
2751  // created by prefixing F with an implicit leading 1 and a binary point.
2752 
2753  FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
2754  e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
2755  0x8000000000000000ul, m);
2756 
2757  // we do not have to call Standardizing() here
2758  // because the mantissa will have the highest bit set
2759  }
2760  else
2761  {
2762  // e == 0
2763 
2764  if( m != 0 )
2765  {
2766  // If E=0 and F is nonzero,
2767  // then V=(-1)**S * 2 ** (-1022) * (0.F)
2768  // These are "unnormalized" values.
2769 
2770  FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
2771  e - 1022 - man*TTMATH_BITS_PER_UINT + 1, 0, m);
2772  Standardizing();
2773  }
2774  else
2775  {
2776  // If E=0 and F is zero and S is 1, then V=-0
2777  // If E=0 and F is zero and S is 0, then V=0
2778 
2779  // we do not support -0 or 0, only is one 0
2780  SetZero();
2781  }
2782  }
2783 
2784  return 0; // never be a carry
2785  }
2786 
2787 private:
2788 
2789  void FromDouble_SetExpAndMan(bool is_sign, sint e, uint mhighest, uint m)
2790  {
2791  exponent = e;
2792  mantissa.table[man-1] = m | mhighest;
2793 
2794  for(uint i=0 ; i<man-1 ; ++i)
2795  mantissa.table[i] = 0;
2796 
2797  info = 0;
2798 
2799  // the value should be different from zero
2800  TTMATH_ASSERT( mantissa.IsZero() == false )
2801 
2802  if( is_sign )
2803  SetSign();
2804  }
2805 
2806 #endif
2807 
2808 
2809 public:
2810 
2811 
2812  /*!
2813  this method converts from float to this class
2814  */
2815  uint FromFloat(float value)
2816  {
2817  return FromDouble(double(value));
2818  }
2819 
2820 
2821  /*!
2822  this method converts from this class into the 'double'
2823 
2824  if the value is too big:
2825  'result' will be +/-infinity (depending on the sign)
2826 
2827  if the value is too small:
2828  'result' will be 0
2829  */
2830  double ToDouble() const
2831  {
2832  double result;
2833 
2834  ToDouble(result);
2835 
2836  return result;
2837  }
2838 
2839 
2840 private:
2841 
2842 
2843  /*!
2844  an auxiliary method to check if the float value is +/-infinity
2845  we provide this method because isinf(float) in only in C99 language
2846 
2847  description taken from: http://www.psc.edu/general/software/packages/ieee/ieee.php
2848 
2849  The IEEE single precision floating point standard representation requires a 32 bit word,
2850  which may be represented as numbered from 0 to 31, left to right.
2851  The first bit is the sign bit, S, the next eight bits are the exponent bits, 'E',
2852  and the final 23 bits are the fraction 'F':
2853 
2854  S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
2855  0 1 8 9 31
2856 
2857  The value V represented by the word may be determined as follows:
2858 
2859  - If E=255 and F is nonzero, then V=NaN ("Not a number")
2860  - If E=255 and F is zero and S is 1, then V=-Infinity
2861  - If E=255 and F is zero and S is 0, then V=Infinity
2862  - If 0<E<255 then V=(-1)**S * 2 ** (E-127) * (1.F) where "1.F" is intended to represent
2863  the binary number created by prefixing F with an implicit leading 1 and a binary point.
2864  - If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-126) * (0.F) These are "unnormalized" values.
2865  - If E=0 and F is zero and S is 1, then V=-0
2866  - If E=0 and F is zero and S is 0, then V=0
2867  */
2868  bool IsInf(float value) const
2869  {
2870  // CHECK ME
2871  // need testing on a 64 bit machine
2872 
2873  union
2874  {
2875  float d;
2876  uint u;
2877  } temp;
2878 
2879  temp.d = value;
2880 
2881  if( ((temp.u >> 23) & 0xff) == 0xff )
2882  {
2883  if( (temp.u & 0x7FFFFF) == 0 )
2884  return true; // +/- infinity
2885  }
2886 
2887  return false;
2888  }
2889 
2890 
2891 public:
2892 
2893  /*!
2894  this method converts from this class into the 'float'
2895 
2896  if the value is too big:
2897  'result' will be +/-infinity (depending on the sign)
2898 
2899  if the value is too small:
2900  'result' will be 0
2901  */
2902  float ToFloat() const
2903  {
2904  float result;
2905 
2906  ToFloat(result);
2907 
2908  return result;
2909  }
2910 
2911 
2912  /*!
2913  this method converts from this class into the 'float'
2914 
2915  if the value is too big:
2916  - 'result' will be +/-infinity (depending on the sign)
2917  - and the method returns 1
2918 
2919  if the value is too small:
2920  - 'result' will be 0
2921  - and the method returns 1
2922  */
2923  uint ToFloat(float & result) const
2924  {
2925  double result_double;
2926 
2927  uint c = ToDouble(result_double);
2928  result = float(result_double);
2929 
2930  if( result == -0.0f )
2931  result = 0.0f;
2932 
2933  if( c )
2934  return 1;
2935 
2936  // although the result_double can have a correct value
2937  // but after converting to float there can be infinity
2938 
2939  if( IsInf(result) )
2940  return 1;
2941 
2942  if( result == 0.0f && result_double != 0.0 )
2943  // result_double was too small for float
2944  return 1;
2945 
2946  return 0;
2947  }
2948 
2949 
2950  /*!
2951  this method converts from this class into the 'double'
2952 
2953  if the value is too big:
2954  - 'result' will be +/-infinity (depending on the sign)
2955  - and the method returns 1
2956 
2957  if the value is too small:
2958  - 'result' will be 0
2959  - and the method returns 1
2960  */
2961  uint ToDouble(double & result) const
2962  {
2963  if( IsZero() )
2964  {
2965  result = 0.0;
2966  return 0;
2967  }
2968 
2969  if( IsNan() )
2970  {
2971  result = ToDouble_SetDouble( false, 2047, 0, false, true);
2972 
2973  return 0;
2974  }
2975 
2976  sint e_correction = sint(man*TTMATH_BITS_PER_UINT) - 1;
2977 
2978  if( exponent >= 1024 - e_correction )
2979  {
2980  // +/- infinity
2981  result = ToDouble_SetDouble( IsSign(), 2047, 0, true);
2982 
2983  return 1;
2984  }
2985  else
2986  if( exponent <= -1023 - 52 - e_correction )
2987  {
2988  // too small value - we assume that there'll be a zero
2989  result = 0;
2990 
2991  // and return a carry
2992  return 1;
2993  }
2994 
2995  sint e = exponent.ToInt() + e_correction;
2996 
2997  if( e <= -1023 )
2998  {
2999  // -1023-52 < e <= -1023 (unnormalized value)
3000  result = ToDouble_SetDouble( IsSign(), 0, -(e + 1023));
3001  }
3002  else
3003  {
3004  // -1023 < e < 1024
3005  result = ToDouble_SetDouble( IsSign(), e + 1023, -1);
3006  }
3007 
3008  return 0;
3009  }
3010 
3011 private:
3012 
3013 #ifdef TTMATH_PLATFORM32
3014 
3015  // 32bit platforms
3016  double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
3017  {
3018  union
3019  {
3020  double d;
3021  uint u[2]; // two 32bit words
3022  } temp;
3023 
3024  temp.u[0] = temp.u[1] = 0;
3025 
3026  if( is_sign )
3027  temp.u[1] |= 0x80000000u;
3028 
3029  temp.u[1] |= (e << 20) & 0x7FF00000u;
3030 
3031  if( nan )
3032  {
3033  temp.u[0] |= 1;
3034  return temp.d;
3035  }
3036 
3037  if( infinity )
3038  return temp.d;
3039 
3040  UInt<2> m;
3041  m.table[1] = mantissa.table[man-1];
3042  m.table[0] = ( man > 1 ) ? mantissa.table[sint(man-2)] : 0;
3043  // although man>1 we're using casting into sint
3044  // to get rid from a warning which generates Microsoft Visual:
3045  // warning C4307: '*' : integral constant overflow
3046 
3047  m.Rcr( 12 + move );
3048  m.table[1] &= 0xFFFFFu; // cutting the 20 bit (when 'move' was -1)
3049 
3050  temp.u[1] |= m.table[1];
3051  temp.u[0] |= m.table[0];
3052 
3053  return temp.d;
3054  }
3055 
3056 #else
3057 
3058  // 64bit platforms
3059  double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
3060  {
3061  union
3062  {
3063  double d;
3064  uint u; // 64bit word
3065  } temp;
3066 
3067  temp.u = 0;
3068 
3069  if( is_sign )
3070  temp.u |= 0x8000000000000000ul;
3071 
3072  temp.u |= (e << 52) & 0x7FF0000000000000ul;
3073 
3074  if( nan )
3075  {
3076  temp.u |= 1;
3077  return temp.d;
3078  }
3079 
3080  if( infinity )
3081  return temp.d;
3082 
3083  uint m = mantissa.table[man-1];
3084 
3085  m >>= ( 12 + move );
3086  m &= 0xFFFFFFFFFFFFFul; // cutting the 20 bit (when 'move' was -1)
3087  temp.u |= m;
3088 
3089  return temp.d;
3090  }
3091 
3092 #endif
3093 
3094 
3095 public:
3096 
3097 
3098  /*!
3099  an operator= for converting 'sint' to this class
3100  */
3102  {
3103  FromInt(value);
3104 
3105  return *this;
3106  }
3107 
3108 
3109  /*!
3110  an operator= for converting 'uint' to this class
3111  */
3113  {
3114  FromUInt(value);
3115 
3116  return *this;
3117  }
3118 
3119 
3120  /*!
3121  an operator= for converting 'float' to this class
3122  */
3123  Big<exp, man> & operator=(float value)
3124  {
3125  FromFloat(value);
3126 
3127  return *this;
3128  }
3129 
3130 
3131  /*!
3132  an operator= for converting 'double' to this class
3133  */
3134  Big<exp, man> & operator=(double value)
3135  {
3136  FromDouble(value);
3137 
3138  return *this;
3139  }
3140 
3141 
3142  /*!
3143  a constructor for converting 'sint' to this class
3144  */
3145  Big(sint value)
3146  {
3147  FromInt(value);
3148  }
3149 
3150  /*!
3151  a constructor for converting 'uint' to this class
3152  */
3153  Big(uint value)
3154  {
3155  FromUInt(value);
3156  }
3157 
3158 
3159  /*!
3160  a constructor for converting 'double' to this class
3161  */
3162  Big(double value)
3163  {
3164  FromDouble(value);
3165  }
3166 
3167 
3168  /*!
3169  a constructor for converting 'float' to this class
3170  */
3171  Big(float value)
3172  {
3173  FromFloat(value);
3174  }
3175 
3176 
3177 #ifdef TTMATH_PLATFORM32
3178 
3179  /*!
3180  this method converts 'this' into 'result' (64 bit unsigned integer)
3181  if the value is too big this method returns a carry (1)
3182  */
3183  uint ToUInt(ulint & result) const
3184  {
3185  UInt<2> temp; // 64 bits container
3186 
3187  uint c = ToUInt(temp);
3188  temp.ToUInt(result);
3189 
3190  return c;
3191  }
3192 
3193 
3194  /*!
3195  this method converts 'this' into 'result' (64 bit unsigned integer)
3196  if the value is too big this method returns a carry (1)
3197  */
3198  uint ToInt(ulint & result) const
3199  {
3200  return ToUInt(result);
3201  }
3202 
3203 
3204  /*!
3205  this method converts 'this' into 'result' (64 bit unsigned integer)
3206  if the value is too big this method returns a carry (1)
3207  */
3208  uint ToInt(slint & result) const
3209  {
3210  Int<2> temp; // 64 bits container
3211 
3212  uint c = ToInt(temp);
3213  temp.ToInt(result);
3214 
3215  return c;
3216  }
3217 
3218 
3219  /*!
3220  a method for converting 'ulint' (64bit unsigned integer) to this class
3221  */
3222  uint FromUInt(ulint value)
3223  {
3224  if( value == 0 )
3225  {
3226  SetZero();
3227  return 0;
3228  }
3229 
3230  info = 0;
3231 
3232  if( man == 1 )
3233  {
3234  sint bit = mantissa.FindLeadingBitInWord(uint(value >> TTMATH_BITS_PER_UINT));
3235 
3236  if( bit != -1 )
3237  {
3238  // the highest word from value is different from zero
3239  bit += 1;
3240  value >>= bit;
3241  exponent = bit;
3242  }
3243  else
3244  {
3245  exponent.SetZero();
3246  }
3247 
3248  mantissa.table[0] = uint(value);
3249  }
3250  else
3251  {
3252  #ifdef _MSC_VER
3253  //warning C4307: '*' : integral constant overflow
3254  #pragma warning( disable: 4307 )
3255  #endif
3256 
3257  // man >= 2
3258  mantissa.table[man-1] = uint(value >> TTMATH_BITS_PER_UINT);
3259  mantissa.table[man-2] = uint(value);
3260 
3261  #ifdef _MSC_VER
3262  //warning C4307: '*' : integral constant overflow
3263  #pragma warning( default: 4307 )
3264  #endif
3265 
3266  exponent = -sint(man-2) * sint(TTMATH_BITS_PER_UINT);
3267 
3268  for(uint i=0 ; i<man-2 ; ++i)
3269  mantissa.table[i] = 0;
3270  }
3271 
3272  // there shouldn't be a carry because 'value' has the 'ulint' type
3273  // (we have sufficient exponent)
3274  Standardizing();
3275 
3276  return 0;
3277  }
3278 
3279 
3280  /*!
3281  a method for converting 'ulint' (64bit unsigned integer) to this class
3282  */
3283  uint FromInt(ulint value)
3284  {
3285  return FromUInt(value);
3286  }
3287 
3288 
3289  /*!
3290  a method for converting 'slint' (64bit signed integer) to this class
3291  */
3292  uint FromInt(slint value)
3293  {
3294  bool is_sign = false;
3295 
3296  if( value < 0 )
3297  {
3298  value = -value;
3299  is_sign = true;
3300  }
3301 
3302  FromUInt(ulint(value));
3303 
3304  if( is_sign )
3305  SetSign();
3306 
3307  return 0;
3308  }
3309 
3310 
3311  /*!
3312  a constructor for converting 'ulint' (64bit unsigned integer) to this class
3313  */
3314  Big(ulint value)
3315  {
3316  FromUInt(value);
3317  }
3318 
3319 
3320  /*!
3321  an operator for converting 'ulint' (64bit unsigned integer) to this class
3322  */
3323  Big<exp, man> & operator=(ulint value)
3324  {
3325  FromUInt(value);
3326 
3327  return *this;
3328  }
3329 
3330 
3331  /*!
3332  a constructor for converting 'slint' (64bit signed integer) to this class
3333  */
3334  Big(slint value)
3335  {
3336  FromInt(value);
3337  }
3338 
3339 
3340  /*!
3341  an operator for converting 'slint' (64bit signed integer) to this class
3342  */
3343  Big<exp, man> & operator=(slint value)
3344  {
3345  FromInt(value);
3346 
3347  return *this;
3348  }
3349 
3350 #endif
3351 
3352 
3353 
3354 #ifdef TTMATH_PLATFORM64
3355 
3356 
3357  /*!
3358  this method converts 'this' into 'result' (32 bit unsigned integer)
3359  ***this method is created only on a 64bit platform***
3360  if the value is too big this method returns a carry (1)
3361  */
3362  uint ToUInt(unsigned int & result) const
3363  {
3364  uint result_uint;
3365 
3366  uint c = ToUInt(result_uint);
3367  result = (unsigned int)result_uint;
3368 
3369  if( c || result_uint != uint(result) )
3370  return 1;
3371 
3372  return 0;
3373  }
3374 
3375 
3376  /*!
3377  this method converts 'this' into 'result' (32 bit unsigned integer)
3378  ***this method is created only on a 64bit platform***
3379  if the value is too big this method returns a carry (1)
3380  */
3381  uint ToInt(unsigned int & result) const
3382  {
3383  return ToUInt(result);
3384  }
3385 
3386 
3387  /*!
3388  this method converts 'this' into 'result' (32 bit signed integer)
3389  ***this method is created only on a 64bit platform***
3390  if the value is too big this method returns a carry (1)
3391  */
3392  uint ToInt(signed int & result) const
3393  {
3394  sint result_sint;
3395 
3396  uint c = ToInt(result_sint);
3397  result = (signed int)result_sint;
3398 
3399  if( c || result_sint != sint(result) )
3400  return 1;
3401 
3402  return 0;
3403  }
3404 
3405 
3406  /*
3407  this method converts 32 bit unsigned int to this class
3408  ***this method is created only on a 64bit platform***
3409  */
3410  uint FromUInt(unsigned int value)
3411  {
3412  return FromUInt(uint(value));
3413  }
3414 
3415 
3416  /*
3417  this method converts 32 bit unsigned int to this class
3418  ***this method is created only on a 64bit platform***
3419  */
3420  uint FromInt(unsigned int value)
3421  {
3422  return FromUInt(uint(value));
3423  }
3424 
3425 
3426  /*
3427  this method converts 32 bit signed int to this class
3428  ***this method is created only on a 64bit platform***
3429  */
3430  uint FromInt(signed int value)
3431  {
3432  return FromInt(sint(value));
3433  }
3434 
3435 
3436  /*!
3437  an operator= for converting 32 bit unsigned int to this class
3438  ***this operator is created only on a 64bit platform***
3439  */
3440  Big<exp, man> & operator=(unsigned int value)
3441  {
3442  FromUInt(value);
3443 
3444  return *this;
3445  }
3446 
3447 
3448  /*!
3449  a constructor for converting 32 bit unsigned int to this class
3450  ***this constructor is created only on a 64bit platform***
3451  */
3452  Big(unsigned int value)
3453  {
3454  FromUInt(value);
3455  }
3456 
3457 
3458  /*!
3459  an operator for converting 32 bit signed int to this class
3460  ***this operator is created only on a 64bit platform***
3461  */
3462  Big<exp, man> & operator=(signed int value)
3463  {
3464  FromInt(value);
3465 
3466  return *this;
3467  }
3468 
3469 
3470  /*!
3471  a constructor for converting 32 bit signed int to this class
3472  ***this constructor is created only on a 64bit platform***
3473  */
3474  Big(signed int value)
3475  {
3476  FromInt(value);
3477  }
3478 
3479 #endif
3480 
3481 
3482 private:
3483 
3484  /*!
3485  an auxiliary method for converting from UInt and Int
3486 
3487  we assume that there'll never be a carry here
3488  (we have an exponent and the value in Big can be bigger than
3489  that one from the UInt)
3490  */
3491  template<uint int_size>
3492  uint FromUIntOrInt(const UInt<int_size> & value, sint compensation)
3493  {
3494  uint minimum_size = (int_size < man)? int_size : man;
3495  exponent = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation;
3496 
3497  // copying the highest words
3498  uint i;
3499  for(i=1 ; i<=minimum_size ; ++i)
3500  mantissa.table[man-i] = value.table[int_size-i];
3501 
3502  // setting the rest of mantissa.table into zero (if some has left)
3503  for( ; i<=man ; ++i)
3504  mantissa.table[man-i] = 0;
3505 
3506  // the highest bit is either one or zero (when the whole mantissa is zero)
3507  // we can only call CorrectZero()
3508  CorrectZero();
3509 
3510  return 0;
3511  }
3512 
3513 
3514 public:
3515 
3516  /*!
3517  a method for converting from 'UInt<int_size>' to this class
3518  */
3519  template<uint int_size>
3521  {
3522  info = 0;
3523  sint compensation = (sint)value.CompensationToLeft();
3524 
3525  return FromUIntOrInt(value, compensation);
3526  }
3527 
3528 
3529  /*!
3530  a method for converting from 'UInt<int_size>' to this class
3531  */
3532  template<uint int_size>
3533  uint FromInt(const UInt<int_size> & value)
3534  {
3535  return FromUInt(value);
3536  }
3537 
3538 
3539  /*!
3540  a method for converting from 'Int<int_size>' to this class
3541  */
3542  template<uint int_size>
3544  {
3545  info = 0;
3546  bool is_sign = false;
3547 
3548  if( value.IsSign() )
3549  {
3550  value.ChangeSign();
3551  is_sign = true;
3552  }
3553 
3554  sint compensation = (sint)value.CompensationToLeft();
3555  FromUIntOrInt(value, compensation);
3556 
3557  if( is_sign )
3558  SetSign();
3559 
3560  return 0;
3561  }
3562 
3563 
3564  /*!
3565  an operator= for converting from 'Int<int_size>' to this class
3566  */
3567  template<uint int_size>
3569  {
3570  FromInt(value);
3571 
3572  return *this;
3573  }
3574 
3575 
3576  /*!
3577  a constructor for converting from 'Int<int_size>' to this class
3578  */
3579  template<uint int_size>
3580  Big(const Int<int_size> & value)
3581  {
3582  FromInt(value);
3583  }
3584 
3585 
3586  /*!
3587  an operator= for converting from 'UInt<int_size>' to this class
3588  */
3589  template<uint int_size>
3591  {
3592  FromUInt(value);
3593 
3594  return *this;
3595  }
3596 
3597 
3598  /*!
3599  a constructor for converting from 'UInt<int_size>' to this class
3600  */
3601  template<uint int_size>
3602  Big(const UInt<int_size> & value)
3603  {
3604  FromUInt(value);
3605  }
3606 
3607 
3608  /*!
3609  an operator= for converting from 'Big<another_exp, another_man>' to this class
3610  */
3611  template<uint another_exp, uint another_man>
3613  {
3614  FromBig(value);
3615 
3616  return *this;
3617  }
3618 
3619 
3620  /*!
3621  a constructor for converting from 'Big<another_exp, another_man>' to this class
3622  */
3623  template<uint another_exp, uint another_man>
3625  {
3626  FromBig(value);
3627  }
3628 
3629 
3630  /*!
3631  a default constructor
3632 
3633  by default we don't set any of the members to zero
3634  only NaN flag is set
3635 
3636  if you want the mantissa and exponent to be set to zero
3637  define TTMATH_BIG_DEFAULT_CLEAR macro
3638  (useful for debug purposes)
3639  */
3641  {
3642  #ifdef TTMATH_BIG_DEFAULT_CLEAR
3643 
3644  SetZeroNan();
3645 
3646  #else
3647 
3648  info = TTMATH_BIG_NAN;
3649  // we're directly setting 'info' (instead of calling SetNan())
3650  // in order to get rid of a warning saying that 'info' is uninitialized
3651 
3652  #endif
3653  }
3654 
3655 
3656  /*!
3657  a destructor
3658  */
3660  {
3661  }
3662 
3663 
3664  /*!
3665  the default assignment operator
3666  */
3668  {
3669  info = value.info;
3670  exponent = value.exponent;
3671  mantissa = value.mantissa;
3672 
3673  return *this;
3674  }
3675 
3676 
3677  /*!
3678  a constructor for copying from another object of this class
3679  */
3680 
3681  Big(const Big<exp,man> & value)
3682  {
3683  operator=(value);
3684  }
3685 
3686 
3687 
3688  /*!
3689  a method for converting into a string
3690  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3691 
3692  return value:
3693  - 0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
3694  - 1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
3695  is somewhere an error in the library)
3696  */
3697  uint ToString( std::string & result,
3698  uint base = 10,
3699  bool scient = false,
3700  sint scient_from = 15,
3701  sint round = -1,
3702  bool trim_zeroes = true,
3703  char comma = '.' ) const
3704  {
3705  Conv conv;
3706 
3707  conv.base = base;
3708  conv.scient = scient;
3709  conv.scient_from = scient_from;
3710  conv.round = round;
3711  conv.trim_zeroes = trim_zeroes;
3712  conv.comma = static_cast<uint>(comma);
3713 
3714  return ToStringBase<std::string, char>(result, conv);
3715  }
3716 
3717 
3718  /*!
3719  a method for converting into a string
3720  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3721  */
3722  uint ToString(std::string & result, const Conv & conv) const
3723  {
3724  return ToStringBase<std::string, char>(result, conv);
3725  }
3726 
3727 
3728  /*!
3729  a method for converting into a string
3730  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3731  */
3732  std::string ToString(const Conv & conv) const
3733  {
3734  std::string result;
3735  ToStringBase<std::string, char>(result, conv);
3736 
3737  return result;
3738  }
3739 
3740 
3741  /*!
3742  a method for converting into a string
3743  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3744  */
3745  std::string ToString(uint base = 10) const
3746  {
3747  Conv conv;
3748  conv.base = base;
3749 
3750  return ToString(conv);
3751  }
3752 
3753 
3754 
3755 #ifndef TTMATH_DONT_USE_WCHAR
3756 
3757 
3758  /*!
3759  a method for converting into a string
3760  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3761  */
3762  uint ToString( std::wstring & result,
3763  uint base = 10,
3764  bool scient = false,
3765  sint scient_from = 15,
3766  sint round = -1,
3767  bool trim_zeroes = true,
3768  wchar_t comma = '.' ) const
3769  {
3770  Conv conv;
3771 
3772  conv.base = base;
3773  conv.scient = scient;
3774  conv.scient_from = scient_from;
3775  conv.round = round;
3776  conv.trim_zeroes = trim_zeroes;
3777  conv.comma = static_cast<uint>(comma);
3778 
3779  return ToStringBase<std::wstring, wchar_t>(result, conv);
3780  }
3781 
3782 
3783  /*!
3784  a method for converting into a string
3785  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3786  */
3787  uint ToString(std::wstring & result, const Conv & conv) const
3788  {
3789  return ToStringBase<std::wstring, wchar_t>(result, conv);
3790  }
3791 
3792 
3793  /*!
3794  a method for converting into a string
3795  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3796  */
3797  std::wstring ToWString(const Conv & conv) const
3798  {
3799  std::wstring result;
3800  ToStringBase<std::wstring, wchar_t>(result, conv);
3801 
3802  return result;
3803  }
3804 
3805 
3806  /*!
3807  a method for converting into a string
3808  struct Conv is defined in ttmathtypes.h, look there for more information about parameters
3809  */
3810  std::wstring ToWString(uint base = 10) const
3811  {
3812  Conv conv;
3813  conv.base = base;
3814 
3815  return ToWString(conv);
3816  }
3817 
3818 #endif
3819 
3820 
3821 
3822 private:
3823 
3824 
3825  /*!
3826  an auxiliary method for converting into the string
3827  */
3828  template<class string_type, class char_type>
3829  uint ToStringBase(string_type & result, const Conv & conv) const
3830  {
3831  static char error_overflow_msg[] = "overflow";
3832  static char error_nan_msg[] = "NaN";
3833  result.erase();
3834 
3835  if( IsNan() )
3836  {
3837  Misc::AssignString(result, error_nan_msg);
3838  return 0;
3839  }
3840 
3841  if( conv.base<2 || conv.base>16 )
3842  {
3843  Misc::AssignString(result, error_overflow_msg);
3844  return 1;
3845  }
3846 
3847  if( IsZero() )
3848  {
3849  result = '0';
3850 
3851  return 0;
3852  }
3853 
3854  /*
3855  since 'base' is greater or equal 2 that 'new_exp' of type 'Int<exp>' should
3856  hold the new value of exponent but we're using 'Int<exp+1>' because
3857  if the value for example would be 'max()' then we couldn't show it
3858 
3859  max() -> 11111111 * 2 ^ 11111111111 (bin)(the mantissa and exponent have all bits set)
3860  if we were using 'Int<exp>' we couldn't show it in this format:
3861  1,1111111 * 2 ^ 11111111111 (bin)
3862  because we have to add something to the mantissa and because
3863  mantissa is full we can't do it and it'll be a carry
3864  (look at ToString_SetCommaAndExponent(...))
3865 
3866  when the base would be greater than two (for example 10)
3867  we could use 'Int<exp>' here
3868  */
3869  Int<exp+1> new_exp;
3870 
3871  if( ToString_CreateNewMantissaAndExponent<string_type, char_type>(result, conv, new_exp) )
3872  {
3873  Misc::AssignString(result, error_overflow_msg);
3874  return 1;
3875  }
3876 
3877 
3878  if( ToString_SetCommaAndExponent<string_type, char_type>(result, conv, new_exp) )
3879  {
3880  Misc::AssignString(result, error_overflow_msg);
3881  return 1;
3882  }
3883 
3884  if( IsSign() )
3885  result.insert(result.begin(), '-');
3886 
3887 
3888  // converted successfully
3889  return 0;
3890  }
3891 
3892 
3893 
3894  /*!
3895  in the method 'ToString_CreateNewMantissaAndExponent()' we're using
3896  type 'Big<exp+1,man>' and we should have the ability to use some
3897  necessary methods from that class (methods which are private here)
3898  */
3899  friend class Big<exp-1,man>;
3900 
3901 
3902  /*!
3903  an auxiliary method for converting into the string
3904 
3905  input:
3906  base - the base in range <2,16>
3907 
3908  output:
3909  return values:
3910  0 - ok
3911  1 - if there was a carry
3912  new_man - the new mantissa for 'base'
3913  new_exp - the new exponent for 'base'
3914 
3915  mathematic part:
3916 
3917  the value is stored as:
3918  value = mantissa * 2^exponent
3919  we want to show 'value' as:
3920  value = new_man * base^new_exp
3921 
3922  then 'new_man' we'll print using the standard method from UInt<> type for printing
3923  and 'new_exp' is the offset of the comma operator in a system of a base 'base'
3924 
3925  value = mantissa * 2^exponent
3926  value = mantissa * 2^exponent * (base^new_exp / base^new_exp)
3927  value = mantissa * (2^exponent / base^new_exp) * base^new_exp
3928 
3929  look at the part (2^exponent / base^new_exp), there'll be good if we take
3930  a 'new_exp' equal that value when the (2^exponent / base^new_exp) will be equal one
3931 
3932  on account of the 'base' is not as power of 2 (can be from 2 to 16),
3933  this formula will not be true for integer 'new_exp' then in our case we take
3934  'base^new_exp' _greater_ than '2^exponent'
3935 
3936  if 'base^new_exp' were smaller than '2^exponent' the new mantissa could be
3937  greater than the max value of the container UInt<man>
3938 
3939  value = mantissa * (2^exponent / base^new_exp) * base^new_exp
3940  let M = mantissa * (2^exponent / base^new_exp) then
3941  value = M * base^new_exp
3942 
3943  in our calculation we treat M as floating value showing it as:
3944  M = mm * 2^ee where ee will be <= 0
3945 
3946  next we'll move all bits of mm into the right when ee is equal zero
3947  abs(ee) must not be too big that only few bits from mm we can leave
3948 
3949  then we'll have:
3950  M = mmm * 2^0
3951  'mmm' is the new_man which we're looking for
3952 
3953 
3954  new_exp we calculate in this way:
3955  2^exponent <= base^new_exp
3956  new_exp >= log base (2^exponent) <- logarithm with the base 'base' from (2^exponent)
3957 
3958  but we need new_exp as integer then we test:
3959  if new_exp is greater than zero and with fraction we add one to new_exp
3960  new_exp = new_exp + 1 (if new_exp>0 and with fraction)
3961  and at the end we take the integer part:
3962  new_exp = int(new_exp)
3963  */
3964  template<class string_type, class char_type>
3965  uint ToString_CreateNewMantissaAndExponent( string_type & new_man, const Conv & conv,
3966  Int<exp+1> & new_exp) const
3967  {
3968  uint c = 0;
3969 
3970  if( conv.base<2 || conv.base>16 )
3971  return 1;
3972 
3973  // special method for base equal 2
3974  if( conv.base == 2 )
3975  return ToString_CreateNewMantissaAndExponent_Base2(new_man, new_exp);
3976 
3977  // special method for base equal 4
3978  if( conv.base == 4 )
3979  return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 2);
3980 
3981  // special method for base equal 8
3982  if( conv.base == 8 )
3983  return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 3);
3984 
3985  // special method for base equal 16
3986  if( conv.base == 16 )
3987  return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 4);
3988 
3989 
3990  // this = mantissa * 2^exponent
3991 
3992  // temp = +1 * 2^exponent
3993  // we're using a bigger type than 'big<exp,man>' (look below)
3994  Big<exp+1,man> temp;
3995  temp.info = 0;
3996  temp.exponent = exponent;
3997  temp.mantissa.SetOne();
3998  c += temp.Standardizing();
3999 
4000  // new_exp_ = log base (2^exponent)
4001  // if new_exp_ is positive and with fraction then we add one
4002  Big<exp+1,man> new_exp_;
4003  c += new_exp_.ToString_Log(temp, conv.base); // this logarithm isn't very complicated
4004 
4005  // rounding up to the nearest integer
4006  if( !new_exp_.IsInteger() )
4007  {
4008  if( !new_exp_.IsSign() )
4009  c += new_exp_.AddOne(); // new_exp_ > 0 and with fraction
4010 
4011  new_exp_.SkipFraction();
4012  }
4013 
4014  if( ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp) )
4015  {
4016  // in very rare cases there can be an overflow from ToString_CreateNewMantissaTryExponent
4017  // it means that new_exp_ was too small (the problem comes from floating point numbers precision)
4018  // so we increse new_exp_ and try again
4019  new_exp_.AddOne();
4020  c += ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp);
4021  }
4022 
4023  return (c==0)? 0 : 1;
4024  }
4025 
4026 
4027 
4028  /*!
4029  an auxiliary method for converting into the string
4030 
4031  trying to calculate new_man for given exponent (new_exp_)
4032  if there is a carry it can mean that new_exp_ is too small
4033  */
4034  template<class string_type, class char_type>
4035  uint ToString_CreateNewMantissaTryExponent( string_type & new_man, const Conv & conv,
4036  const Big<exp+1,man> & new_exp_, Int<exp+1> & new_exp) const
4037  {
4038  uint c = 0;
4039 
4040  // because 'base^new_exp' is >= '2^exponent' then
4041  // because base is >= 2 then we've got:
4042  // 'new_exp_' must be smaller or equal 'new_exp'
4043  // and we can pass it into the Int<exp> type
4044  // (in fact we're using a greater type then it'll be ok)
4045  c += new_exp_.ToInt(new_exp);
4046 
4047  // base_ = base
4048  Big<exp+1,man> base_(conv.base);
4049 
4050  // base_ = base_ ^ new_exp_
4051  c += base_.Pow( new_exp_ ); // use new_exp_ so Pow(Big<> &) version will be used
4052  // if we hadn't used a bigger type than 'Big<exp,man>' then the result
4053  // of this formula 'Pow(...)' would have been with an overflow
4054 
4055  // temp = mantissa * 2^exponent / base_^new_exp_
4056  Big<exp+1,man> temp;
4057  temp.info = 0;
4058  temp.mantissa = mantissa;
4059  temp.exponent = exponent;
4060  c += temp.Div(base_);
4061 
4062  // moving all bits of the mantissa into the right
4063  // (how many times to move depend on the exponent)
4064  c += temp.ToString_MoveMantissaIntoRight();
4065 
4066  // because we took 'new_exp' as small as it was
4067  // possible ([log base (2^exponent)] + 1) that after the division
4068  // (temp.Div( base_ )) the value of exponent should be equal zero or
4069  // minimum smaller than zero then we've got the mantissa which has
4070  // maximum valid bits
4071  temp.mantissa.ToString(new_man, conv.base);
4072 
4073  if( IsInteger() )
4074  {
4075  // making sure the new mantissa will be without fraction (integer)
4076  ToString_CheckMantissaInteger<string_type, char_type>(new_man, new_exp);
4077  }
4078  else
4079  if( conv.base_round )
4080  {
4081  c += ToString_BaseRound<string_type, char_type>(new_man, conv, new_exp);
4082  }
4083 
4084  return (c==0)? 0 : 1;
4085  }
4086 
4087 
4088  /*!
4089  this method calculates the logarithm
4090  it is used by ToString_CreateNewMantissaAndExponent() method
4091 
4092  it's not too complicated
4093  because x=+1*2^exponent (mantissa is one) then during the calculation
4094  the Ln(x) will not be making the long formula from LnSurrounding1()
4095  and only we have to calculate 'Ln(base)' but it'll be calculated
4096  only once, the next time we will get it from the 'history'
4097 
4098  x is greater than 0
4099  base is in <2,16> range
4100  */
4101  uint ToString_Log(const Big<exp,man> & x, uint base)
4102  {
4104  TTMATH_ASSERT( base>=2 && base<=16 )
4105 
4106  Big<exp,man> temp;
4107  temp.SetOne();
4108 
4109  if( x == temp )
4110  {
4111  // log(1) is 0
4112  SetZero();
4113 
4114  return 0;
4115  }
4116 
4117  // there can be only a carry
4118  // because the 'x' is in '1+2*exponent' form then
4119  // the long formula from LnSurrounding1() will not be calculated
4120  // (LnSurrounding1() will return one immediately)
4121  uint c = Ln(x);
4122 
4123  if( base==10 && man<=TTMATH_BUILTIN_VARIABLES_SIZE )
4124  {
4125  // for the base equal 10 we're using SetLn10() instead of calculating it
4126  // (only if we have the constant sufficient big)
4127  temp.SetLn10();
4128  }
4129  else
4130  {
4131  c += ToString_LogBase(base, temp);
4132  }
4133 
4134  c += Div( temp );
4135 
4136  return (c==0)? 0 : 1;
4137  }
4138 
4139 
4140 #ifndef TTMATH_MULTITHREADS
4141 
4142  /*!
4143  this method calculates the logarithm of 'base'
4144  it's used in single thread environment
4145  */
4146  uint ToString_LogBase(uint base, Big<exp,man> & result)
4147  {
4148  TTMATH_ASSERT( base>=2 && base<=16 )
4149 
4150  // this guardians are initialized before the program runs (static POD types)
4151  static int guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4152  static Big<exp,man> log_history[15];
4153  uint index = base - 2;
4154  uint c = 0;
4155 
4156  if( guardians[index] == 0 )
4157  {
4158  Big<exp,man> base_(base);
4159  c += log_history[index].Ln(base_);
4160  guardians[index] = 1;
4161  }
4162 
4163  result = log_history[index];
4164 
4165  return (c==0)? 0 : 1;
4166  }
4167 
4168 #else
4169 
4170  /*!
4171  this method calculates the logarithm of 'base'
4172  it's used in multi-thread environment
4173  */
4174  uint ToString_LogBase(uint base, Big<exp,man> & result)
4175  {
4176  TTMATH_ASSERT( base>=2 && base<=16 )
4177 
4178  // this guardians are initialized before the program runs (static POD types)
4179  volatile static sig_atomic_t guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4180  static Big<exp,man> * plog_history;
4181  uint index = base - 2;
4182  uint c = 0;
4183 
4184  // double-checked locking
4185  if( guardians[index] == 0 )
4186  {
4187  ThreadLock thread_lock;
4188 
4189  // locking
4190  if( thread_lock.Lock() )
4191  {
4192  static Big<exp,man> log_history[15];
4193 
4194  if( guardians[index] == 0 )
4195  {
4196  plog_history = log_history;
4197 
4198  Big<exp,man> base_(base);
4199  c += log_history[index].Ln(base_);
4200  guardians[index] = 1;
4201  }
4202  }
4203  else
4204  {
4205  // there was a problem with locking, we store the result directly in 'result' object
4206  Big<exp,man> base_(base);
4207  c += result.Ln(base_);
4208 
4209  return (c==0)? 0 : 1;
4210  }
4211 
4212  // automatically unlocking
4213  }
4214 
4215  result = plog_history[index];
4216 
4217  return (c==0)? 0 : 1;
4218  }
4219 
4220 #endif
4221 
4222  /*!
4223  an auxiliary method for converting into the string (private)
4224 
4225  this method moving all bits from mantissa into the right side
4226  the exponent tell us how many times moving (the exponent is <=0)
4227  */
4228  uint ToString_MoveMantissaIntoRight()
4229  {
4230  if( exponent.IsZero() )
4231  return 0;
4232 
4233  // exponent can't be greater than zero
4234  // because we would cat the highest bits of the mantissa
4235  if( !exponent.IsSign() )
4236  return 1;
4237 
4238 
4239  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
4240  {
4241  // if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
4242  // it means that we must cut the whole mantissa
4243  // (there'll not be any of the valid bits)
4244  return 1;
4245  }
4246 
4247  // e will be from (-man*TTMATH_BITS_PER_UINT, 0>
4248  sint e = -( exponent.ToInt() );
4249  mantissa.Rcr(e,0);
4250 
4251  return 0;
4252  }
4253 
4254 
4255  /*!
4256  a special method similar to the 'ToString_CreateNewMantissaAndExponent'
4257  when the 'base' is equal 2
4258 
4259  we use it because if base is equal 2 we don't have to make those
4260  complicated calculations and the output is directly from the source
4261  (there will not be any small distortions)
4262  */
4263  template<class string_type>
4264  uint ToString_CreateNewMantissaAndExponent_Base2( string_type & new_man,
4265  Int<exp+1> & new_exp ) const
4266  {
4267  for( sint i=man-1 ; i>=0 ; --i )
4268  {
4269  uint value = mantissa.table[i];
4270 
4271  for( uint bit=0 ; bit<TTMATH_BITS_PER_UINT ; ++bit )
4272  {
4273  if( (value & TTMATH_UINT_HIGHEST_BIT) != 0 )
4274  new_man += '1';
4275  else
4276  new_man += '0';
4277 
4278  value <<= 1;
4279  }
4280  }
4281 
4282  new_exp = exponent;
4283 
4284  return 0;
4285  }
4286 
4287 
4288  /*!
4289  a special method used to calculate the new mantissa and exponent
4290  when the 'base' is equal 4, 8 or 16
4291 
4292  - when base is 4 then bits is 2
4293  - when base is 8 then bits is 3
4294  - when base is 16 then bits is 4
4295  (and the algorithm can be used with a base greater than 16)
4296  */
4297  template<class string_type>
4298  uint ToString_CreateNewMantissaAndExponent_BasePow2( string_type & new_man,
4299  Int<exp+1> & new_exp,
4300  uint bits) const
4301  {
4302  sint move; // how many times move the mantissa
4303  UInt<man+1> man_temp(mantissa); // man+1 for moving
4304  new_exp = exponent;
4305  new_exp.DivInt((sint)bits, move);
4306 
4307  if( move != 0 )
4308  {
4309  // we're moving the man_temp to left-hand side
4310  if( move < 0 )
4311  {
4312  move = sint(bits) + move;
4313  new_exp.SubOne(); // when move is < than 0 then new_exp is < 0 too
4314  }
4315 
4316  man_temp.Rcl(move);
4317  }
4318 
4319 
4320  if( bits == 3 )
4321  {
4322  // base 8
4323  // now 'move' is greater than or equal 0
4324  uint len = man*TTMATH_BITS_PER_UINT + move;
4325  return ToString_CreateNewMantissaAndExponent_Base8(new_man, man_temp, len, bits);
4326  }
4327  else
4328  {
4329  // base 4 or 16
4330  return ToString_CreateNewMantissaAndExponent_Base4or16(new_man, man_temp, bits);
4331  }
4332  }
4333 
4334 
4335  /*!
4336  a special method used to calculate the new mantissa
4337  when the 'base' is equal 8
4338 
4339  bits is always 3
4340 
4341  we can use this algorithm when the base is 4 or 16 too
4342  but we have a faster method ToString_CreateNewMantissaAndExponent_Base4or16()
4343  */
4344  template<class string_type>
4345  uint ToString_CreateNewMantissaAndExponent_Base8( string_type & new_man,
4346  UInt<man+1> & man_temp,
4347  uint len,
4348  uint bits) const
4349  {
4350  uint shift = TTMATH_BITS_PER_UINT - bits;
4351  uint mask = TTMATH_UINT_MAX_VALUE >> shift;
4352  uint i;
4353 
4354  for( i=0 ; i<len ; i+=bits )
4355  {
4356  uint digit = man_temp.table[0] & mask;
4357  new_man.insert(new_man.begin(), static_cast<char>(Misc::DigitToChar(digit)));
4358 
4359  man_temp.Rcr(bits);
4360  }
4361 
4362  TTMATH_ASSERT( man_temp.IsZero() )
4363 
4364  return 0;
4365  }
4366 
4367 
4368  /*!
4369  a special method used to calculate the new mantissa
4370  when the 'base' is equal 4 or 16
4371 
4372  when the base is equal 4 or 16 the bits is 2 or 4
4373  and because TTMATH_BITS_PER_UINT (32 or 64) is divisible by 2 (or 4)
4374  then we can get digits from the end of our mantissa
4375  */
4376  template<class string_type>
4377  uint ToString_CreateNewMantissaAndExponent_Base4or16( string_type & new_man,
4378  UInt<man+1> & man_temp,
4379  uint bits) const
4380  {
4381  TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 2 == 0 )
4382  TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 4 == 0 )
4383 
4384  uint shift = TTMATH_BITS_PER_UINT - bits;
4385  uint mask = TTMATH_UINT_MAX_VALUE << shift;
4386  uint digit;
4387 
4388  // table[man] - last word - is different from zero if we moved man_temp
4389  digit = man_temp.table[man];
4390 
4391  if( digit != 0 )
4392  new_man += static_cast<char>(Misc::DigitToChar(digit));
4393 
4394 
4395  for( int i=man-1 ; i>=0 ; --i )
4396  {
4397  uint shift_local = shift;
4398  uint mask_local = mask;
4399 
4400  while( mask_local != 0 )
4401  {
4402  digit = man_temp.table[i] & mask_local;
4403 
4404  if( shift_local != 0 )
4405  digit = digit >> shift_local;
4406 
4407  new_man += static_cast<char>(Misc::DigitToChar(digit));
4408  mask_local = mask_local >> bits;
4409  shift_local = shift_local - bits;
4410  }
4411  }
4412 
4413  return 0;
4414  }
4415 
4416 
4417  /*!
4418  an auxiliary method for converting into the string
4419  */
4420  template<class string_type, class char_type>
4421  bool ToString_RoundMantissaWouldBeInteger(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
4422  {
4423  // if new_exp is greater or equal to zero then we have an integer value,
4424  // if new_exp is equal -1 then we have only one digit after the comma
4425  // and after rounding it would be an integer value
4426  if( !new_exp.IsSign() || new_exp == -1 )
4427  return true;
4428 
4429  if( new_man.size() >= TTMATH_UINT_HIGHEST_BIT || new_man.size() < 2 )
4430  return true; // oops, the mantissa is too large for calculating (or too small) - we are not doing the base rounding
4431 
4432  uint i = 0;
4433  char_type digit;
4434 
4435  if( new_exp >= -sint(new_man.size()) )
4436  {
4437  uint new_exp_abs = -new_exp.ToInt();
4438  i = new_man.size() - new_exp_abs; // start from the first digit after the comma operator
4439  }
4440 
4441  if( Misc::CharToDigit(new_man[new_man.size()-1]) >= conv.base/2 )
4442  {
4443  if( new_exp < -sint(new_man.size()) )
4444  {
4445  // there are some zeroes after the comma operator
4446  // (between the comma and the first digit from the mantissa)
4447  // and the result value will never be an integer
4448  return false;
4449  }
4450 
4451  digit = static_cast<char_type>( Misc::DigitToChar(conv.base-1) );
4452  }
4453  else
4454  {
4455  digit = '0';
4456  }
4457 
4458  for( ; i < new_man.size()-1 ; ++i)
4459  if( new_man[i] != digit )
4460  return false; // it will not be an integer
4461 
4462  return true; // it will be integer after rounding
4463  }
4464 
4465 
4466  /*!
4467  an auxiliary method for converting into the string
4468  (when this is integer)
4469 
4470  after floating point calculating the new mantissa can consist of some fraction
4471  so if our value is integer we should check the new mantissa
4472  (after the decimal point there should be only zeroes)
4473 
4474  often this is a last digit different from zero
4475  ToString_BaseRound would not get rid of it because the method make a test against
4476  an integer value (ToString_RoundMantissaWouldBeInteger) and returns immediately
4477  */
4478  template<class string_type, class char_type>
4479  void ToString_CheckMantissaInteger(string_type & new_man, const Int<exp+1> & new_exp) const
4480  {
4481  if( !new_exp.IsSign() )
4482  return; // return if new_exp >= 0
4483 
4484  uint i = 0;
4485  uint man_size = new_man.size();
4486 
4487  if( man_size >= TTMATH_UINT_HIGHEST_BIT )
4488  return; // ops, the mantissa is too long
4489 
4490  sint sman_size = -sint(man_size);
4491 
4492  if( new_exp >= sman_size )
4493  {
4494  sint e = new_exp.ToInt();
4495  e = -e;
4496  // now e means how many last digits from the mantissa should be equal zero
4497 
4498  i = man_size - uint(e);
4499  }
4500 
4501  for( ; i<man_size ; ++i)
4502  new_man[i] = '0';
4503  }
4504 
4505 
4506  /*!
4507  an auxiliary method for converting into the string
4508 
4509  this method is used for base!=2, base!=4, base!=8 and base!=16
4510  we do the rounding when the value has fraction (is not an integer)
4511  */
4512  template<class string_type, class char_type>
4513  uint ToString_BaseRound(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
4514  {
4515  // we must have minimum two characters
4516  if( new_man.size() < 2 )
4517  return 0;
4518 
4519  // assert that there will not be an integer after rounding
4520  if( ToString_RoundMantissaWouldBeInteger<string_type, char_type>(new_man, conv, new_exp) )
4521  return 0;
4522 
4523  typename string_type::size_type i = new_man.length() - 1;
4524 
4525  // we're erasing the last character
4526  uint digit = Misc::CharToDigit( new_man[i] );
4527  new_man.erase(i, 1);
4528  uint c = new_exp.AddOne();
4529 
4530  // if the last character is greater or equal 'base/2'
4531  // we are adding one into the new mantissa
4532  if( digit >= conv.base / 2 )
4533  ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
4534 
4535  return c;
4536  }
4537 
4538 
4539  /*!
4540  an auxiliary method for converting into the string
4541 
4542  this method addes one into the new mantissa
4543  */
4544  template<class string_type, class char_type>
4545  void ToString_RoundMantissa_AddOneIntoMantissa(string_type & new_man, const Conv & conv) const
4546  {
4547  if( new_man.empty() )
4548  return;
4549 
4550  sint i = sint( new_man.length() ) - 1;
4551  bool was_carry = true;
4552 
4553  for( ; i>=0 && was_carry ; --i )
4554  {
4555  // we can have the comma as well because
4556  // we're using this method later in ToString_CorrectDigitsAfterComma_Round()
4557  // (we're only ignoring it)
4558  if( new_man[i] == static_cast<char_type>(conv.comma) )
4559  continue;
4560 
4561  // we're adding one
4562  uint digit = Misc::CharToDigit( new_man[i] ) + 1;
4563 
4564  if( digit == conv.base )
4565  digit = 0;
4566  else
4567  was_carry = false;
4568 
4569  new_man[i] = static_cast<char_type>( Misc::DigitToChar(digit) );
4570  }
4571 
4572  if( i<0 && was_carry )
4573  new_man.insert( new_man.begin() , '1' );
4574  }
4575 
4576 
4577 
4578  /*!
4579  an auxiliary method for converting into the string
4580 
4581  this method sets the comma operator and/or puts the exponent
4582  into the string
4583  */
4584  template<class string_type, class char_type>
4585  uint ToString_SetCommaAndExponent(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
4586  {
4587  uint carry = 0;
4588 
4589  if( new_man.empty() )
4590  return carry;
4591 
4592  Int<exp+1> scientific_exp( new_exp );
4593 
4594  // 'new_exp' depends on the 'new_man' which is stored like this e.g:
4595  // 32342343234 (the comma is at the end)
4596  // we'd like to show it in this way:
4597  // 3.2342343234 (the 'scientific_exp' is connected with this example)
4598 
4599  sint offset = sint( new_man.length() ) - 1;
4600  carry += scientific_exp.Add( offset );
4601  // there shouldn't have been a carry because we're using
4602  // a greater type -- 'Int<exp+1>' instead of 'Int<exp>'
4603 
4604  bool print_scientific = conv.scient;
4605 
4606  if( !print_scientific )
4607  {
4608  if( scientific_exp > conv.scient_from || scientific_exp < -sint(conv.scient_from) )
4609  print_scientific = true;
4610  }
4611 
4612  if( !print_scientific )
4613  ToString_SetCommaAndExponent_Normal<string_type, char_type>(new_man, conv, new_exp);
4614  else
4615  // we're passing the 'scientific_exp' instead of 'new_exp' here
4616  ToString_SetCommaAndExponent_Scientific<string_type, char_type>(new_man, conv, scientific_exp);
4617 
4618  return (carry==0)? 0 : 1;
4619  }
4620 
4621 
4622  /*!
4623  an auxiliary method for converting into the string
4624  */
4625  template<class string_type, class char_type>
4626  void ToString_SetCommaAndExponent_Normal(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp ) const
4627  {
4628  if( !new_exp.IsSign() ) // it means: if( new_exp >= 0 )
4629  ToString_SetCommaAndExponent_Normal_AddingZero<string_type, char_type>(new_man, new_exp);
4630  else
4631  ToString_SetCommaAndExponent_Normal_SetCommaInside<string_type, char_type>(new_man, conv, new_exp);
4632 
4633 
4634  ToString_Group_man<string_type, char_type>(new_man, conv);
4635  }
4636 
4637 
4638  /*!
4639  an auxiliary method for converting into the string
4640  */
4641  template<class string_type, class char_type>
4642  void ToString_SetCommaAndExponent_Normal_AddingZero(string_type & new_man,
4643  Int<exp+1> & new_exp) const
4644  {
4645  // we're adding zero characters at the end
4646  // 'i' will be smaller than 'when_scientific' (or equal)
4647  uint i = new_exp.ToInt();
4648 
4649  if( new_man.length() + i > new_man.capacity() )
4650  // about 6 characters more (we'll need it for the comma or something)
4651  new_man.reserve( new_man.length() + i + 6 );
4652 
4653  for( ; i>0 ; --i)
4654  new_man += '0';
4655  }
4656 
4657 
4658  /*!
4659  an auxiliary method for converting into the string
4660  */
4661  template<class string_type, class char_type>
4662  void ToString_SetCommaAndExponent_Normal_SetCommaInside(
4663  string_type & new_man,
4664  const Conv & conv,
4665  Int<exp+1> & new_exp ) const
4666  {
4667  // new_exp is < 0
4668 
4669  sint new_man_len = sint(new_man.length()); // 'new_man_len' with a sign
4670  sint e = -( new_exp.ToInt() ); // 'e' will be positive
4671 
4672  if( new_exp > -new_man_len )
4673  {
4674  // we're setting the comma within the mantissa
4675 
4676  sint index = new_man_len - e;
4677  new_man.insert( new_man.begin() + index, static_cast<char_type>(conv.comma));
4678  }
4679  else
4680  {
4681  // we're adding zero characters before the mantissa
4682 
4683  uint how_many = e - new_man_len;
4684  string_type man_temp(how_many+1, '0');
4685 
4686  man_temp.insert( man_temp.begin()+1, static_cast<char_type>(conv.comma));
4687  new_man.insert(0, man_temp);
4688  }
4689 
4690  ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
4691  }
4692 
4693 
4694  /*!
4695  an auxiliary method for converting into the string
4696  */
4697  template<class string_type, class char_type>
4698  void ToString_SetCommaAndExponent_Scientific( string_type & new_man,
4699  const Conv & conv,
4700  Int<exp+1> & scientific_exp ) const
4701  {
4702  if( new_man.empty() )
4703  return;
4704 
4705  if( new_man.size() > 1 )
4706  {
4707  new_man.insert( new_man.begin()+1, static_cast<char_type>(conv.comma) );
4708  ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
4709  }
4710 
4711  ToString_Group_man<string_type, char_type>(new_man, conv);
4712 
4713  if( conv.base == 10 )
4714  {
4715  new_man += 'e';
4716 
4717  if( !scientific_exp.IsSign() )
4718  new_man += '+';
4719  }
4720  else
4721  {
4722  // the 10 here is meant as the base 'base'
4723  // (no matter which 'base' we're using there'll always be 10 here)
4724  Misc::AddString(new_man, "*10^");
4725  }
4726 
4727  string_type temp_exp;
4728  scientific_exp.ToString( temp_exp, conv.base );
4729 
4730  new_man += temp_exp;
4731  }
4732 
4733 
4734  /*!
4735  an auxiliary method for converting into the string
4736  */
4737  template<class string_type, class char_type>
4738  void ToString_Group_man(string_type & new_man, const Conv & conv) const
4739  {
4740  typedef typename string_type::size_type StrSize;
4741 
4742  if( conv.group == 0 )
4743  return;
4744 
4745  // first we're looking for the comma operator
4746  StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
4747 
4748  if( index == string_type::npos )
4749  index = new_man.size();
4750 
4751  ToString_Group_man_before_comma<string_type, char_type>(new_man, conv, index);
4752  ToString_Group_man_after_comma<string_type, char_type>(new_man, conv, index+1);
4753  }
4754 
4755 
4756 
4757  /*!
4758  an auxiliary method for converting into the string
4759  */
4760  template<class string_type, class char_type>
4761  void ToString_Group_man_before_comma( string_type & new_man, const Conv & conv,
4762  typename string_type::size_type & index) const
4763  {
4764  typedef typename string_type::size_type StrSize;
4765 
4766  uint group = 0;
4767  StrSize i = index;
4768  uint group_digits = conv.group_digits;
4769 
4770  if( group_digits < 1 )
4771  group_digits = 1;
4772 
4773  // adding group characters before the comma operator
4774  // i>0 because on the first position we don't put any additional grouping characters
4775  for( ; i>0 ; --i, ++group)
4776  {
4777  if( group >= group_digits )
4778  {
4779  group = 0;
4780  new_man.insert(i, 1, static_cast<char_type>(conv.group));
4781  ++index;
4782  }
4783  }
4784  }
4785 
4786 
4787  /*!
4788  an auxiliary method for converting into the string
4789  */
4790  template<class string_type, class char_type>
4791  void ToString_Group_man_after_comma(string_type & new_man, const Conv & conv,
4792  typename string_type::size_type index) const
4793  {
4794  uint group = 0;
4795  uint group_digits = conv.group_digits;
4796 
4797  if( group_digits < 1 )
4798  group_digits = 1;
4799 
4800  for( ; index<new_man.size() ; ++index, ++group)
4801  {
4802  if( group >= group_digits )
4803  {
4804  group = 0;
4805  new_man.insert(index, 1, static_cast<char_type>(conv.group));
4806  ++index;
4807  }
4808  }
4809  }
4810 
4811 
4812  /*!
4813  an auxiliary method for converting into the string
4814  */
4815  template<class string_type, class char_type>
4816  void ToString_CorrectDigitsAfterComma( string_type & new_man,
4817  const Conv & conv ) const
4818  {
4819  if( conv.round >= 0 )
4820  ToString_CorrectDigitsAfterComma_Round<string_type, char_type>(new_man, conv);
4821 
4822  if( conv.trim_zeroes )
4823  ToString_CorrectDigitsAfterComma_CutOffZeroCharacters<string_type, char_type>(new_man, conv);
4824  }
4825 
4826 
4827  /*!
4828  an auxiliary method for converting into the string
4829  */
4830  template<class string_type, class char_type>
4831  void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
4832  string_type & new_man,
4833  const Conv & conv) const
4834  {
4835  // minimum two characters
4836  if( new_man.length() < 2 )
4837  return;
4838 
4839  // we're looking for the index of the last character which is not zero
4840  uint i = uint( new_man.length() ) - 1;
4841  for( ; i>0 && new_man[i]=='0' ; --i );
4842 
4843  // if there is another character than zero at the end
4844  // we're finishing
4845  if( i == new_man.length() - 1 )
4846  return;
4847 
4848  // we must have a comma
4849  // (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
4850  // which is called before)
4851  if( new_man.find_last_of(static_cast<char_type>(conv.comma), i) == string_type::npos )
4852  return;
4853 
4854  // if directly before the first zero is the comma operator
4855  // we're cutting it as well
4856  if( i>0 && new_man[i]==static_cast<char_type>(conv.comma) )
4857  --i;
4858 
4859  new_man.erase(i+1, new_man.length()-i-1);
4860  }
4861 
4862 
4863  /*!
4864  an auxiliary method for converting into the string
4865  */
4866  template<class string_type, class char_type>
4867  void ToString_CorrectDigitsAfterComma_Round(
4868  string_type & new_man,
4869  const Conv & conv ) const
4870  {
4871  typedef typename string_type::size_type StrSize;
4872 
4873  // first we're looking for the comma operator
4874  StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
4875 
4876  if( index == string_type::npos )
4877  // nothing was found (actually there can't be this situation)
4878  return;
4879 
4880  // we're calculating how many digits there are at the end (after the comma)
4881  // 'after_comma' will be greater than zero because at the end
4882  // we have at least one digit
4883  StrSize after_comma = new_man.length() - index - 1;
4884 
4885  // if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
4886  // we don't have anything for cutting
4887  if( static_cast<StrSize>(conv.round) >= after_comma )
4888  return;
4889 
4890  uint last_digit = Misc::CharToDigit( new_man[ index + conv.round + 1 ], conv.base );
4891 
4892  // we're cutting the rest of the string
4893  new_man.erase(index + conv.round + 1, after_comma - conv.round);
4894 
4895  if( conv.round == 0 )
4896  {
4897  // we're cutting the comma operator as well
4898  // (it's not needed now because we've cut the whole rest after the comma)
4899  new_man.erase(index, 1);
4900  }
4901 
4902  if( last_digit >= conv.base / 2 )
4903  // we must round here
4904  ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
4905  }
4906 
4907 
4908 
4909 public:
4910 
4911  /*!
4912  a method for converting a string into its value
4913 
4914  it returns 1 if the value is too big -- we cannot pass it into the range
4915  of our class Big<exp,man> (or if the base is incorrect)
4916 
4917  that means only digits before the comma operator can make this value too big,
4918  all digits after the comma we can ignore
4919 
4920  'source' - pointer to the string for parsing
4921 
4922  if 'after_source' is set that when this method finishes
4923  it sets the pointer to the new first character after parsed value
4924 
4925  'value_read' - if the pointer is provided that means the value_read will be true
4926  only when a value has been actually read, there can be situation where only such
4927  a string '-' or '+' will be parsed -- 'after_source' will be different from 'source' but
4928  no value has been read (there are no digits)
4929  on other words if 'value_read' is true -- there is at least one digit in the string
4930  */
4931  uint FromString(const char * source, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
4932  {
4933  Conv conv;
4934  conv.base = base;
4935 
4936  return FromStringBase(source, conv, after_source, value_read);
4937  }
4938 
4939 
4940  /*!
4941  a method for converting a string into its value
4942  */
4943  uint FromString(const char * source, const Conv & conv, const char ** after_source = 0, bool * value_read = 0)
4944  {
4945  return FromStringBase(source, conv, after_source, value_read);
4946  }
4947 
4948 
4949  /*!
4950  a method for converting a string into its value
4951  */
4952  uint FromString(const std::string & string, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
4953  {
4954  return FromString(string.c_str(), base, after_source, value_read);
4955  }
4956 
4957 
4958  /*!
4959  a method for converting a string into its value
4960  */
4961  uint FromString(const std::string & string, const Conv & conv, const char ** after_source = 0, bool * value_read = 0)
4962  {
4963  return FromString(string.c_str(), conv, after_source, value_read);
4964  }
4965 
4966 
4967 #ifndef TTMATH_DONT_USE_WCHAR
4968 
4969  /*!
4970  a method for converting a string into its value
4971  */
4972  uint FromString(const wchar_t * source, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
4973  {
4974  Conv conv;
4975  conv.base = base;
4976 
4977  return FromStringBase(source, conv, after_source, value_read);
4978  }
4979 
4980 
4981  /*!
4982  a method for converting a string into its value
4983  */
4984  uint FromString(const wchar_t * source, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
4985  {
4986  return FromStringBase(source, conv, after_source, value_read);
4987  }
4988 
4989 
4990  /*!
4991  a method for converting a string into its value
4992  */
4993  uint FromString(const std::wstring & string, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
4994  {
4995  return FromString(string.c_str(), base, after_source, value_read);
4996  }
4997 
4998 
4999  /*!
5000  a method for converting a string into its value
5001  */
5002  uint FromString(const std::wstring & string, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
5003  {
5004  return FromString(string.c_str(), conv, after_source, value_read);
5005  }
5006 
5007 #endif
5008 
5009 
5010 private:
5011 
5012 
5013  /*!
5014  an auxiliary method for converting from a string
5015  */
5016  template<class char_type>
5017  uint FromStringBase(const char_type * source, const Conv & conv, const char_type ** after_source = 0, bool * value_read = 0)
5018  {
5019  bool is_sign;
5020  bool value_read_temp = false;
5021 
5022  if( conv.base<2 || conv.base>16 )
5023  {
5024  SetNan();
5025 
5026  if( after_source )
5027  *after_source = source;
5028 
5029  if( value_read )
5030  *value_read = value_read_temp;
5031 
5032  return 1;
5033  }
5034 
5035  SetZero();
5036  FromString_TestSign( source, is_sign );
5037 
5038  uint c = FromString_ReadPartBeforeComma( source, conv, value_read_temp );
5039 
5040  if( FromString_TestCommaOperator(source, conv) )
5041  c += FromString_ReadPartAfterComma( source, conv, value_read_temp );
5042 
5043  if( value_read_temp && conv.base == 10 )
5044  c += FromString_ReadScientificIfExists( source );
5045 
5046  if( is_sign && !IsZero() )
5047  ChangeSign();
5048 
5049  if( after_source )
5050  *after_source = source;
5051 
5052  if( value_read )
5053  *value_read = value_read_temp;
5054 
5055  return CheckCarry(c);
5056  }
5057 
5058 
5059  /*!
5060  we're testing whether the value is with the sign
5061 
5062  (this method is used from 'FromString_ReadPartScientific' too)
5063  */
5064  template<class char_type>
5065  void FromString_TestSign( const char_type * & source, bool & is_sign )
5066  {
5067  Misc::SkipWhiteCharacters(source);
5068 
5069  is_sign = false;
5070 
5071  if( *source == '-' )
5072  {
5073  is_sign = true;
5074  ++source;
5075  }
5076  else
5077  if( *source == '+' )
5078  {
5079  ++source;
5080  }
5081  }
5082 
5083 
5084  /*!
5085  we're testing whether there's a comma operator
5086  */
5087  template<class char_type>
5088  bool FromString_TestCommaOperator(const char_type * & source, const Conv & conv)
5089  {
5090  if( (*source == static_cast<char_type>(conv.comma)) ||
5091  (*source == static_cast<char_type>(conv.comma2) && conv.comma2 != 0 ) )
5092  {
5093  ++source;
5094 
5095  return true;
5096  }
5097 
5098  return false;
5099  }
5100 
5101 
5102  /*!
5103  this method reads the first part of a string
5104  (before the comma operator)
5105  */
5106  template<class char_type>
5107  uint FromString_ReadPartBeforeComma( const char_type * & source, const Conv & conv, bool & value_read )
5108  {
5109  sint character;
5110  Big<exp, man> temp;
5111  Big<exp, man> base_( conv.base );
5112 
5113  Misc::SkipWhiteCharacters( source );
5114 
5115  for( ; true ; ++source )
5116  {
5117  if( conv.group!=0 && *source==static_cast<char>(conv.group) )
5118  continue;
5119 
5120  character = Misc::CharToDigit(*source, conv.base);
5121 
5122  if( character == -1 )
5123  break;
5124 
5125  value_read = true;
5126  temp = character;
5127 
5128  if( Mul(base_) )
5129  return 1;
5130 
5131  if( Add(temp) )
5132  return 1;
5133  }
5134 
5135  return 0;
5136  }
5137 
5138 
5139  /*!
5140  this method reads the second part of a string
5141  (after the comma operator)
5142  */
5143  template<class char_type>
5144  uint FromString_ReadPartAfterComma( const char_type * & source, const Conv & conv, bool & value_read )
5145  {
5146  sint character;
5147  uint c = 0, power = 0;
5148  UInt<1> power_;
5149  Big<exp, man> sum, base_(conv.base);
5150 
5151  // we don't remove any white characters here
5152  sum.SetZero();
5153 
5154  for( ; sum.exponent.IsSign() || sum.exponent.IsZero() ; ++source )
5155  {
5156  if( conv.group!=0 && *source==static_cast<char>(conv.group) )
5157  continue;
5158 
5159  character = Misc::CharToDigit(*source, conv.base);
5160 
5161  if( character == -1 )
5162  break;
5163 
5164  value_read = true;
5165 
5166  // there actually shouldn't be a carry here
5167  c += sum.Mul(base_);
5168  c += sum.Add(character);
5169  power += 1;
5170 
5171  if( power == 0 )
5172  c += 1;
5173  }
5174 
5175  // we could break the parsing somewhere in the middle of the string,
5176  // but the result (value) still can be good
5177  // we should set a correct value of 'source' now
5178  while( Misc::CharToDigit(*source, conv.base) != -1 )
5179  {
5180  ++source;
5181  }
5182 
5183  power_ = power;
5184  c += base_.Pow(power_);
5185  c += sum.Div(base_);
5186  c += Add(sum);
5187 
5188  return (c==0)? 0 : 1;
5189  }
5190 
5191 
5192  /*!
5193  this method checks whether there is a scientific part: [e|E][-|+]value
5194 
5195  it is called when the base is 10 and some digits were read before
5196  */
5197  template<class char_type>
5198  uint FromString_ReadScientificIfExists(const char_type * & source)
5199  {
5200  uint c = 0;
5201 
5202  bool scientific_read = false;
5203  const char_type * before_scientific = source;
5204 
5205  if( FromString_TestScientific(source) )
5206  c += FromString_ReadPartScientific( source, scientific_read );
5207 
5208  if( !scientific_read )
5209  source = before_scientific;
5210 
5211  return (c==0)? 0 : 1;
5212  }
5213 
5214 
5215 
5216  /*!
5217  we're testing whether is there the character 'e'
5218 
5219  this character is only allowed when we're using the base equals 10
5220  */
5221  template<class char_type>
5222  bool FromString_TestScientific(const char_type * & source)
5223  {
5224  Misc::SkipWhiteCharacters(source);
5225 
5226  if( *source=='e' || *source=='E' )
5227  {
5228  ++source;
5229 
5230  return true;
5231  }
5232 
5233  return false;
5234  }
5235 
5236 
5237  /*!
5238  this method reads the exponent (after 'e' character) when there's a scientific
5239  format of value and only when we're using the base equals 10
5240  */
5241  template<class char_type>
5242  uint FromString_ReadPartScientific( const char_type * & source, bool & scientific_read )
5243  {
5244  uint c = 0;
5245  Big<exp, man> new_exponent, temp;
5246  bool was_sign = false;
5247 
5248  FromString_TestSign( source, was_sign );
5249  c += FromString_ReadPartScientific_ReadExponent( source, new_exponent, scientific_read );
5250 
5251  if( scientific_read )
5252  {
5253  if( was_sign )
5254  new_exponent.ChangeSign();
5255 
5256  temp = 10;
5257  c += temp.Pow( new_exponent );
5258  c += Mul(temp);
5259  }
5260 
5261  return (c==0)? 0 : 1;
5262  }
5263 
5264 
5265  /*!
5266  this method reads the value of the extra exponent when scientific format is used
5267  (only when base == 10)
5268  */
5269  template<class char_type>
5270  uint FromString_ReadPartScientific_ReadExponent( const char_type * & source, Big<exp, man> & new_exponent, bool & scientific_read )
5271  {
5272  sint character;
5273  Big<exp, man> base, temp;
5274 
5275  Misc::SkipWhiteCharacters(source);
5276 
5277  new_exponent.SetZero();
5278  base = 10;
5279 
5280  for( ; (character=Misc::CharToDigit(*source, 10)) != -1 ; ++source )
5281  {
5282  scientific_read = true;
5283 
5284  temp = character;
5285 
5286  if( new_exponent.Mul(base) )
5287  return 1;
5288 
5289  if( new_exponent.Add(temp) )
5290  return 1;
5291  }
5292 
5293  return 0;
5294  }
5295 
5296 
5297 public:
5298 
5299 
5300  /*!
5301  a constructor for converting a string into this class
5302  */
5303  Big(const char * string)
5304  {
5305  FromString( string );
5306  }
5307 
5308 
5309  /*!
5310  a constructor for converting a string into this class
5311  */
5312  Big(const std::string & string)
5313  {
5314  FromString( string.c_str() );
5315  }
5316 
5317 
5318  /*!
5319  an operator= for converting a string into its value
5320  */
5321  Big<exp, man> & operator=(const char * string)
5322  {
5323  FromString( string );
5324 
5325  return *this;
5326  }
5327 
5328 
5329  /*!
5330  an operator= for converting a string into its value
5331  */
5332  Big<exp, man> & operator=(const std::string & string)
5333  {
5334  FromString( string.c_str() );
5335 
5336  return *this;
5337  }
5338 
5339 
5340 
5341 #ifndef TTMATH_DONT_USE_WCHAR
5342 
5343  /*!
5344  a constructor for converting a string into this class
5345  */
5346  Big(const wchar_t * string)
5347  {
5348  FromString( string );
5349  }
5350 
5351 
5352  /*!
5353  a constructor for converting a string into this class
5354  */
5355  Big(const std::wstring & string)
5356  {
5357  FromString( string.c_str() );
5358  }
5359 
5360 
5361  /*!
5362  an operator= for converting a string into its value
5363  */
5364  Big<exp, man> & operator=(const wchar_t * string)
5365  {
5366  FromString( string );
5367 
5368  return *this;
5369  }
5370 
5371 
5372  /*!
5373  an operator= for converting a string into its value
5374  */
5375  Big<exp, man> & operator=(const std::wstring & string)
5376  {
5377  FromString( string.c_str() );
5378 
5379  return *this;
5380  }
5381 
5382 
5383 #endif
5384 
5385 
5386 
5387  /*!
5388  *
5389  * methods for comparing
5390  *
5391  */
5392 
5393 
5394  /*!
5395  this method performs the formula 'abs(this) < abs(ss2)'
5396  and returns the result
5397 
5398  (in other words it treats 'this' and 'ss2' as values without a sign)
5399  we don't check the NaN flag
5400  */
5401  bool SmallerWithoutSignThan(const Big<exp,man> & ss2) const
5402  {
5403  if( IsZero() )
5404  {
5405  if( ss2.IsZero() )
5406  // we've got two zeroes
5407  return false;
5408  else
5409  // this==0 and ss2!=0
5410  return true;
5411  }
5412 
5413  if( ss2.IsZero() )
5414  {
5415  // this!=0 and ss2==0
5416  return false;
5417  }
5418 
5419  // we're using the fact that all bits in mantissa are pushed
5420  // into the left side -- Standardizing()
5421  if( exponent == ss2.exponent )
5422  return mantissa < ss2.mantissa;
5423 
5424  return exponent < ss2.exponent;
5425  }
5426 
5427 
5428  /*!
5429  this method performs the formula 'abs(this) > abs(ss2)'
5430  and returns the result
5431 
5432  (in other words it treats 'this' and 'ss2' as values without a sign)
5433  we don't check the NaN flag
5434  */
5435  bool GreaterWithoutSignThan(const Big<exp,man> & ss2) const
5436  {
5437  if( IsZero() )
5438  {
5439  if( ss2.IsZero() )
5440  {
5441  // we've got two zeroes
5442  return false;
5443  }
5444  else
5445  {
5446  // this==0 and ss2!=0
5447  return false;
5448  }
5449  }
5450 
5451  if( ss2.IsZero() )
5452  {
5453  // this!=0 and ss2==0
5454  return true;
5455  }
5456 
5457  // we're using the fact that all bits in mantissa are pushed
5458  // into the left side -- Standardizing()
5459  if( exponent == ss2.exponent )
5460  return mantissa > ss2.mantissa;
5461 
5462  return exponent > ss2.exponent;
5463  }
5464 
5465 
5466  /*!
5467  this method performs the formula 'abs(this) == abs(ss2)'
5468  and returns the result
5469 
5470  (in other words it treats 'this' and 'ss2' as values without a sign)
5471  we don't check the NaN flag
5472  */
5473  bool EqualWithoutSign(const Big<exp,man> & ss2) const
5474  {
5475  if( IsZero() )
5476  {
5477  if( ss2.IsZero() )
5478  {
5479  // we've got two zeroes
5480  return true;
5481  }
5482  else
5483  {
5484  // this==0 and ss2!=0
5485  return false;
5486  }
5487  }
5488 
5489  if( ss2.IsZero() )
5490  {
5491  // this!=0 and ss2==0
5492  return false;
5493  }
5494 
5495  if( exponent==ss2.exponent && mantissa==ss2.mantissa )
5496  return true;
5497 
5498  return false;
5499  }
5500 
5501 
5502  bool operator<(const Big<exp,man> & ss2) const
5503  {
5504  if( IsSign() && !ss2.IsSign() )
5505  {
5506  // this<0 and ss2>=0
5507  return true;
5508  }
5509 
5510  if( !IsSign() && ss2.IsSign() )
5511  {
5512  // this>=0 and ss2<0
5513  return false;
5514  }
5515 
5516  // both signs are the same
5517 
5518  if( IsSign() )
5519  return ss2.SmallerWithoutSignThan( *this );
5520 
5521  return SmallerWithoutSignThan( ss2 );
5522  }
5523 
5524 
5525  bool operator==(const Big<exp,man> & ss2) const
5526  {
5527  if( IsSign() != ss2.IsSign() )
5528  return false;
5529 
5530  return EqualWithoutSign( ss2 );
5531  }
5532 
5533 
5534  bool operator>(const Big<exp,man> & ss2) const
5535  {
5536  if( IsSign() && !ss2.IsSign() )
5537  {
5538  // this<0 and ss2>=0
5539  return false;
5540  }
5541 
5542  if( !IsSign() && ss2.IsSign() )
5543  {
5544  // this>=0 and ss2<0
5545  return true;
5546  }
5547 
5548  // both signs are the same
5549 
5550  if( IsSign() )
5551  return ss2.GreaterWithoutSignThan( *this );
5552 
5553  return GreaterWithoutSignThan( ss2 );
5554  }
5555 
5556 
5557  bool operator>=(const Big<exp,man> & ss2) const
5558  {
5559  return !operator<( ss2 );
5560  }
5561 
5562 
5563  bool operator<=(const Big<exp,man> & ss2) const
5564  {
5565  return !operator>( ss2 );
5566  }
5567 
5568 
5569  bool operator!=(const Big<exp,man> & ss2) const
5570  {
5571  return !operator==(ss2);
5572  }
5573 
5574 
5575 
5576 
5577 
5578  /*!
5579  *
5580  * standard mathematical operators
5581  *
5582  */
5583 
5584 
5585  /*!
5586  an operator for changing the sign
5587 
5588  this method is not changing 'this' but the changed value is returned
5589  */
5591  {
5592  Big<exp,man> temp(*this);
5593 
5594  temp.ChangeSign();
5595 
5596  return temp;
5597  }
5598 
5599 
5600  Big<exp,man> operator-(const Big<exp,man> & ss2) const
5601  {
5602  Big<exp,man> temp(*this);
5603 
5604  temp.Sub(ss2);
5605 
5606  return temp;
5607  }
5608 
5609  Big<exp,man> & operator-=(const Big<exp,man> & ss2)
5610  {
5611  Sub(ss2);
5612 
5613  return *this;
5614  }
5615 
5616 
5617  Big<exp,man> operator+(const Big<exp,man> & ss2) const
5618  {
5619  Big<exp,man> temp(*this);
5620 
5621  temp.Add(ss2);
5622 
5623  return temp;
5624  }
5625 
5626 
5627  Big<exp,man> & operator+=(const Big<exp,man> & ss2)
5628  {
5629  Add(ss2);
5630 
5631  return *this;
5632  }
5633 
5634 
5635  Big<exp,man> operator*(const Big<exp,man> & ss2) const
5636  {
5637  Big<exp,man> temp(*this);
5638 
5639  temp.Mul(ss2);
5640 
5641  return temp;
5642  }
5643 
5644 
5645  Big<exp,man> & operator*=(const Big<exp,man> & ss2)
5646  {
5647  Mul(ss2);
5648 
5649  return *this;
5650  }
5651 
5652 
5653  Big<exp,man> operator/(const Big<exp,man> & ss2) const
5654  {
5655  Big<exp,man> temp(*this);
5656 
5657  temp.Div(ss2);
5658 
5659  return temp;
5660  }
5661 
5662 
5663  Big<exp,man> & operator/=(const Big<exp,man> & ss2)
5664  {
5665  Div(ss2);
5666 
5667  return *this;
5668  }
5669 
5670 
5671  /*!
5672  Prefix operator e.g ++variable
5673  */
5675  {
5676  AddOne();
5677 
5678  return *this;
5679  }
5680 
5681 
5682  /*!
5683  Postfix operator e.g variable++
5684  */
5686  {
5687  Big<exp,man> temp( *this );
5688 
5689  AddOne();
5690 
5691  return temp;
5692  }
5693 
5694 
5695  Big<exp,man> & operator--()
5696  {
5697  SubOne();
5698 
5699  return *this;
5700  }
5701 
5702 
5703  Big<exp,man> operator--(int)
5704  {
5705  Big<exp,man> temp( *this );
5706 
5707  SubOne();
5708 
5709  return temp;
5710  }
5711 
5712 
5713 
5714  /*!
5715  *
5716  * bitwise operators
5717  * (we do not define bitwise not)
5718  */
5719 
5720 
5722  {
5723  Big<exp,man> temp( *this );
5724 
5725  temp.BitAnd(p2);
5726 
5727  return temp;
5728  }
5729 
5730 
5731  Big<exp,man> & operator&=(const Big<exp,man> & p2)
5732  {
5733  BitAnd(p2);
5734 
5735  return *this;
5736  }
5737 
5738 
5739  Big<exp,man> operator|(const Big<exp,man> & p2) const
5740  {
5741  Big<exp,man> temp( *this );
5742 
5743  temp.BitOr(p2);
5744 
5745  return temp;
5746  }
5747 
5748 
5749  Big<exp,man> & operator|=(const Big<exp,man> & p2)
5750  {
5751  BitOr(p2);
5752 
5753  return *this;
5754  }
5755 
5756 
5757  Big<exp,man> operator^(const Big<exp,man> & p2) const
5758  {
5759  Big<exp,man> temp( *this );
5760 
5761  temp.BitXor(p2);
5762 
5763  return temp;
5764  }
5765 
5766 
5767  Big<exp,man> & operator^=(const Big<exp,man> & p2)
5768  {
5769  BitXor(p2);
5770 
5771  return *this;
5772  }
5773 
5774 
5775 
5776 
5777 
5778 
5779  /*!
5780  this method makes an integer value by skipping any fractions
5781 
5782  samples:
5783  - 10.7 will be 10
5784  - 12.1 -- 12
5785  - -20.2 -- 20
5786  - -20.9 -- 20
5787  - -0.7 -- 0
5788  - 0.8 -- 0
5789  */
5791  {
5792  if( IsNan() || IsZero() )
5793  return;
5794 
5795  if( !exponent.IsSign() )
5796  // exponent >=0 -- the value don't have any fractions
5797  return;
5798 
5799  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
5800  {
5801  // the value is from (-1,1), we return zero
5802  SetZero();
5803  return;
5804  }
5805 
5806  // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
5807  sint e = exponent.ToInt();
5808 
5809  mantissa.ClearFirstBits( -e );
5810 
5811  // we don't have to standardize 'Standardizing()' the value because
5812  // there's at least one bit in the mantissa
5813  // (the highest bit which we didn't touch)
5814  }
5815 
5816 
5817  /*!
5818  this method remains only a fraction from the value
5819 
5820  samples:
5821  - 30.56 will be 0.56
5822  - -12.67 will be -0.67
5823  */
5825  {
5826  if( IsNan() || IsZero() )
5827  return;
5828 
5829  if( !exponent.IsSign() )
5830  {
5831  // exponent >= 0 -- the value doesn't have any fractions
5832  // we return zero
5833  SetZero();
5834  return;
5835  }
5836 
5837  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
5838  {
5839  // the value is from (-1,1)
5840  // we don't make anything with the value
5841  return;
5842  }
5843 
5844  // e will be from (-man*TTMATH_BITS_PER_UINT, 0)
5845  sint e = exponent.ToInt();
5846 
5847  sint how_many_bits_leave = sint(man*TTMATH_BITS_PER_UINT) + e; // there'll be a subtraction -- e is negative
5848  mantissa.Rcl( how_many_bits_leave, 0);
5849 
5850  // there'll not be a carry because the exponent is too small
5851  exponent.Sub( how_many_bits_leave );
5852 
5853  // we must call Standardizing() here
5854  Standardizing();
5855  }
5856 
5857 
5858 
5859  /*!
5860  this method returns true if the value is integer
5861  (there is no a fraction)
5862 
5863  (we don't check NaN)
5864  */
5865  bool IsInteger() const
5866  {
5867  if( IsZero() )
5868  return true;
5869 
5870  if( !exponent.IsSign() )
5871  // exponent >=0 -- the value don't have any fractions
5872  return true;
5873 
5874  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
5875  // the value is from (-1,1)
5876  return false;
5877 
5878  // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
5879  sint e = exponent.ToInt();
5880  e = -e; // e means how many bits we must check
5881 
5882  uint len = e / TTMATH_BITS_PER_UINT;
5883  uint rest = e % TTMATH_BITS_PER_UINT;
5884  uint i = 0;
5885 
5886  for( ; i<len ; ++i )
5887  if( mantissa.table[i] != 0 )
5888  return false;
5889 
5890  if( rest > 0 )
5891  {
5892  uint rest_mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
5893  if( (mantissa.table[i] & rest_mask) != 0 )
5894  return false;
5895  }
5896 
5897  return true;
5898  }
5899 
5900 
5901  /*!
5902  this method rounds to the nearest integer value
5903  (it returns a carry if it was)
5904 
5905  samples:
5906  - 2.3 = 2
5907  - 2.8 = 3
5908  - -2.3 = -2
5909  - -2.8 = 3
5910  */
5912  {
5913  Big<exp,man> half;
5914  uint c;
5915 
5916  if( IsNan() )
5917  return 1;
5918 
5919  if( IsZero() )
5920  return 0;
5921 
5922  half.Set05();
5923 
5924  if( IsSign() )
5925  {
5926  // 'this' is < 0
5927  c = Sub( half );
5928  }
5929  else
5930  {
5931  // 'this' is > 0
5932  c = Add( half );
5933  }
5934 
5935  SkipFraction();
5936 
5937  return CheckCarry(c);
5938  }
5939 
5940 
5941 
5942  /*!
5943  *
5944  * input/output operators for standard streams
5945  *
5946  */
5947 
5948 private:
5949 
5950  /*!
5951  an auxiliary method for outputing to standard streams
5952  */
5953  template<class ostream_type, class string_type>
5954  static ostream_type & OutputToStream(ostream_type & s, const Big<exp,man> & l)
5955  {
5956  string_type ss;
5957 
5958  l.ToString(ss);
5959  s << ss;
5960 
5961  return s;
5962  }
5963 
5964 
5965 public:
5966 
5967 
5968  /*!
5969  output to standard streams
5970  */
5971  friend std::ostream & operator<<(std::ostream & s, const Big<exp,man> & l)
5972  {
5973  return OutputToStream<std::ostream, std::string>(s, l);
5974  }
5975 
5976 
5977 #ifndef TTMATH_DONT_USE_WCHAR
5978 
5979  /*!
5980  output to standard streams
5981  */
5982  friend std::wostream & operator<<(std::wostream & s, const Big<exp,man> & l)
5983  {
5984  return OutputToStream<std::wostream, std::wstring>(s, l);
5985  }
5986 
5987 #endif
5988 
5989 
5990 
5991 private:
5992 
5993  /*!
5994  an auxiliary method for converting from a string
5995  */
5996  template<class istream_type, class string_type, class char_type>
5997  static istream_type & InputFromStream(istream_type & s, Big<exp,man> & l)
5998  {
5999  string_type ss;
6000 
6001  // char or wchar_t for operator>>
6002  char_type z, old_z;
6003  bool was_comma = false;
6004  bool was_e = false;
6005 
6006 
6007  // operator>> omits white characters if they're set for ommiting
6008  s >> z;
6009 
6010  if( z=='-' || z=='+' )
6011  {
6012  ss += z;
6013  s >> z; // we're reading a next character (white characters can be ommited)
6014  }
6015 
6016  old_z = 0;
6017 
6018  // we're reading only digits (base=10) and only one comma operator
6019  for( ; s.good() ; z=static_cast<char_type>(s.get()) )
6020  {
6021  if( z=='.' || z==',' )
6022  {
6023  if( was_comma || was_e )
6024  // second comma operator or comma operator after 'e' character
6025  break;
6026 
6027  was_comma = true;
6028  }
6029  else
6030  if( z == 'e' || z == 'E' )
6031  {
6032  if( was_e )
6033  // second 'e' character
6034  break;
6035 
6036  was_e = true;
6037  }
6038  else
6039  if( z == '+' || z == '-' )
6040  {
6041  if( old_z != 'e' && old_z != 'E' )
6042  // '+' or '-' is allowed only after 'e' character
6043  break;
6044  }
6045  else
6046  if( Misc::CharToDigit(z, 10) < 0 )
6047  break;
6048 
6049 
6050  ss += z;
6051  old_z = z;
6052  }
6053 
6054  // we're leaving the last read character
6055  // (it's not belonging to the value)
6056  s.unget();
6057 
6058  l.FromString( ss );
6059 
6060  return s;
6061  }
6062 
6063 
6064 
6065 public:
6066 
6067  /*!
6068  input from standard streams
6069  */
6070  friend std::istream & operator>>(std::istream & s, Big<exp,man> & l)
6071  {
6072  return InputFromStream<std::istream, std::string, char>(s, l);
6073  }
6074 
6075 
6076 #ifndef TTMATH_DONT_USE_WCHAR
6077 
6078  /*!
6079  input from standard streams
6080  */
6081  friend std::wistream & operator>>(std::wistream & s, Big<exp,man> & l)
6082  {
6083  return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
6084  }
6085 
6086 #endif
6087 
6088 };
6089 
6090 
6091 } // namespace
6092 
6093 #endif
void SetFromTable(const unsigned int *temp_table, uint temp_table_len)
Definition: ttmathuint.h:325
uint ToInt(UInt< int_size > &result) const
Definition: ttmathbig.h:2486
signed long sint
Definition: ttmathtypes.h:243
uint PowFrac(const Big< exp, man > &pow)
Definition: ttmathbig.h:1749
uint ToFloat(float &result) const
Definition: ttmathbig.h:2923
uint ToInt(signed int &result) const
Definition: ttmathbig.h:3392
void SetLn10()
Definition: ttmathbig.h:558
uint ToString(std::string &result, uint base=10, bool scient=false, sint scient_from=15, sint round=-1, bool trim_zeroes=true, char comma='.') const
Definition: ttmathbig.h:3697
void Set05()
Definition: ttmathbig.h:285
uint Rcl(uint bits, uint c=0)
Definition: ttmathuint.h:460
Big< exp, man > & operator=(const Big< another_exp, another_man > &value)
Definition: ttmathbig.h:3612
Big< exp, man > & operator=(uint value)
Definition: ttmathbig.h:3112
uint ToUInt() const
Definition: ttmathbig.h:2318
uint FromInt(sint value)
Definition: ttmathbig.h:2555
Big< exp, man > & operator=(float value)
Definition: ttmathbig.h:3123
uint FromInt(Int< int_size > value)
Definition: ttmathbig.h:3543
void SetZeroNan()
Definition: ttmathbig.h:306
static uint CharToDigit(uint c)
Definition: ttmathmisc.h:181
#define TTMATH_ARITHMETIC_MAX_LOOP
Definition: ttmathtypes.h:310
void RemainFraction()
Definition: ttmathbig.h:5824
bool IsSign() const
Definition: ttmathbig.h:658
uint CheckCarry(uint c)
Definition: ttmathbig.h:121
sint scient_from
Definition: ttmathtypes.h:429
static LibTypeCode LibType()
Definition: ttmathbig.h:154
uint FromString(const wchar_t *source, const Conv &conv, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4984
static void AddString(std::string &result, const char *str)
Definition: ttmathmisc.h:135
std::string ToString(uint base=10) const
Definition: ttmathbig.h:3745
uint table[value_size]
Definition: ttmathuint.h:81
uint ToInt(sint &result) const
Definition: ttmathbig.h:2374
uint FromString(const std::wstring &string, uint base=10, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4993
static const char * LibTypeStr()
float ToFloat() const
Definition: ttmathbig.h:2902
Big< exp, man > & operator=(const std::wstring &string)
Definition: ttmathbig.h:5375
uint ToInt(uint &result) const
Definition: ttmathbig.h:2363
Big(const wchar_t *string)
Definition: ttmathbig.h:5346
uint FromString(const wchar_t *source, uint base=10, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4972
uint FromInt(const Int< argument_size > &p)
Definition: ttmathint.h:697
uint FromString(const char *source, uint base=10, const char **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4931
void SetSign()
Definition: ttmathbig.h:726
static uint DigitToChar(uint digit)
Definition: ttmathmisc.h:236
uint ToUInt(uint &result) const
Definition: ttmathbig.h:2333
Big(double value)
Definition: ttmathbig.h:3162
uint Sub(const UInt< value_size > &ss2, uint c=0)
uint Pow(UInt< pow_size > pow)
Definition: ttmathbig.h:1566
bool IsTheLowestBitSet() const
Definition: ttmathuint.h:2556
uint Add(const UInt< value_size > &ss2, uint c=0)
uint Ln(const Big< exp, man > &x)
Definition: ttmathbig.h:2126
void ClearInfoBit(unsigned char bit)
Definition: ttmathbig.h:224
Big< exp, man > & operator=(const wchar_t *string)
Definition: ttmathbig.h:5364
uint FromUInt(uint value)
Definition: ttmathbig.h:2520
Big(const Big< exp, man > &value)
Definition: ttmathbig.h:3681
uint Abs()
Definition: ttmathint.h:168
uint Mod(const Big< exp, man > &ss2)
Definition: ttmathbig.h:1521
void SetNan()
Definition: ttmathbig.h:296
static LibTypeCode LibType()
#define TTMATH_BIG_NAN
Definition: ttmathbig.h:104
bool IsTheHighestBitSet() const
Definition: ttmathuint.h:2547
void SetOne()
Definition: ttmathbig.h:271
uint Pow(const Big< exp, man > &pow)
Definition: ttmathbig.h:1779
void MulBig(const UInt< value_size > &ss2, UInt< value_size *2 > &result, uint algorithm=100)
Definition: ttmathuint.h:951
uint FromString(const std::string &string, const Conv &conv, const char **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4961
uint group_digits
Definition: ttmathtypes.h:503
Big(signed int value)
Definition: ttmathbig.h:3474
void Abs()
Definition: ttmathbig.h:682
uint FromFloat(float value)
Definition: ttmathbig.h:2815
void SetMax()
Definition: ttmathuint.h:215
uint ToInt(Int< int_size > &result) const
Definition: ttmathbig.h:2498
Big< exp, man > & operator=(unsigned int value)
Definition: ttmathbig.h:3440
uint FromDouble(double value)
Definition: ttmathbig.h:2718
uint Exp(const Big< exp, man > &x)
Definition: ttmathbig.h:1948
uint AddOne()
Definition: ttmathint.h:327
uint MulInt(sint ss2)
Definition: ttmathbig.h:1215
sint ToInt() const
Definition: ttmathbig.h:2348
uint Mod2() const
Definition: ttmathbig.h:1541
uint Sqrt()
Definition: ttmathbig.h:1817
#define TTMATH_UINT_HIGHEST_BIT
Definition: ttmathtypes.h:258
void SetE()
Definition: ttmathbig.h:433
uint Pow(Int< pow_size > pow)
Definition: ttmathbig.h:1618
uint MulInt(uint ss2)
Definition: ttmathuint.h:835
#define TTMATH_BIG_ZERO
Definition: ttmathbig.h:113
uint PowUInt(Big< exp, man > pow)
Definition: ttmathbig.h:1657
uint Mul(const Big< exp, man > &ss2, bool round=true)
Definition: ttmathbig.h:1355
uint BitOr(Big< exp, man > ss2)
Definition: ttmathbig.h:1053
bool EqualWithoutSign(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5473
void SetMax()
Definition: ttmathint.h:71
Big< exp, man > operator &(const Big< exp, man > &p2) const
Definition: ttmathbig.h:5721
static void AssignString(std::string &result, const char *str)
Definition: ttmathmisc.h:72
Big< exp, man > operator-() const
Definition: ttmathbig.h:5590
std::wstring ToWString(uint base=10) const
Definition: ttmathbig.h:3810
a namespace for the TTMath library
Definition: ttmath.h:62
void ChangeSign()
Definition: ttmathbig.h:740
uint Div(const Big< exp, man > &ss2, bool round=true)
Definition: ttmathbig.h:1452
void SetZero()
Definition: ttmathuint.h:188
uint FromString(const std::string &string, uint base=10, const char **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4952
void ToString(std::string &result, uint b=10) const
Definition: ttmathint.h:1332
uint ToUInt(UInt< int_size > &result) const
Definition: ttmathbig.h:2466
uint ToInt(unsigned int &result) const
Definition: ttmathbig.h:3381
bool IsZero() const
Definition: ttmathbig.h:648
Big(const std::wstring &string)
Definition: ttmathbig.h:5355
uint FromBig(const Big< another_exp, another_man > &another)
Definition: ttmathbig.h:2222
uint Div(const UInt< value_size > &divisor, UInt< value_size > *remainder=0, uint algorithm=3)
Definition: ttmathuint.h:1626
#define TTMATH_UINT_MAX_VALUE
Definition: ttmathtypes.h:264
Big(uint value)
Definition: ttmathbig.h:3153
bool AreFirstBitsZero(uint bits) const
Definition: ttmathuint.h:2618
void BitAnd(const UInt< value_size > &ss2)
Definition: ttmathuint.h:743
bool IsInteger() const
Definition: ttmathbig.h:5865
#define TTMATH_BUILTIN_VARIABLES_SIZE
Definition: ttmathtypes.h:271
Big< exp, man > & operator=(signed int value)
Definition: ttmathbig.h:3462
objects of this class are used to synchronize
uint Rcr(uint bits, uint c=0)
Definition: ttmathuint.h:555
double ToDouble() const
Definition: ttmathbig.h:2830
std::string ToString(const Conv &conv) const
Definition: ttmathbig.h:3732
uint Sub(const Big< exp, man > &ss2, bool round=true)
Definition: ttmathbig.h:978
Big(float value)
Definition: ttmathbig.h:3171
void BitOr(const UInt< value_size > &ss2)
Definition: ttmathuint.h:755
Big< exp, man > & operator=(double value)
Definition: ttmathbig.h:3134
template class Int<uint>
bool IsSign() const
Definition: ttmathint.h:156
uint Round()
Definition: ttmathbig.h:5911
bool IsNan() const
Definition: ttmathbig.h:667
uint SubOne()
Definition: ttmathint.h:340
Big< exp, man > & operator=(const Int< int_size > &value)
Definition: ttmathbig.h:3568
Big(unsigned int value)
Definition: ttmathbig.h:3452
Big(const std::string &string)
Definition: ttmathbig.h:5312
Big(const Big< another_exp, another_man > &value)
Definition: ttmathbig.h:3624
uint Add(const Int< value_size > &ss2)
Definition: ttmathint.h:220
uint AddInt(uint value, uint index=0)
Definition: ttmathint.h:237
Big< exp, man > & operator=(const UInt< int_size > &value)
Definition: ttmathbig.h:3590
static const char * LibTypeStr()
Definition: ttmathbig.h:145
#define TTMATH_BITS_PER_UINT
Definition: ttmathtypes.h:253
uint FromUInt(UInt< int_size > value)
Definition: ttmathbig.h:3520
uint ChangeSign()
Definition: ttmathint.h:105
void BitXor(const UInt< value_size > &ss2)
Definition: ttmathuint.h:767
Big< exp, man > & operator=(const char *string)
Definition: ttmathbig.h:5321
uint CompensationToLeft()
Definition: ttmathuint.h:598
bool IsInfoBit(unsigned char bit) const
Definition: ttmathbig.h:247
Big(const char *string)
Definition: ttmathbig.h:5303
bool SmallerWithoutSignThan(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5401
uint FromInt(const UInt< int_size > &value)
Definition: ttmathbig.h:3533
std::wstring ToWString(const Conv &conv) const
Definition: ttmathbig.h:3797
Big(sint value)
Definition: ttmathbig.h:3145
uint ToString(std::string &result, const Conv &conv) const
Definition: ttmathbig.h:3722
void Set2Pi()
Definition: ttmathbig.h:419
uint ToDouble(double &result) const
Definition: ttmathbig.h:2961
void SetPi()
Definition: ttmathbig.h:393
Big(const Int< int_size > &value)
Definition: ttmathbig.h:3580
uint ToString(std::wstring &result, const Conv &conv) const
Definition: ttmathbig.h:3787
Big< exp, man > & operator=(const Big< exp, man > &value)
Definition: ttmathbig.h:3667
uint PowInt(const Big< exp, man > &pow)
Definition: ttmathbig.h:1713
uint ToString(std::wstring &result, uint base=10, bool scient=false, sint scient_from=15, sint round=-1, bool trim_zeroes=true, wchar_t comma='.') const
Definition: ttmathbig.h:3762
#define TTMATH_BIG_SIGN
Definition: ttmathbig.h:97
void SetInfoBit(unsigned char bit)
Definition: ttmathbig.h:236
uint ToUInt(unsigned int &result) const
Definition: ttmathbig.h:3362
void Sgn()
Definition: ttmathbig.h:696
Big< exp, man > & operator=(const std::string &string)
Definition: ttmathbig.h:5332
unsigned long uint
Definition: ttmathtypes.h:238
uint BitXor(Big< exp, man > ss2)
Definition: ttmathbig.h:1109
uint DivInt(sint ss2, sint *remainder=0)
Definition: ttmathint.h:524
Big(const UInt< int_size > &value)
Definition: ttmathbig.h:3602
uint FromString(const std::wstring &string, const Conv &conv, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:5002
void ToString(std::string &result, uint b=10) const
Definition: ttmathuint.h:3370
uint Add(Big< exp, man > ss2, bool round=true, bool adding=true)
Definition: ttmathbig.h:930
Big< exp, man > & operator++()
Definition: ttmathbig.h:5674
void ClearFirstBits(uint n)
Definition: ttmathuint.h:2508
Big< exp, man > & operator=(sint value)
Definition: ttmathbig.h:3101
uint MulUInt(uint ss2)
Definition: ttmathbig.h:1161
Some objects used in multithreads environment.
void SkipFraction()
Definition: ttmathbig.h:5790
uint AddOne()
Definition: ttmathuint.h:386
void SetOne()
Definition: ttmathuint.h:202
bool IsZero() const
Definition: ttmathuint.h:2605
uint BitAnd(Big< exp, man > ss2)
Definition: ttmathbig.h:994
uint GetBit(uint bit_index) const
Definition: ttmathuint.h:706
uint Standardizing()
Definition: ttmathbig.h:173
uint ToUInt() const
Definition: ttmathuint.h:3103
void SetLn2()
Definition: ttmathbig.h:490
bool GreaterWithoutSignThan(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5435
Big implements the floating point numbers.
Definition: ttmathbig.h:63
uint Log(const Big< exp, man > &x, const Big< exp, man > &base)
Definition: ttmathbig.h:2171
uint SubInt(uint value, uint index=0)
Definition: ttmathint.h:314
Big< exp, man > operator++(int)
Definition: ttmathbig.h:5685
void Set05Pi()
Definition: ttmathbig.h:406
void SetMax()
Definition: ttmathbig.h:618
bool trim_zeroes
Definition: ttmathtypes.h:469
uint FromString(const char *source, const Conv &conv, const char **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4943
#define TTMATH_REFERENCE_ASSERT(expression)
Definition: ttmathtypes.h:681
void SetZero()
Definition: ttmathbig.h:256
uint FromInt(uint value)
Definition: ttmathbig.h:2546
void Swap(UInt< value_size > &ss2)
Definition: ttmathuint.h:239
void SetMin()
Definition: ttmathbig.h:632
friend std::wistream & operator>>(std::wistream &s, Big< exp, man > &l)
Definition: ttmathbig.h:6081
uint Sub(const Int< value_size > &ss2)
Definition: ttmathint.h:299
void Swap(Big< exp, man > &ss2)
Definition: ttmathbig.h:316
friend std::istream & operator>>(std::istream &s, Big< exp, man > &l)
Definition: ttmathbig.h:6070
uint SubOne()
Definition: ttmathuint.h:395
sint ToInt() const
Definition: ttmathint.h:1132