All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 (new) BSD licence.
4  * Author: Tomasz Sowa <t.sowa@ttmath.org>
5  */
6 
7 /*
8  * Copyright (c) 2006-2012, 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 
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 
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) making 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 
89 unsigned char info;
90 
91 
97 #define TTMATH_BIG_SIGN 128
98 
99 
104 #define TTMATH_BIG_NAN 64
105 
106 
113 #define TTMATH_BIG_ZERO 32
114 
115 
122  {
123  if( c != 0 )
124  {
125  SetNan();
126  return 1;
127  }
128 
129  return 0;
130  }
131 
132 public:
133 
134 
145  static const char * LibTypeStr()
146  {
147  return UInt<man>::LibTypeStr();
148  }
149 
150 
155  {
156  return UInt<man>::LibType();
157  }
158 
159 
160 
174  {
176  {
178  return 0;
179  }
180 
181  if( CorrectZero() )
182  return 0;
183 
185 
186  return exponent.Sub( comp );
187  }
188 
189 
190 private:
191 
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 
224  void ClearInfoBit(unsigned char bit)
225  {
226  info = info & (~bit);
227  }
228 
229 
236  void SetInfoBit(unsigned char bit)
237  {
238  info = info | bit;
239  }
240 
241 
247  bool IsInfoBit(unsigned char bit) const
248  {
249  return (info & bit) != 0;
250  }
251 
252 
256  void SetZero()
257  {
259  exponent.SetZero();
260  mantissa.SetZero();
261 
262  /*
263  we don't have to compensate zero
264  */
265  }
266 
267 
271  void SetOne()
272  {
273  info = 0;
274  mantissa.SetZero();
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 
285  void Set05()
286  {
287  SetOne();
288  exponent.SubOne();
289  }
290 
291 
296  void SetNan()
297  {
299  }
300 
301 
306  void SetZeroNan()
307  {
308  SetZero();
309  SetNan();
310  }
311 
312 
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 
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 
393  void SetPi()
394  {
395  SetMantissaPi();
396  info = 0;
397  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
398  }
399 
400 
404  void Set05Pi()
405  {
406  SetMantissaPi();
407  info = 0;
408  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
409  }
410 
411 
415  void Set2Pi()
416  {
417  SetMantissaPi();
418  info = 0;
419  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
420  }
421 
422 
427  void SetE()
428  {
429  static const unsigned int temp_table[] = {
430  0xadf85458, 0xa2bb4a9a, 0xafdc5620, 0x273d3cf1, 0xd8b9c583, 0xce2d3695, 0xa9e13641, 0x146433fb,
431  0xcc939dce, 0x249b3ef9, 0x7d2fe363, 0x630c75d8, 0xf681b202, 0xaec4617a, 0xd3df1ed5, 0xd5fd6561,
432  0x2433f51f, 0x5f066ed0, 0x85636555, 0x3ded1af3, 0xb557135e, 0x7f57c935, 0x984f0c70, 0xe0e68b77,
433  0xe2a689da, 0xf3efe872, 0x1df158a1, 0x36ade735, 0x30acca4f, 0x483a797a, 0xbc0ab182, 0xb324fb61,
434  0xd108a94b, 0xb2c8e3fb, 0xb96adab7, 0x60d7f468, 0x1d4f42a3, 0xde394df4, 0xae56ede7, 0x6372bb19,
435  0x0b07a7c8, 0xee0a6d70, 0x9e02fce1, 0xcdf7e2ec, 0xc03404cd, 0x28342f61, 0x9172fe9c, 0xe98583ff,
436  0x8e4f1232, 0xeef28183, 0xc3fe3b1b, 0x4c6fad73, 0x3bb5fcbc, 0x2ec22005, 0xc58ef183, 0x7d1683b2,
437  0xc6f34a26, 0xc1b2effa, 0x886b4238, 0x611fcfdc, 0xde355b3b, 0x6519035b, 0xbc34f4de, 0xf99c0238,
438  0x61b46fc9, 0xd6e6c907, 0x7ad91d26, 0x91f7f7ee, 0x598cb0fa, 0xc186d91c, 0xaefe1309, 0x85139270,
439  0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x64f2e21e, 0x71f54bff, 0x5cae82ab, 0x9c9df69e,
440  0xe86d2bc5, 0x22363a0d, 0xabc52197, 0x9b0deada, 0x1dbf9a42, 0xd5c4484e, 0x0abcd06b, 0xfa53ddef,
441  0x3c1b20ee, 0x3fd59d7c, 0x25e41d2b, 0x669e1ef1, 0x6e6f52c3, 0x164df4fb, 0x7930e9e4, 0xe58857b6,
442  0xac7d5f42, 0xd69f6d18, 0x7763cf1d, 0x55034004, 0x87f55ba5, 0x7e31cc7a, 0x7135c886, 0xefb4318a,
443  0xed6a1e01, 0x2d9e6832, 0xa907600a, 0x918130c4, 0x6dc778f9, 0x71ad0038, 0x092999a3, 0x33cb8b7a,
444  0x1a1db93d, 0x7140003c, 0x2a4ecea9, 0xf98d0acc, 0x0a8291cd, 0xcec97dcf, 0x8ec9b55a, 0x7f88a46b,
445  0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a,
446  0x23ba4442, 0xcaf53ea6, 0x3bb45432, 0x9b7624c8, 0x917bdd64, 0xb1c0fd4c, 0xb38e8c33, 0x4c701c3a,
447  0xcdad0657, 0xfccfec71, 0x9b1f5c3e, 0x4e46041f, 0x388147fb, 0x4cfdb477, 0xa52471f7, 0xa9a96910,
448  0xb855322e, 0xdb6340d8, 0xa00ef092, 0x350511e3, 0x0abec1ff, 0xf9e3a26e, 0x7fb29f8c, 0x183023c3,
449  0x587e38da, 0x0077d9b4, 0x763e4e4b, 0x94b2bbc1, 0x94c6651e, 0x77caf992, 0xeeaac023, 0x2a281bf6,
450  0xb3a739c1, 0x22611682, 0x0ae8db58, 0x47a67cbe, 0xf9c9091b, 0x462d538c, 0xd72b0374, 0x6ae77f5e,
451  0x62292c31, 0x1562a846, 0x505dc82d, 0xb854338a, 0xe49f5235, 0xc95b9117, 0x8ccf2dd5, 0xcacef403,
452  0xec9d1810, 0xc6272b04, 0x5b3b71f9, 0xdc6b80d6, 0x3fdd4a8e, 0x9adb1e69, 0x62a69526, 0xd43161c1,
453  0xa41d570d, 0x7938dad4, 0xa40e329c, 0xcff46aaa, 0x36ad004c, 0xf600c838, 0x1e425a31, 0xd951ae64,
454  0xfdb23fce, 0xc9509d43, 0x687feb69, 0xedd1cc5e, 0x0b8cc3bd, 0xf64b10ef, 0x86b63142, 0xa3ab8829,
455  0x555b2f74, 0x7c932665, 0xcb2c0f1c, 0xc01bd702, 0x29388839, 0xd2af05e4, 0x54504ac7, 0x8b758282,
456  0x2846c0ba, 0x35c35f5c, 0x59160cc0, 0x46fd8251, 0x541fc68c, 0x9c86b022, 0xbb709987, 0x6a460e74,
457  0x51a8a931, 0x09703fee, 0x1c217e6c, 0x3826e52c, 0x51aa691e, 0x0e423cfc, 0x99e9e316, 0x50c1217b,
458  0x624816cd, 0xad9a95f9, 0xd5b80194, 0x88d9c0a0, 0xa1fe3075, 0xa577e231, 0x83f81d4a, 0x3f2fa457,
459  0x1efc8ce0, 0xba8a4fe8, 0xb6855dfe, 0x72b0a66e, 0xded2fbab, 0xfbe58a30, 0xfafabe1c, 0x5d71a87e,
460  0x2f741ef8, 0xc1fe86fe, 0xa6bbfde5, 0x30677f0d, 0x97d11d49, 0xf7a8443d, 0x0822e506, 0xa9f4614e,
461  0x011e2a94, 0x838ff88c, 0xd68c8bb7, 0xc51eef6d, 0x49ea8ab4, 0xf2c3df5b, 0xb4e0735a, 0xb0d68749
462  // 0x2fe26dd4, ...
463  // 256 32bit words for the mantissa -- about 2464 valid decimal digits
464  };
465 
466  // above value was calculated using Big<1,400> type on a 32bit platform
467  // and then the first 256 words were taken,
468  // the calculating was made by using ExpSurrounding0(1) method
469  // which took 1420 iterations
470  // (the result was compared with e taken from http://antwrp.gsfc.nasa.gov/htmltest/gifcity/e.2mil)
471  // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
472  // and on 64bit platform value 128 (256/2=128))
473 
474  mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
475  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
476  info = 0;
477  }
478 
479 
484  void SetLn2()
485  {
486  static const unsigned int temp_table[] = {
487  0xb17217f7, 0xd1cf79ab, 0xc9e3b398, 0x03f2f6af, 0x40f34326, 0x7298b62d, 0x8a0d175b, 0x8baafa2b,
488  0xe7b87620, 0x6debac98, 0x559552fb, 0x4afa1b10, 0xed2eae35, 0xc1382144, 0x27573b29, 0x1169b825,
489  0x3e96ca16, 0x224ae8c5, 0x1acbda11, 0x317c387e, 0xb9ea9bc3, 0xb136603b, 0x256fa0ec, 0x7657f74b,
490  0x72ce87b1, 0x9d6548ca, 0xf5dfa6bd, 0x38303248, 0x655fa187, 0x2f20e3a2, 0xda2d97c5, 0x0f3fd5c6,
491  0x07f4ca11, 0xfb5bfb90, 0x610d30f8, 0x8fe551a2, 0xee569d6d, 0xfc1efa15, 0x7d2e23de, 0x1400b396,
492  0x17460775, 0xdb8990e5, 0xc943e732, 0xb479cd33, 0xcccc4e65, 0x9393514c, 0x4c1a1e0b, 0xd1d6095d,
493  0x25669b33, 0x3564a337, 0x6a9c7f8a, 0x5e148e82, 0x074db601, 0x5cfe7aa3, 0x0c480a54, 0x17350d2c,
494  0x955d5179, 0xb1e17b9d, 0xae313cdb, 0x6c606cb1, 0x078f735d, 0x1b2db31b, 0x5f50b518, 0x5064c18b,
495  0x4d162db3, 0xb365853d, 0x7598a195, 0x1ae273ee, 0x5570b6c6, 0x8f969834, 0x96d4e6d3, 0x30af889b,
496  0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef9, 0x8d6f5177, 0xfbcf0755, 0x268a5c1f, 0x9538b982,
497  0x61affd44, 0x6b1ca3cf, 0x5e9222b8, 0x8c66d3c5, 0x422183ed, 0xc9942109, 0x0bbb16fa, 0xf3d949f2,
498  0x36e02b20, 0xcee886b9, 0x05c128d5, 0x3d0bd2f9, 0x62136319, 0x6af50302, 0x0060e499, 0x08391a0c,
499  0x57339ba2, 0xbeba7d05, 0x2ac5b61c, 0xc4e9207c, 0xef2f0ce2, 0xd7373958, 0xd7622658, 0x901e646a,
500  0x95184460, 0xdc4e7487, 0x156e0c29, 0x2413d5e3, 0x61c1696d, 0xd24aaebd, 0x473826fd, 0xa0c238b9,
501  0x0ab111bb, 0xbd67c724, 0x972cd18b, 0xfbbd9d42, 0x6c472096, 0xe76115c0, 0x5f6f7ceb, 0xac9f45ae,
502  0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd8,
503  0x85db6ab0, 0x3a49bd0d, 0xc0b1b31d, 0x8a0e23fa, 0xc5e5767d, 0xf95884e0, 0x6425a415, 0x26fac51c,
504  0x3ea8449f, 0xe8f70edd, 0x062b1a63, 0xa6c4c60c, 0x52ab3316, 0x1e238438, 0x897a39ce, 0x78b63c9f,
505  0x364f5b8a, 0xef22ec2f, 0xee6e0850, 0xeca42d06, 0xfb0c75df, 0x5497e00c, 0x554b03d7, 0xd2874a00,
506  0x0ca8f58d, 0x94f0341c, 0xbe2ec921, 0x56c9f949, 0xdb4a9316, 0xf281501e, 0x53daec3f, 0x64f1b783,
507  0x154c6032, 0x0e2ff793, 0x33ce3573, 0xfacc5fdc, 0xf1178590, 0x3155bbd9, 0x0f023b22, 0x0224fcd8,
508  0x471bf4f4, 0x45f0a88a, 0x14f0cd97, 0x6ea354bb, 0x20cdb5cc, 0xb3db2392, 0x88d58655, 0x4e2a0e8a,
509  0x6fe51a8c, 0xfaa72ef2, 0xad8a43dc, 0x4212b210, 0xb779dfe4, 0x9d7307cc, 0x846532e4, 0xb9694eda,
510  0xd162af05, 0x3b1751f3, 0xa3d091f6, 0x56658154, 0x12b5e8c2, 0x02461069, 0xac14b958, 0x784934b8,
511  0xd6cce1da, 0xa5053701, 0x1aa4fb42, 0xb9a3def4, 0x1bda1f85, 0xef6fdbf2, 0xf2d89d2a, 0x4b183527,
512  0x8fd94057, 0x89f45681, 0x2b552879, 0xa6168695, 0xc12963b0, 0xff01eaab, 0x73e5b5c1, 0x585318e7,
513  0x624f14a5, 0x1a4a026b, 0x68082920, 0x57fd99b6, 0x6dc085a9, 0x8ac8d8ca, 0xf9eeeea9, 0x8a2400ca,
514  0xc95f260f, 0xd10036f9, 0xf91096ac, 0x3195220a, 0x1a356b2a, 0x73b7eaad, 0xaf6d6058, 0x71ef7afb,
515  0x80bc4234, 0x33562e94, 0xb12dfab4, 0x14451579, 0xdf59eae0, 0x51707062, 0x4012a829, 0x62c59cab,
516  0x347f8304, 0xd889659e, 0x5a9139db, 0x14efcc30, 0x852be3e8, 0xfc99f14d, 0x1d822dd6, 0xe2f76797,
517  0xe30219c8, 0xaa9ce884, 0x8a886eb3, 0xc87b7295, 0x988012e8, 0x314186ed, 0xbaf86856, 0xccd3c3b6,
518  0xee94e62f, 0x110a6783, 0xd2aae89c, 0xcc3b76fc, 0x435a0ce1, 0x34c2838f, 0xd571ec6c, 0x1366a993 // last one was: 0x1366a992
519  //0xcbb9ac40, ...
520  // (the last word 0x1366a992 was rounded up because the next one is 0xcbb9ac40 -- first bit is one 0xc..)
521  // 256 32bit words for the mantissa -- about 2464 valid decimal digits
522  };
523 
524  // above value was calculated using Big<1,400> type on a 32bit platform
525  // and then the first 256 words were taken,
526  // the calculating was made by using LnSurrounding1(2) method
527  // which took 4035 iterations
528  // (the result was compared with ln(2) taken from http://ja0hxv.calico.jp/pai/estart.html)
529  // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
530  // and on 64bit platform value 128 (256/2=128))
531 
532  mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
534  info = 0;
535  }
536 
537 
552  void SetLn10()
553  {
554  static const unsigned int temp_table[] = {
555  0x935d8ddd, 0xaaa8ac16, 0xea56d62b, 0x82d30a28, 0xe28fecf9, 0xda5df90e, 0x83c61e82, 0x01f02d72,
556  0x962f02d7, 0xb1a8105c, 0xcc70cbc0, 0x2c5f0d68, 0x2c622418, 0x410be2da, 0xfb8f7884, 0x02e516d6,
557  0x782cf8a2, 0x8a8c911e, 0x765aa6c3, 0xb0d831fb, 0xef66ceb0, 0x4ab3c6fa, 0x5161bb49, 0xd219c7bb,
558  0xca67b35b, 0x23605085, 0x8e93368d, 0x44789c4f, 0x5b08b057, 0xd5ede20f, 0x469ea58e, 0x9305e981,
559  0xe2478fca, 0xad3aee98, 0x9cd5b42e, 0x6a271619, 0xa47ecb26, 0x978c5d4f, 0xdb1d28ea, 0x57d4fdc0,
560  0xe40bf3cc, 0x1e14126a, 0x45765cde, 0x268339db, 0xf47fa96d, 0xeb271060, 0xaf88486e, 0xa9b7401e,
561  0x3dfd3c51, 0x748e6d6e, 0x3848c8d2, 0x5faf1bca, 0xe88047f1, 0x7b0d9b50, 0xa949eaaa, 0xdf69e8a5,
562  0xf77e3760, 0x4e943960, 0xe38a5700, 0xffde2db1, 0xad6bfbff, 0xd821ba0a, 0x4cb0466d, 0x61ba648e,
563  0xef99c8e5, 0xf6974f36, 0x3982a78c, 0xa45ddfc8, 0x09426178, 0x19127a6e, 0x3b70fcda, 0x2d732d47,
564  0xb5e4b1c8, 0xc0e5a10a, 0xaa6604a5, 0x324ec3dc, 0xbc64ea80, 0x6e198566, 0x1f1d366c, 0x20663834,
565  0x4d5e843f, 0x20642b97, 0x0a62d18e, 0x478f7bd5, 0x8fcd0832, 0x4a7b32a6, 0xdef85a05, 0xeb56323a,
566  0x421ef5e0, 0xb00410a0, 0xa0d9c260, 0x794a976f, 0xf6ff363d, 0xb00b6b33, 0xf42c58de, 0xf8a3c52d,
567  0xed69b13d, 0xc1a03730, 0xb6524dc1, 0x8c167e86, 0x99d6d20e, 0xa2defd2b, 0xd006f8b4, 0xbe145a2a,
568  0xdf3ccbb3, 0x189da49d, 0xbc1261c8, 0xb3e4daad, 0x6a36cecc, 0xb2d5ae5b, 0x89bf752f, 0xb5dfb353,
569  0xff3065c4, 0x0cfceec8, 0x1be5a9a9, 0x67fddc57, 0xc4b83301, 0x006bf062, 0x4b40ed7a, 0x56c6cdcd,
570  0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f8,
571  0xfb5f06c3, 0x58ac8f70, 0xfa9d8c59, 0x8c574502, 0xbaf54c96, 0xc84911f0, 0x0482d095, 0x1a0af022,
572  0xabbab080, 0xec97efd3, 0x671e4e0e, 0x52f166b6, 0xcd5cd226, 0x0dc67795, 0x2e1e34a3, 0xf799677f,
573  0x2c1d48f1, 0x2944b6c5, 0x2ba1307e, 0x704d67f9, 0x1c1035e4, 0x4e927c63, 0x03cf12bf, 0xe2cd2e31,
574  0xf8ee4843, 0x344d51b0, 0xf37da42b, 0x9f0b0fd9, 0x134fb2d9, 0xf815e490, 0xd966283f, 0x23962766,
575  0xeceab1e4, 0xf3b5fc86, 0x468127e2, 0xb606d10d, 0x3a45f4b6, 0xb776102d, 0x2fdbb420, 0x80c8fa84,
576  0xd0ff9f45, 0xc58aef38, 0xdb2410fd, 0x1f1cebad, 0x733b2281, 0x52ca5f36, 0xddf29daa, 0x544334b8,
577  0xdeeaf659, 0x4e462713, 0x1ed485b4, 0x6a0822e1, 0x28db471c, 0xa53938a8, 0x44c3bef7, 0xf35215c8,
578  0xb382bc4e, 0x3e4c6f15, 0x6285f54c, 0x17ab408e, 0xccbf7f5e, 0xd16ab3f6, 0xced2846d, 0xf457e14f,
579  0xbb45d9c5, 0x646ad497, 0xac697494, 0x145de32e, 0x93907128, 0xd263d521, 0x79efb424, 0xd64651d6,
580  0xebc0c9f0, 0xbb583a44, 0xc6412c84, 0x85bb29a6, 0x4d31a2cd, 0x92954469, 0xa32b1abd, 0xf7f5202c,
581  0xa4aa6c93, 0x2e9b53cf, 0x385ab136, 0x2741f356, 0x5de9c065, 0x6009901c, 0x88abbdd8, 0x74efcf73,
582  0x3f761ad4, 0x35f3c083, 0xfd6b8ee0, 0x0bef11c7, 0xc552a89d, 0x58ce4a21, 0xd71e54f2, 0x4157f6c7,
583  0xd4622316, 0xe98956d7, 0x450027de, 0xcbd398d8, 0x4b98b36a, 0x0724c25c, 0xdb237760, 0xe9324b68,
584  0x7523e506, 0x8edad933, 0x92197f00, 0xb853a326, 0xb330c444, 0x65129296, 0x34bc0670, 0xe177806d,
585  0xe338dac4, 0x5537492a, 0xe19add83, 0xcf45000f, 0x5b423bce, 0x6497d209, 0xe30e18a1, 0x3cbf0687,
586  0x67973103, 0xd9485366, 0x81506bba, 0x2e93a9a4, 0x7dd59d3f, 0xf17cd746, 0x8c2075be, 0x552a4348 // last one was: 0x552a4347
587  // 0xb4a638ef, ...
588  //(the last word 0x552a4347 was rounded up because the next one is 0xb4a638ef -- first bit is one 0xb..)
589  // 256 32bit words for the mantissa -- about 2464 valid digits (decimal)
590  };
591 
592  // above value was calculated using Big<1,400> type on a 32bit platform
593  // and then the first 256 32bit words were taken,
594  // the calculating was made by using LnSurrounding1(10) method
595  // which took 22080 iterations
596  // (the result was compared with ln(10) taken from http://ja0hxv.calico.jp/pai/estart.html)
597  // (the formula used in LnSurrounding1(x) converges badly when
598  // the x is greater than one but in fact we can use it, only the
599  // number of iterations will be greater)
600  // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
601  // and on 64bit platform value 128 (256/2=128))
602 
603  mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
604  exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
605  info = 0;
606  }
607 
608 
612  void SetMax()
613  {
614  info = 0;
615  mantissa.SetMax();
616  exponent.SetMax();
617 
618  // we don't have to use 'Standardizing()' because the last bit from
619  // the mantissa is set
620  }
621 
622 
626  void SetMin()
627  {
628  info = 0;
629 
630  mantissa.SetMax();
631  exponent.SetMax();
632  SetSign();
633 
634  // we don't have to use 'Standardizing()' because the last bit from
635  // the mantissa is set
636  }
637 
638 
642  bool IsZero() const
643  {
644  return IsInfoBit(TTMATH_BIG_ZERO);
645  }
646 
647 
652  bool IsSign() const
653  {
654  return IsInfoBit(TTMATH_BIG_SIGN);
655  }
656 
657 
661  bool IsNan() const
662  {
663  return IsInfoBit(TTMATH_BIG_NAN);
664  }
665 
666 
667 
676  void Abs()
677  {
679  }
680 
681 
688  void Sgn()
689  {
690  // we have to check the NaN flag, because the next SetOne() method would clear it
691  if( IsNan() )
692  return;
693 
694  if( IsSign() )
695  {
696  SetOne();
697  SetSign();
698  }
699  else
700  if( IsZero() )
701  SetZero(); // !! is nedeed here?
702  else
703  SetOne();
704  }
705 
706 
707 
718  void SetSign()
719  {
721  }
722 
723 
732  void ChangeSign()
733  {
734  // we don't have to check the NaN flag here
735 
736  if( IsZero() )
737  return;
738 
739  if( IsSign() )
741  else
743  }
744 
745 
746 
747 private:
748 
759  uint RoundHalfToEven(bool is_half, bool rounding_up = true)
760  {
761  uint c = 0;
762 
763  if( !is_half || mantissa.IsTheLowestBitSet() )
764  {
765  if( rounding_up )
766  {
767  if( mantissa.AddOne() )
768  {
769  mantissa.Rcr(1, 1);
770  c = exponent.AddOne();
771  }
772  }
773  else
774  {
775  #ifdef TTMATH_DEBUG
776  uint c_from_zero =
777  #endif
778  mantissa.SubOne();
779 
780  // we're using rounding_up=false in Add() when the mantissas have different signs
781  // mantissa can be zero only when previous mantissa was equal to ss2.mantissa
782  // but in such a case 'last_bit_set' will not be set and consequently 'do_rounding' will be false
783  TTMATH_ASSERT( c_from_zero == 0 )
784  }
785  }
786 
787  return c;
788  }
789 
790 
791 
792 
793 
804  uint AddOne()
805  {
806  Big<exp, man> one;
807 
808  one.SetOne();
809 
810  return Add(one);
811  }
812 
813 
817  uint SubOne()
818  {
819  Big<exp, man> one;
820 
821  one.SetOne();
822 
823  return Sub(one);
824  }
825 
826 
827 private:
828 
829 
833  void AddCheckExponents( Big<exp, man> & ss2,
834  Int<exp> & exp_offset,
835  bool & last_bit_set,
836  bool & rest_zero,
837  bool & do_adding,
838  bool & do_rounding)
839  {
840  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
841 
842  if( exp_offset == mantissa_size_in_bits )
843  {
844  last_bit_set = ss2.mantissa.IsTheHighestBitSet();
845  rest_zero = ss2.mantissa.AreFirstBitsZero(man*TTMATH_BITS_PER_UINT - 1);
846  do_rounding = true; // we'are only rounding
847  }
848  else
849  if( exp_offset < mantissa_size_in_bits )
850  {
851  uint moved = exp_offset.ToInt(); // how many times we must move ss2.mantissa
852  rest_zero = true;
853 
854  if( moved > 0 )
855  {
856  last_bit_set = static_cast<bool>( ss2.mantissa.GetBit(moved-1) );
857 
858  if( moved > 1 )
859  rest_zero = ss2.mantissa.AreFirstBitsZero(moved - 1);
860 
861  // (2) moving 'exp_offset' times
862  ss2.mantissa.Rcr(moved, 0);
863  }
864 
865  do_adding = true;
866  do_rounding = true;
867  }
868 
869  // if exp_offset is greater than mantissa_size_in_bits then we do nothing
870  // ss2 is too small for taking into consideration in the sum
871  }
872 
873 
877  uint AddMantissas( Big<exp, man> & ss2,
878  bool & last_bit_set,
879  bool & rest_zero)
880  {
881  uint c = 0;
882 
883  if( IsSign() == ss2.IsSign() )
884  {
885  // values have the same signs
886  if( mantissa.Add(ss2.mantissa) )
887  {
888  // we have one bit more from addition (carry)
889  // now rest_zero means the old rest_zero with the old last_bit_set
890  rest_zero = (!last_bit_set && rest_zero);
891  last_bit_set = mantissa.Rcr(1,1);
892  c += exponent.AddOne();
893  }
894  }
895  else
896  {
897  // values have different signs
898  // there shouldn't be a carry here because
899  // (1) (2) guarantee that the mantissa of this
900  // is greater than or equal to the mantissa of the ss2
901 
902  #ifdef TTMATH_DEBUG
903  uint c_temp =
904  #endif
905  mantissa.Sub(ss2.mantissa);
906 
907  TTMATH_ASSERT( c_temp == 0 )
908  }
909 
910  return c;
911  }
912 
913 
914 public:
915 
916 
922  uint Add(Big<exp, man> ss2, bool round = true, bool adding = true)
923  {
924  bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
925  Int<exp> exp_offset( exponent );
926  uint c = 0;
927 
928  if( IsNan() || ss2.IsNan() )
929  return CheckCarry(1);
930 
931  if( !adding )
932  ss2.ChangeSign(); // subtracting
933 
934  exp_offset.Sub( ss2.exponent );
935  exp_offset.Abs();
936 
937  // (1) abs(this) will be >= abs(ss2)
938  if( SmallerWithoutSignThan(ss2) )
939  Swap(ss2);
940 
941  if( ss2.IsZero() )
942  return 0;
943 
944  last_bit_set = rest_zero = do_adding = do_rounding = false;
945  rounding_up = (IsSign() == ss2.IsSign());
946 
947  AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
948 
949  if( do_adding )
950  c += AddMantissas(ss2, last_bit_set, rest_zero);
951 
952  if( !round || !last_bit_set )
953  do_rounding = false;
954 
955  if( do_rounding )
956  c += RoundHalfToEven(rest_zero, rounding_up);
957 
958  if( do_adding || do_rounding )
959  c += Standardizing();
960 
961  return CheckCarry(c);
962  }
963 
964 
970  uint Sub(const Big<exp, man> & ss2, bool round = true)
971  {
972  return Add(ss2, round, false);
973  }
974 
975 
986  {
987  if( IsNan() || ss2.IsNan() )
988  return CheckCarry(1);
989 
990  if( IsSign() || ss2.IsSign() )
991  {
992  SetNan();
993  return 2;
994  }
995 
996  if( IsZero() )
997  return 0;
998 
999  if( ss2.IsZero() )
1000  {
1001  SetZero();
1002  return 0;
1003  }
1004 
1005  Int<exp> exp_offset( exponent );
1006  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
1007 
1008  uint c = 0;
1009 
1010  exp_offset.Sub( ss2.exponent );
1011  exp_offset.Abs();
1012 
1013  // abs(this) will be >= abs(ss2)
1014  if( SmallerWithoutSignThan(ss2) )
1015  Swap(ss2);
1016 
1017  if( exp_offset >= mantissa_size_in_bits )
1018  {
1019  // the second value is too small
1020  SetZero();
1021  return 0;
1022  }
1023 
1024  // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
1025  ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
1026  mantissa.BitAnd(ss2.mantissa);
1027 
1028  c += Standardizing();
1029 
1030  return CheckCarry(c);
1031  }
1032 
1033 
1044  {
1045  if( IsNan() || ss2.IsNan() )
1046  return CheckCarry(1);
1047 
1048  if( IsSign() || ss2.IsSign() )
1049  {
1050  SetNan();
1051  return 2;
1052  }
1053 
1054  if( IsZero() )
1055  {
1056  *this = ss2;
1057  return 0;
1058  }
1059 
1060  if( ss2.IsZero() )
1061  return 0;
1062 
1063  Int<exp> exp_offset( exponent );
1064  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
1065 
1066  uint c = 0;
1067 
1068  exp_offset.Sub( ss2.exponent );
1069  exp_offset.Abs();
1070 
1071  // abs(this) will be >= abs(ss2)
1072  if( SmallerWithoutSignThan(ss2) )
1073  Swap(ss2);
1074 
1075  if( exp_offset >= mantissa_size_in_bits )
1076  // the second value is too small
1077  return 0;
1078 
1079  // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
1080  ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
1081  mantissa.BitOr(ss2.mantissa);
1082 
1083  c += Standardizing();
1084 
1085  return CheckCarry(c);
1086  }
1087 
1088 
1099  {
1100  if( IsNan() || ss2.IsNan() )
1101  return CheckCarry(1);
1102 
1103  if( IsSign() || ss2.IsSign() )
1104  {
1105  SetNan();
1106  return 2;
1107  }
1108 
1109  if( ss2.IsZero() )
1110  return 0;
1111 
1112  if( IsZero() )
1113  {
1114  *this = ss2;
1115  return 0;
1116  }
1117 
1118  Int<exp> exp_offset( exponent );
1119  Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
1120 
1121  uint c = 0;
1122 
1123  exp_offset.Sub( ss2.exponent );
1124  exp_offset.Abs();
1125 
1126  // abs(this) will be >= abs(ss2)
1127  if( SmallerWithoutSignThan(ss2) )
1128  Swap(ss2);
1129 
1130  if( exp_offset >= mantissa_size_in_bits )
1131  // the second value is too small
1132  return 0;
1133 
1134  // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
1135  ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
1136  mantissa.BitXor(ss2.mantissa);
1137 
1138  c += Standardizing();
1139 
1140  return CheckCarry(c);
1141  }
1142 
1143 
1144 
1151  {
1152  UInt<man+1> man_result;
1153  uint i,c = 0;
1154 
1155  if( IsNan() )
1156  return 1;
1157 
1158  if( IsZero() )
1159  return 0;
1160 
1161  if( ss2 == 0 )
1162  {
1163  SetZero();
1164  return 0;
1165  }
1166 
1167  // man_result = mantissa * ss2.mantissa
1168  mantissa.MulInt(ss2, man_result);
1169 
1170  sint bit = UInt<man>::FindLeadingBitInWord(man_result.table[man]); // man - last word
1171 
1172  if( bit!=-1 && uint(bit) > (TTMATH_BITS_PER_UINT/2) )
1173  {
1174  // 'i' will be from 0 to TTMATH_BITS_PER_UINT
1175  i = man_result.CompensationToLeft();
1176  c = exponent.Add( TTMATH_BITS_PER_UINT - i );
1177 
1178  for(i=0 ; i<man ; ++i)
1179  mantissa.table[i] = man_result.table[i+1];
1180  }
1181  else
1182  {
1183  if( bit != -1 )
1184  {
1185  man_result.Rcr(bit+1, 0);
1186  c += exponent.Add(bit+1);
1187  }
1188 
1189  for(i=0 ; i<man ; ++i)
1190  mantissa.table[i] = man_result.table[i];
1191  }
1192 
1193  c += Standardizing();
1194 
1195  return CheckCarry(c);
1196  }
1197 
1198 
1205  {
1206  if( IsNan() )
1207  return 1;
1208 
1209  if( ss2 == 0 )
1210  {
1211  SetZero();
1212  return 0;
1213  }
1214 
1215  if( IsZero() )
1216  return 0;
1217 
1218  if( IsSign() == (ss2<0) )
1219  {
1220  // the signs are the same (both are either - or +), the result is positive
1221  Abs();
1222  }
1223  else
1224  {
1225  // the signs are different, the result is negative
1226  SetSign();
1227  }
1228 
1229  if( ss2<0 )
1230  ss2 = -ss2;
1231 
1232 
1233  return MulUInt( uint(ss2) );
1234  }
1235 
1236 
1237 private:
1238 
1239 
1251  bool CheckGreaterOrEqualHalf(uint * tab, uint len)
1252  {
1253  uint i;
1254 
1255  TTMATH_ASSERT( len>0 && (tab[len-1] & TTMATH_UINT_HIGHEST_BIT)!=0 )
1256 
1257  for(i=0 ; i<len-1 ; ++i)
1258  if( tab[i] != 0 )
1259  return false;
1260 
1261  if( tab[i] != TTMATH_UINT_HIGHEST_BIT )
1262  return false;
1263 
1264  return true;
1265  }
1266 
1267 
1268 private:
1269 
1274  uint MulRef(const Big<exp, man> & ss2, bool round = true)
1275  {
1277 
1278  UInt<man*2> man_result;
1279  uint c = 0;
1280  uint i;
1281 
1282  if( IsNan() || ss2.IsNan() )
1283  return CheckCarry(1);
1284 
1285  if( IsZero() )
1286  return 0;
1287 
1288  if( ss2.IsZero() )
1289  {
1290  SetZero();
1291  return 0;
1292  }
1293 
1294  // man_result = mantissa * ss2.mantissa
1295  mantissa.MulBig(ss2.mantissa, man_result);
1296 
1297  // 'i' will be from 0 to man*TTMATH_BITS_PER_UINT
1298  // because mantissa and ss2.mantissa are standardized
1299  // (the highest bit in man_result is set to 1 or
1300  // if there is a zero value in man_result the method CompensationToLeft()
1301  // returns 0 but we'll correct this at the end in Standardizing() method)
1302  i = man_result.CompensationToLeft();
1303  uint exp_add = man * TTMATH_BITS_PER_UINT - i;
1304 
1305  if( exp_add )
1306  c += exponent.Add( exp_add );
1307 
1308  c += exponent.Add( ss2.exponent );
1309 
1310  for(i=0 ; i<man ; ++i)
1311  mantissa.table[i] = man_result.table[i+man];
1312 
1313  if( round && (man_result.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
1314  {
1315  bool is_half = CheckGreaterOrEqualHalf(man_result.table, man);
1316  c += RoundHalfToEven(is_half);
1317  }
1318 
1319  if( IsSign() == ss2.IsSign() )
1320  {
1321  // the signs are the same, the result is positive
1322  Abs();
1323  }
1324  else
1325  {
1326  // the signs are different, the result is negative
1327  // if the value is zero it will be corrected later in Standardizing method
1328  SetSign();
1329  }
1330 
1331  c += Standardizing();
1332 
1333  return CheckCarry(c);
1334  }
1335 
1336 
1337 public:
1338 
1339 
1344  uint Mul(const Big<exp, man> & ss2, bool round = true)
1345  {
1346  if( this == &ss2 )
1347  {
1348  Big<exp, man> copy_ss2(ss2);
1349  return MulRef(copy_ss2, round);
1350  }
1351  else
1352  {
1353  return MulRef(ss2, round);
1354  }
1355  }
1356 
1357 
1358 private:
1359 
1368  uint DivRef(const Big<exp, man> & ss2, bool round = true)
1369  {
1371 
1372  UInt<man*2> man1;
1373  UInt<man*2> man2;
1374  uint i,c = 0;
1375 
1376  if( IsNan() || ss2.IsNan() )
1377  return CheckCarry(1);
1378 
1379  if( ss2.IsZero() )
1380  {
1381  SetNan();
1382  return 2;
1383  }
1384 
1385  if( IsZero() )
1386  return 0;
1387 
1388  // !! this two loops can be joined together
1389 
1390  for(i=0 ; i<man ; ++i)
1391  {
1392  man1.table[i+man] = mantissa.table[i];
1393  man2.table[i] = ss2.mantissa.table[i];
1394  }
1395 
1396  for(i=0 ; i<man ; ++i)
1397  {
1398  man1.table[i] = 0;
1399  man2.table[i+man] = 0;
1400  }
1401 
1402  man1.Div(man2);
1403 
1404  i = man1.CompensationToLeft();
1405 
1406  if( i )
1407  c += exponent.Sub(i);
1408 
1409  c += exponent.Sub(ss2.exponent);
1410 
1411  for(i=0 ; i<man ; ++i)
1412  mantissa.table[i] = man1.table[i+man];
1413 
1414  if( round && (man1.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
1415  {
1416  bool is_half = CheckGreaterOrEqualHalf(man1.table, man);
1417  c += RoundHalfToEven(is_half);
1418  }
1419 
1420  if( IsSign() == ss2.IsSign() )
1421  Abs();
1422  else
1423  SetSign(); // if there is a zero it will be corrected in Standardizing()
1424 
1425  c += Standardizing();
1426 
1427  return CheckCarry(c);
1428  }
1429 
1430 
1431 public:
1432 
1441  uint Div(const Big<exp, man> & ss2, bool round = true)
1442  {
1443  if( this == &ss2 )
1444  {
1445  Big<exp, man> copy_ss2(ss2);
1446  return DivRef(copy_ss2, round);
1447  }
1448  else
1449  {
1450  return DivRef(ss2, round);
1451  }
1452  }
1453 
1454 
1455 private:
1456 
1460  uint ModRef(const Big<exp, man> & ss2)
1461  {
1463 
1464  uint c = 0;
1465 
1466  if( IsNan() || ss2.IsNan() )
1467  return CheckCarry(1);
1468 
1469  if( ss2.IsZero() )
1470  {
1471  SetNan();
1472  return 2;
1473  }
1474 
1475  if( !SmallerWithoutSignThan(ss2) )
1476  {
1477  Big<exp, man> temp(*this);
1478 
1479  c = temp.Div(ss2);
1480  temp.SkipFraction();
1481  c += temp.Mul(ss2);
1482  c += Sub(temp);
1483 
1484  if( !SmallerWithoutSignThan( ss2 ) )
1485  c += 1;
1486  }
1487 
1488  return CheckCarry(c);
1489  }
1490 
1491 
1492 public:
1493 
1511  uint Mod(const Big<exp, man> & ss2)
1512  {
1513  if( this == &ss2 )
1514  {
1515  Big<exp, man> copy_ss2(ss2);
1516  return ModRef(copy_ss2);
1517  }
1518  else
1519  {
1520  return ModRef(ss2);
1521  }
1522  }
1523 
1524 
1531  uint Mod2() const
1532  {
1533  if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
1534  return 0;
1535 
1536  sint exp_int = exponent.ToInt();
1537  // 'exp_int' is negative (or zero), we set it as positive
1538  exp_int = -exp_int;
1539 
1540  return mantissa.GetBit(exp_int);
1541  }
1542 
1543 
1555  template<uint pow_size>
1557  {
1558  if( IsNan() )
1559  return 1;
1560 
1561  if( IsZero() )
1562  {
1563  if( pow.IsZero() )
1564  {
1565  // we don't define zero^zero
1566  SetNan();
1567  return 2;
1568  }
1569 
1570  // 0^(+something) is zero
1571  return 0;
1572  }
1573 
1574  Big<exp, man> start(*this);
1575  Big<exp, man> result;
1576  result.SetOne();
1577  uint c = 0;
1578 
1579  while( !c )
1580  {
1581  if( pow.table[0] & 1 )
1582  c += result.Mul(start);
1583 
1584  pow.Rcr(1);
1585 
1586  if( pow.IsZero() )
1587  break;
1588 
1589  c += start.Mul(start);
1590  }
1591 
1592  *this = result;
1593 
1594  return CheckCarry(c);
1595  }
1596 
1597 
1607  template<uint pow_size>
1609  {
1610  if( IsNan() )
1611  return 1;
1612 
1613  if( !pow.IsSign() )
1614  return Pow( UInt<pow_size>(pow) );
1615 
1616  if( IsZero() )
1617  {
1618  // if 'p' is negative then
1619  // 'this' must be different from zero
1620  SetNan();
1621  return 2;
1622  }
1623 
1624  uint c = pow.ChangeSign();
1625 
1626  Big<exp, man> t(*this);
1627  c += t.Pow( UInt<pow_size>(pow) ); // here can only be a carry (return:1)
1628 
1629  SetOne();
1630  c += Div(t);
1631 
1632  return CheckCarry(c);
1633  }
1634 
1635 
1648  {
1649  if( IsNan() || pow.IsNan() )
1650  return CheckCarry(1);
1651 
1652  if( IsZero() )
1653  {
1654  if( pow.IsZero() )
1655  {
1656  SetNan();
1657  return 2;
1658  }
1659 
1660  // 0^(+something) is zero
1661  return 0;
1662  }
1663 
1664  if( pow.IsSign() )
1665  pow.Abs();
1666 
1667  Big<exp, man> start(*this);
1668  Big<exp, man> result;
1669  Big<exp, man> one;
1670  uint c = 0;
1671  one.SetOne();
1672  result = one;
1673 
1674  while( !c )
1675  {
1676  if( pow.Mod2() )
1677  c += result.Mul(start);
1678 
1679  c += pow.exponent.SubOne();
1680 
1681  if( pow < one )
1682  break;
1683 
1684  c += start.Mul(start);
1685  }
1686 
1687  *this = result;
1688 
1689  return CheckCarry(c);
1690  }
1691 
1692 
1704  {
1705  if( IsNan() || pow.IsNan() )
1706  return CheckCarry(1);
1707 
1708  if( !pow.IsSign() )
1709  return PowUInt(pow);
1710 
1711  if( IsZero() )
1712  {
1713  // if 'pow' is negative then
1714  // 'this' must be different from zero
1715  SetNan();
1716  return 2;
1717  }
1718 
1719  Big<exp, man> temp(*this);
1720  uint c = temp.PowUInt(pow); // here can only be a carry (result:1)
1721 
1722  SetOne();
1723  c += Div(temp);
1724 
1725  return CheckCarry(c);
1726  }
1727 
1728 
1740  {
1741  if( IsNan() || pow.IsNan() )
1742  return CheckCarry(1);
1743 
1744  Big<exp, man> temp;
1745  uint c = temp.Ln(*this);
1746 
1747  if( c != 0 ) // can be 2 from Ln()
1748  {
1749  SetNan();
1750  return c;
1751  }
1752 
1753  c += temp.Mul(pow);
1754  c += Exp(temp);
1755 
1756  return CheckCarry(c);
1757  }
1758 
1759 
1769  uint Pow(const Big<exp, man> & pow)
1770  {
1771  if( IsNan() || pow.IsNan() )
1772  return CheckCarry(1);
1773 
1774  if( IsZero() )
1775  {
1776  // 0^pow will be 0 only for pow>0
1777  if( pow.IsSign() || pow.IsZero() )
1778  {
1779  SetNan();
1780  return 2;
1781  }
1782 
1783  SetZero();
1784 
1785  return 0;
1786  }
1787 
1788  if( pow.exponent>-sint(man*TTMATH_BITS_PER_UINT) && pow.exponent<=0 )
1789  {
1790  if( pow.IsInteger() )
1791  return PowInt( pow );
1792  }
1793 
1794  return PowFrac(pow);
1795  }
1796 
1797 
1807  {
1808  if( IsNan() || IsSign() )
1809  {
1810  SetNan();
1811  return 2;
1812  }
1813 
1814  if( IsZero() )
1815  return 0;
1816 
1817  Big<exp, man> old(*this);
1818  Big<exp, man> ln;
1819  uint c = 0;
1820 
1821  // we're using the formula: sqrt(x) = e ^ (ln(x) / 2)
1822  c += ln.Ln(*this);
1823  c += ln.exponent.SubOne(); // ln = ln / 2
1824  c += Exp(ln);
1825 
1826  // above formula doesn't give accurate results for some integers
1827  // e.g. Sqrt(81) would not be 9 but a value very closed to 9
1828  // we're rounding the result, calculating result*result and comparing
1829  // with the old value, if they are equal then the result is an integer too
1830 
1831  if( !c && old.IsInteger() && !IsInteger() )
1832  {
1833  Big<exp, man> temp(*this);
1834  c += temp.Round();
1835 
1836  Big<exp, man> temp2(temp);
1837  c += temp.Mul(temp2);
1838 
1839  if( temp == old )
1840  *this = temp2;
1841  }
1842 
1843  return CheckCarry(c);
1844  }
1845 
1846 
1847 private:
1848 
1849 #ifdef TTMATH_CONSTANTSGENERATOR
1850 public:
1851 #endif
1852 
1858  void ExpSurrounding0(const Big<exp,man> & x, uint * steps = 0)
1859  {
1861 
1862  Big<exp,man> denominator, denominator_i;
1863  Big<exp,man> one, old_value, next_part;
1864  Big<exp,man> numerator = x;
1865 
1866  SetOne();
1867  one.SetOne();
1868  denominator.SetOne();
1869  denominator_i.SetOne();
1870 
1871  uint i;
1872  old_value = *this;
1873 
1874  // we begin from 1 in order to not test at the beginning
1875  #ifdef TTMATH_CONSTANTSGENERATOR
1876  for(i=1 ; true ; ++i)
1877  #else
1878  for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
1879  #endif
1880  {
1881  bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
1882 
1883  next_part = numerator;
1884 
1885  if( next_part.Div( denominator ) )
1886  // if there is a carry here we only break the loop
1887  // however the result we return as good
1888  // it means there are too many parts of the formula
1889  break;
1890 
1891  // there shouldn't be a carry here
1892  Add( next_part );
1893 
1894  if( testing )
1895  {
1896  if( old_value == *this )
1897  // we've added next few parts of the formula but the result
1898  // is still the same then we break the loop
1899  break;
1900  else
1901  old_value = *this;
1902  }
1903 
1904  // we set the denominator and the numerator for a next part of the formula
1905  if( denominator_i.Add(one) )
1906  // if there is a carry here the result we return as good
1907  break;
1908 
1909  if( denominator.Mul(denominator_i) )
1910  break;
1911 
1912  if( numerator.Mul(x) )
1913  break;
1914  }
1915 
1916  if( steps )
1917  *steps = i;
1918  }
1919 
1920 public:
1921 
1922 
1934  uint Exp(const Big<exp,man> & x)
1935  {
1936  uint c = 0;
1937 
1938  if( x.IsNan() )
1939  return CheckCarry(1);
1940 
1941  if( x.IsZero() )
1942  {
1943  SetOne();
1944  return 0;
1945  }
1946 
1947  // m will be the value of the mantissa in range (-1,1)
1948  Big<exp,man> m(x);
1950 
1951  // 'e_' will be the value of '2^exponent'
1952  // e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT; and
1953  // e_.exponent.Add(1) mean:
1954  // e_.mantissa.table[0] = 1;
1955  // e_.Standardizing();
1956  // e_.exponent.Add(man*TTMATH_BITS_PER_UINT)
1957  // (we must add 'man*TTMATH_BITS_PER_UINT' because we've taken it from the mantissa)
1958  Big<exp,man> e_(x);
1959  e_.mantissa.SetZero();
1961  c += e_.exponent.Add(1);
1962  e_.Abs();
1963 
1964  /*
1965  now we've got:
1966  m - the value of the mantissa in range (-1,1)
1967  e_ - 2^exponent
1968 
1969  e_ can be as:
1970  ...2^-2, 2^-1, 2^0, 2^1, 2^2 ...
1971  ...1/4 , 1/2 , 1 , 2 , 4 ...
1972 
1973  above one e_ is integer
1974 
1975  if e_ is greater than 1 we calculate the exponent as:
1976  e^(m * e_) = ExpSurrounding0(m) ^ e_
1977  and if e_ is smaller or equal one we calculate the exponent in this way:
1978  e^(m * e_) = ExpSurrounding0(m* e_)
1979  because if e_ is smaller or equal 1 then the product of m*e_ is smaller or equal m
1980  */
1981 
1982  if( e_ <= 1 )
1983  {
1984  m.Mul(e_);
1985  ExpSurrounding0(m);
1986  }
1987  else
1988  {
1989  ExpSurrounding0(m);
1990  c += PowUInt(e_);
1991  }
1992 
1993  return CheckCarry(c);
1994  }
1995 
1996 
1997 
1998 
1999 private:
2000 
2001 #ifdef TTMATH_CONSTANTSGENERATOR
2002 public:
2003 #endif
2004 
2011  void LnSurrounding1(const Big<exp,man> & x, uint * steps = 0)
2012  {
2013  Big<exp,man> old_value, next_part, denominator, one, two, x1(x), x2(x);
2014 
2015  one.SetOne();
2016 
2017  if( x == one )
2018  {
2019  // LnSurrounding1(1) is 0
2020  SetZero();
2021  return;
2022  }
2023 
2024  two = 2;
2025 
2026  x1.Sub(one);
2027  x2.Add(one);
2028 
2029  x1.Div(x2);
2030  x2 = x1;
2031  x2.Mul(x1);
2032 
2033  denominator.SetOne();
2034  SetZero();
2035 
2036  old_value = *this;
2037  uint i;
2038 
2039 
2040  #ifdef TTMATH_CONSTANTSGENERATOR
2041  for(i=1 ; true ; ++i)
2042  #else
2043  // we begin from 1 in order to not test at the beginning
2044  for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
2045  #endif
2046  {
2047  bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
2048 
2049  next_part = x1;
2050 
2051  if( next_part.Div(denominator) )
2052  // if there is a carry here we only break the loop
2053  // however the result we return as good
2054  // it means there are too many parts of the formula
2055  break;
2056 
2057  // there shouldn't be a carry here
2058  Add(next_part);
2059 
2060  if( testing )
2061  {
2062  if( old_value == *this )
2063  // we've added next (step_test) parts of the formula but the result
2064  // is still the same then we break the loop
2065  break;
2066  else
2067  old_value = *this;
2068  }
2069 
2070  if( x1.Mul(x2) )
2071  // if there is a carry here the result we return as good
2072  break;
2073 
2074  if( denominator.Add(two) )
2075  break;
2076  }
2077 
2078  // this = this * 2
2079  // ( there can't be a carry here because we calculate the logarithm between <1,2) )
2080  exponent.AddOne();
2081 
2082  if( steps )
2083  *steps = i;
2084  }
2085 
2086 
2087 
2088 
2089 public:
2090 
2091 
2109  uint Ln(const Big<exp,man> & x)
2110  {
2111  if( x.IsNan() )
2112  return CheckCarry(1);
2113 
2114  if( x.IsSign() || x.IsZero() )
2115  {
2116  SetNan();
2117  return 2;
2118  }
2119 
2120  Big<exp,man> exponent_temp;
2121  exponent_temp.FromInt( x.exponent );
2122 
2123  // m will be the value of the mantissa in range <1,2)
2124  Big<exp,man> m(x);
2125  m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1);
2126 
2127  // we must add 'man*TTMATH_BITS_PER_UINT-1' because we've taken it from the mantissa
2128  uint c = exponent_temp.Add(man*TTMATH_BITS_PER_UINT-1);
2129 
2130  LnSurrounding1(m);
2131 
2132  Big<exp,man> ln2;
2133  ln2.SetLn2();
2134  c += exponent_temp.Mul(ln2);
2135  c += Add(exponent_temp);
2136 
2137  return CheckCarry(c);
2138  }
2139 
2140 
2153  uint Log(const Big<exp,man> & x, const Big<exp,man> & base)
2154  {
2155  if( x.IsNan() || base.IsNan() )
2156  return CheckCarry(1);
2157 
2158  if( x.IsSign() || x.IsZero() )
2159  {
2160  SetNan();
2161  return 2;
2162  }
2163 
2164  Big<exp,man> denominator;;
2165  denominator.SetOne();
2166 
2167  if( base.IsSign() || base.IsZero() || base==denominator )
2168  {
2169  SetNan();
2170  return 3;
2171  }
2172 
2173  if( x == denominator ) // (this is: if x == 1)
2174  {
2175  // log(1) is 0
2176  SetZero();
2177  return 0;
2178  }
2179 
2180  // another error values we've tested at the beginning
2181  // there can only be a carry
2182  uint c = Ln(x);
2183 
2184  c += denominator.Ln(base);
2185  c += Div(denominator);
2186 
2187  return CheckCarry(c);
2188  }
2189 
2190 
2191 
2192 
2203  template<uint another_exp, uint another_man>
2205  {
2206  info = another.info;
2207 
2208  if( IsNan() )
2209  return 1;
2210 
2211  if( exponent.FromInt(another.exponent) )
2212  {
2213  SetNan();
2214  return 1;
2215  }
2216 
2217  uint man_len_min = (man < another_man)? man : another_man;
2218  uint i;
2219  uint c = 0;
2220 
2221  for( i = 0 ; i<man_len_min ; ++i )
2222  mantissa.table[man-1-i] = another.mantissa.table[another_man-1-i];
2223 
2224  for( ; i<man ; ++i )
2225  mantissa.table[man-1-i] = 0;
2226 
2227 
2228  // MS Visual Express 2005 reports a warning (in the lines with 'uint man_diff = ...'):
2229  // warning C4307: '*' : integral constant overflow
2230  // but we're using 'if( man > another_man )' and 'if( man < another_man )' and there'll be no such situation here
2231  #ifdef _MSC_VER
2232  #pragma warning( disable: 4307 )
2233  #endif
2234 
2235  if( man > another_man )
2236  {
2237  uint man_diff = (man - another_man) * TTMATH_BITS_PER_UINT;
2238  c += exponent.SubInt(man_diff, 0);
2239  }
2240  else
2241  if( man < another_man )
2242  {
2243  uint man_diff = (another_man - man) * TTMATH_BITS_PER_UINT;
2244  c += exponent.AddInt(man_diff, 0);
2245  }
2246 
2247  #ifdef _MSC_VER
2248  #pragma warning( default: 4307 )
2249  #endif
2250 
2251  // mantissa doesn't have to be standardized (either the highest bit is set or all bits are equal zero)
2252  CorrectZero();
2253 
2254  return CheckCarry(c);
2255  }
2256 
2257 
2258 private:
2259 
2264  uint ToUIntOrInt(uint & result) const
2265  {
2266  result = 0;
2267 
2268  if( IsZero() )
2269  return 0;
2270 
2271  sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
2272 
2273  if( exponent > maxbit + sint(TTMATH_BITS_PER_UINT) )
2274  // if exponent > (maxbit + sint(TTMATH_BITS_PER_UINT)) the value can't be passed
2275  // into the 'sint' type (it's too big)
2276  return 1;
2277 
2278  if( exponent <= maxbit )
2279  // our value is from the range of (-1,1) and we return zero
2280  return 0;
2281 
2282  // exponent is from a range of (maxbit, maxbit + sint(TTMATH_BITS_PER_UINT) >
2283  // and [maxbit + sint(TTMATH_BITS_PER_UINT] <= 0
2284  sint how_many_bits = exponent.ToInt();
2285 
2286  // how_many_bits is negative, we'll make it positive
2287  how_many_bits = -how_many_bits;
2288 
2289  result = (mantissa.table[man-1] >> (how_many_bits % TTMATH_BITS_PER_UINT));
2290 
2291  return 0;
2292  }
2293 
2294 
2295 public:
2296 
2300  uint ToUInt() const
2301  {
2302  uint result;
2303 
2304  ToUInt(result);
2305 
2306  return result;
2307  }
2308 
2309 
2315  uint ToUInt(uint & result) const
2316  {
2317  if( ToUIntOrInt(result) )
2318  return 1;
2319 
2320  if( IsSign() )
2321  return 1;
2322 
2323  return 0;
2324  }
2325 
2326 
2330  sint ToInt() const
2331  {
2332  sint result;
2333 
2334  ToInt(result);
2335 
2336  return result;
2337  }
2338 
2339 
2345  uint ToInt(uint & result) const
2346  {
2347  return ToUInt(result);
2348  }
2349 
2350 
2356  uint ToInt(sint & result) const
2357  {
2358  uint result_uint;
2359 
2360  uint c = ToUIntOrInt(result_uint);
2361  result = sint(result_uint);
2362 
2363  if( c )
2364  return 1;
2365 
2366  uint mask = 0;
2367 
2368  if( IsSign() )
2369  {
2370  mask = TTMATH_UINT_MAX_VALUE;
2371  result = -result;
2372  }
2373 
2374  return ((result & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
2375  }
2376 
2377 
2378 private:
2379 
2385  template<uint int_size>
2386  uint ToUIntOrInt(UInt<int_size> & result) const
2387  {
2388  result.SetZero();
2389 
2390  if( IsZero() )
2391  return 0;
2392 
2393  sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
2394 
2395  if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )
2396  // if exponent > (maxbit + sint(int_size*TTMATH_BITS_PER_UINT)) the value can't be passed
2397  // into the 'UInt<int_size>' type (it's too big)
2398  return 1;
2399 
2400  if( exponent <= maxbit )
2401  // our value is from range (-1,1) and we return zero
2402  return 0;
2403 
2404  sint how_many_bits = exponent.ToInt();
2405 
2406  if( how_many_bits < 0 )
2407  {
2408  how_many_bits = -how_many_bits;
2409  uint index = how_many_bits / TTMATH_BITS_PER_UINT;
2410 
2411  UInt<man> mantissa_temp(mantissa);
2412  mantissa_temp.Rcr( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
2413 
2414  for(uint i=index, a=0 ; i<man ; ++i,++a)
2415  result.table[a] = mantissa_temp.table[i];
2416  }
2417  else
2418  {
2419  uint index = how_many_bits / TTMATH_BITS_PER_UINT;
2420 
2421  if( index + (man-1) < int_size )
2422  {
2423  // above 'if' is always true
2424  // this is only to get rid of a warning "warning: array subscript is above array bounds"
2425  // (from gcc)
2426  // we checked the condition there: "if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )"
2427  // but gcc doesn't understand our types - exponent is Int<>
2428 
2429  for(uint i=0 ; i<man ; ++i)
2430  result.table[index+i] = mantissa.table[i];
2431  }
2432 
2433  result.Rcl( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
2434  }
2435 
2436  return 0;
2437  }
2438 
2439 
2440 public:
2441 
2447  template<uint int_size>
2448  uint ToUInt(UInt<int_size> & result) const
2449  {
2450  uint c = ToUIntOrInt(result);
2451 
2452  if( c )
2453  return 1;
2454 
2455  if( IsSign() )
2456  return 1;
2457 
2458  return 0;
2459  }
2460 
2461 
2467  template<uint int_size>
2468  uint ToInt(UInt<int_size> & result) const
2469  {
2470  return ToUInt(result);
2471  }
2472 
2473 
2479  template<uint int_size>
2480  uint ToInt(Int<int_size> & result) const
2481  {
2482  uint c = ToUIntOrInt(result);
2483 
2484  if( c )
2485  return 1;
2486 
2487  uint mask = 0;
2488 
2489  if( IsSign() )
2490  {
2491  result.ChangeSign();
2492  mask = TTMATH_UINT_MAX_VALUE;
2493  }
2494 
2495  return ((result.table[int_size-1] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT))? 0 : 1;
2496  }
2497 
2498 
2503  {
2504  if( value == 0 )
2505  {
2506  SetZero();
2507  return 0;
2508  }
2509 
2510  info = 0;
2511 
2512  for(uint i=0 ; i<man-1 ; ++i)
2513  mantissa.table[i] = 0;
2514 
2515  mantissa.table[man-1] = value;
2516  exponent = -sint(man-1) * sint(TTMATH_BITS_PER_UINT);
2517 
2518  // there shouldn't be a carry because 'value' has the 'uint' type
2519  Standardizing();
2520 
2521  return 0;
2522  }
2523 
2524 
2529  {
2530  return FromUInt(value);
2531  }
2532 
2533 
2538  {
2539  bool is_sign = false;
2540 
2541  if( value < 0 )
2542  {
2543  value = -value;
2544  is_sign = true;
2545  }
2546 
2547  FromUInt(uint(value));
2548 
2549  if( is_sign )
2550  SetSign();
2551 
2552  return 0;
2553  }
2554 
2555 
2556 
2585 #ifdef TTMATH_PLATFORM32
2586 
2587  uint FromDouble(double value)
2588  {
2589  // I am not sure what will be on a platform which has
2590  // a different endianness... but we use this library only
2591  // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
2592  union
2593  {
2594  double d;
2595  uint u[2]; // two 32bit words
2596  } temp;
2597 
2598  temp.d = value;
2599 
2600  sint e = ( temp.u[1] & 0x7FF00000u) >> 20;
2601  uint m1 = ((temp.u[1] & 0xFFFFFu) << 11) | (temp.u[0] >> 21);
2602  uint m2 = temp.u[0] << 11;
2603 
2604  if( e == 2047 )
2605  {
2606  // If E=2047 and F is nonzero, then V=NaN ("Not a number")
2607  // If E=2047 and F is zero and S is 1, then V=-Infinity
2608  // If E=2047 and F is zero and S is 0, then V=Infinity
2609 
2610  // we do not support -Infinity and +Infinity
2611  // we assume that there is always NaN
2612 
2613  SetNan();
2614  }
2615  else
2616  if( e > 0 )
2617  {
2618  // If 0<E<2047 then
2619  // V=(-1)**S * 2 ** (E-1023) * (1.F)
2620  // where "1.F" is intended to represent the binary number
2621  // created by prefixing F with an implicit leading 1 and a binary point.
2622 
2623  FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
2624  e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
2625  m1, m2);
2626 
2627  // we do not have to call Standardizing() here
2628  // because the mantissa will have the highest bit set
2629  }
2630  else
2631  {
2632  // e == 0
2633 
2634  if( m1 != 0 || m2 != 0 )
2635  {
2636  // If E=0 and F is nonzero,
2637  // then V=(-1)**S * 2 ** (-1022) * (0.F)
2638  // These are "unnormalized" values.
2639 
2640  UInt<2> m;
2641  m.table[1] = m1;
2642  m.table[0] = m2;
2643  uint moved = m.CompensationToLeft();
2644 
2645  FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
2646  e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
2647  m.table[1], m.table[0]);
2648  }
2649  else
2650  {
2651  // If E=0 and F is zero and S is 1, then V=-0
2652  // If E=0 and F is zero and S is 0, then V=0
2653 
2654  // we do not support -0 or 0, only is one 0
2655  SetZero();
2656  }
2657  }
2658 
2659  return 0; // never be a carry
2660  }
2661 
2662 
2663 private:
2664 
2665  void FromDouble_SetExpAndMan(bool is_sign, int e, uint mhighest, uint m1, uint m2)
2666  {
2667  exponent = e;
2668 
2669  if( man > 1 )
2670  {
2671  mantissa.table[man-1] = m1 | mhighest;
2672  mantissa.table[sint(man-2)] = m2;
2673  // although man>1 we're using casting into sint
2674  // to get rid from a warning which generates Microsoft Visual:
2675  // warning C4307: '*' : integral constant overflow
2676 
2677  for(uint i=0 ; i<man-2 ; ++i)
2678  mantissa.table[i] = 0;
2679  }
2680  else
2681  {
2682  mantissa.table[0] = m1 | mhighest;
2683  }
2684 
2685  info = 0;
2686 
2687  // the value should be different from zero
2688  TTMATH_ASSERT( mantissa.IsZero() == false )
2689 
2690  if( is_sign )
2691  SetSign();
2692  }
2693 
2694 
2695 #else
2696 
2697 public:
2698 
2699  // 64bit platforms
2700  uint FromDouble(double value)
2701  {
2702  // I am not sure what will be on a plaltform which has
2703  // a different endianness... but we use this library only
2704  // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
2705  union
2706  {
2707  double d;
2708  uint u; // one 64bit word
2709  } temp;
2710 
2711  temp.d = value;
2712 
2713  sint e = (temp.u & 0x7FF0000000000000ul) >> 52;
2714  uint m = (temp.u & 0xFFFFFFFFFFFFFul) << 11;
2715 
2716  if( e == 2047 )
2717  {
2718  // If E=2047 and F is nonzero, then V=NaN ("Not a number")
2719  // If E=2047 and F is zero and S is 1, then V=-Infinity
2720  // If E=2047 and F is zero and S is 0, then V=Infinity
2721 
2722  // we do not support -Infinity and +Infinity
2723  // we assume that there is always NaN
2724 
2725  SetNan();
2726  }
2727  else
2728  if( e > 0 )
2729  {
2730  // If 0<E<2047 then
2731  // V=(-1)**S * 2 ** (E-1023) * (1.F)
2732  // where "1.F" is intended to represent the binary number
2733  // created by prefixing F with an implicit leading 1 and a binary point.
2734 
2735  FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
2736  e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
2737  0x8000000000000000ul, m);
2738 
2739  // we do not have to call Standardizing() here
2740  // because the mantissa will have the highest bit set
2741  }
2742  else
2743  {
2744  // e == 0
2745 
2746  if( m != 0 )
2747  {
2748  // If E=0 and F is nonzero,
2749  // then V=(-1)**S * 2 ** (-1022) * (0.F)
2750  // These are "unnormalized" values.
2751 
2752  FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
2753  e - 1022 - man*TTMATH_BITS_PER_UINT + 1, 0, m);
2754  Standardizing();
2755  }
2756  else
2757  {
2758  // If E=0 and F is zero and S is 1, then V=-0
2759  // If E=0 and F is zero and S is 0, then V=0
2760 
2761  // we do not support -0 or 0, only is one 0
2762  SetZero();
2763  }
2764  }
2765 
2766  return 0; // never be a carry
2767  }
2768 
2769 private:
2770 
2771  void FromDouble_SetExpAndMan(bool is_sign, sint e, uint mhighest, uint m)
2772  {
2773  exponent = e;
2774  mantissa.table[man-1] = m | mhighest;
2775 
2776  for(uint i=0 ; i<man-1 ; ++i)
2777  mantissa.table[i] = 0;
2778 
2779  info = 0;
2780 
2781  // the value should be different from zero
2782  TTMATH_ASSERT( mantissa.IsZero() == false )
2783 
2784  if( is_sign )
2785  SetSign();
2786  }
2787 
2788 #endif
2789 
2790 
2791 public:
2792 
2793 
2797  uint FromFloat(float value)
2798  {
2799  return FromDouble(double(value));
2800  }
2801 
2802 
2811  double ToDouble() const
2812  {
2813  double result;
2814 
2815  ToDouble(result);
2816 
2817  return result;
2818  }
2819 
2820 
2821 private:
2822 
2823 
2849  bool IsInf(float value) const
2850  {
2851  // need testing on a 64 bit machine
2852 
2853  union
2854  {
2855  float d;
2856  uint u;
2857  } temp;
2858 
2859  temp.d = value;
2860 
2861  if( ((temp.u >> 23) & 0xff) == 0xff )
2862  {
2863  if( (temp.u & 0x7FFFFF) == 0 )
2864  return true; // +/- infinity
2865  }
2866 
2867  return false;
2868  }
2869 
2870 
2871 public:
2872 
2881  float ToFloat() const
2882  {
2883  float result;
2884 
2885  ToFloat(result);
2886 
2887  return result;
2888  }
2889 
2890 
2901  uint ToFloat(float & result) const
2902  {
2903  double result_double;
2904 
2905  uint c = ToDouble(result_double);
2906  result = float(result_double);
2907 
2908  if( result == -0.0f )
2909  result = 0.0f;
2910 
2911  if( c )
2912  return 1;
2913 
2914  // although the result_double can have a correct value
2915  // but after converting to float there can be infinity
2916 
2917  if( IsInf(result) )
2918  return 1;
2919 
2920  if( result == 0.0f && result_double != 0.0 )
2921  // result_double was too small for float
2922  return 1;
2923 
2924  return 0;
2925  }
2926 
2927 
2938  uint ToDouble(double & result) const
2939  {
2940  if( IsZero() )
2941  {
2942  result = 0.0;
2943  return 0;
2944  }
2945 
2946  if( IsNan() )
2947  {
2948  result = ToDouble_SetDouble( false, 2047, 0, false, true);
2949 
2950  return 0;
2951  }
2952 
2953  sint e_correction = sint(man*TTMATH_BITS_PER_UINT) - 1;
2954 
2955  if( exponent >= 1024 - e_correction )
2956  {
2957  // +/- infinity
2958  result = ToDouble_SetDouble( IsSign(), 2047, 0, true);
2959 
2960  return 1;
2961  }
2962  else
2963  if( exponent <= -1023 - 52 - e_correction )
2964  {
2965  // too small value - we assume that there'll be a zero
2966  result = 0;
2967 
2968  // and return a carry
2969  return 1;
2970  }
2971 
2972  sint e = exponent.ToInt() + e_correction;
2973 
2974  if( e <= -1023 )
2975  {
2976  // -1023-52 < e <= -1023 (unnormalized value)
2977  result = ToDouble_SetDouble( IsSign(), 0, -(e + 1023));
2978  }
2979  else
2980  {
2981  // -1023 < e < 1024
2982  result = ToDouble_SetDouble( IsSign(), e + 1023, -1);
2983  }
2984 
2985  return 0;
2986  }
2987 
2988 private:
2989 
2990 #ifdef TTMATH_PLATFORM32
2991 
2992  // 32bit platforms
2993  double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
2994  {
2995  union
2996  {
2997  double d;
2998  uint u[2]; // two 32bit words
2999  } temp;
3000 
3001  temp.u[0] = temp.u[1] = 0;
3002 
3003  if( is_sign )
3004  temp.u[1] |= 0x80000000u;
3005 
3006  temp.u[1] |= (e << 20) & 0x7FF00000u;
3007 
3008  if( nan )
3009  {
3010  temp.u[0] |= 1;
3011  return temp.d;
3012  }
3013 
3014  if( infinity )
3015  return temp.d;
3016 
3017  UInt<2> m;
3018  m.table[1] = mantissa.table[man-1];
3019  m.table[0] = ( man > 1 ) ? mantissa.table[sint(man-2)] : 0;
3020  // although man>1 we're using casting into sint
3021  // to get rid from a warning which generates Microsoft Visual:
3022  // warning C4307: '*' : integral constant overflow
3023 
3024  m.Rcr( 12 + move );
3025  m.table[1] &= 0xFFFFFu; // cutting the 20 bit (when 'move' was -1)
3026 
3027  temp.u[1] |= m.table[1];
3028  temp.u[0] |= m.table[0];
3029 
3030  return temp.d;
3031  }
3032 
3033 #else
3034 
3035  // 64bit platforms
3036  double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
3037  {
3038  union
3039  {
3040  double d;
3041  uint u; // 64bit word
3042  } temp;
3043 
3044  temp.u = 0;
3045 
3046  if( is_sign )
3047  temp.u |= 0x8000000000000000ul;
3048 
3049  temp.u |= (e << 52) & 0x7FF0000000000000ul;
3050 
3051  if( nan )
3052  {
3053  temp.u |= 1;
3054  return temp.d;
3055  }
3056 
3057  if( infinity )
3058  return temp.d;
3059 
3060  uint m = mantissa.table[man-1];
3061 
3062  m >>= ( 12 + move );
3063  m &= 0xFFFFFFFFFFFFFul; // cutting the 20 bit (when 'move' was -1)
3064  temp.u |= m;
3065 
3066  return temp.d;
3067  }
3068 
3069 #endif
3070 
3071 
3072 public:
3073 
3074 
3079  {
3080  FromInt(value);
3081 
3082  return *this;
3083  }
3084 
3085 
3090  {
3091  FromUInt(value);
3092 
3093  return *this;
3094  }
3095 
3096 
3100  Big<exp, man> & operator=(float value)
3101  {
3102  FromFloat(value);
3103 
3104  return *this;
3105  }
3106 
3107 
3111  Big<exp, man> & operator=(double value)
3112  {
3113  FromDouble(value);
3114 
3115  return *this;
3116  }
3117 
3118 
3122  Big(sint value)
3123  {
3124  FromInt(value);
3125  }
3126 
3130  Big(uint value)
3131  {
3132  FromUInt(value);
3133  }
3134 
3135 
3139  Big(double value)
3140  {
3141  FromDouble(value);
3142  }
3143 
3144 
3148  Big(float value)
3149  {
3150  FromFloat(value);
3151  }
3152 
3153 
3154 #ifdef TTMATH_PLATFORM32
3155 
3160  uint ToUInt(ulint & result) const
3161  {
3162  UInt<2> temp; // 64 bits container
3163 
3164  uint c = ToUInt(temp);
3165  temp.ToUInt(result);
3166 
3167  return c;
3168  }
3169 
3170 
3175  uint ToInt(ulint & result) const
3176  {
3177  return ToUInt(result);
3178  }
3179 
3180 
3185  uint ToInt(slint & result) const
3186  {
3187  Int<2> temp; // 64 bits container
3188 
3189  uint c = ToInt(temp);
3190  temp.ToInt(result);
3191 
3192  return c;
3193  }
3194 
3195 
3200  {
3201  if( value == 0 )
3202  {
3203  SetZero();
3204  return 0;
3205  }
3206 
3207  info = 0;
3208 
3209  if( man == 1 )
3210  {
3211  sint bit = mantissa.FindLeadingBitInWord(uint(value >> TTMATH_BITS_PER_UINT));
3212 
3213  if( bit != -1 )
3214  {
3215  // the highest word from value is different from zero
3216  bit += 1;
3217  value >>= bit;
3218  exponent = bit;
3219  }
3220  else
3221  {
3222  exponent.SetZero();
3223  }
3224 
3225  mantissa.table[0] = uint(value);
3226  }
3227  else
3228  {
3229  #ifdef _MSC_VER
3230  //warning C4307: '*' : integral constant overflow
3231  #pragma warning( disable: 4307 )
3232  #endif
3233 
3234  // man >= 2
3235  mantissa.table[man-1] = uint(value >> TTMATH_BITS_PER_UINT);
3236  mantissa.table[man-2] = uint(value);
3237 
3238  #ifdef _MSC_VER
3239  //warning C4307: '*' : integral constant overflow
3240  #pragma warning( default: 4307 )
3241  #endif
3242 
3243  exponent = -sint(man-2) * sint(TTMATH_BITS_PER_UINT);
3244 
3245  for(uint i=0 ; i<man-2 ; ++i)
3246  mantissa.table[i] = 0;
3247  }
3248 
3249  // there shouldn't be a carry because 'value' has the 'ulint' type
3250  // (we have sufficient exponent)
3251  Standardizing();
3252 
3253  return 0;
3254  }
3255 
3256 
3261  {
3262  return FromUInt(value);
3263  }
3264 
3265 
3270  {
3271  bool is_sign = false;
3272 
3273  if( value < 0 )
3274  {
3275  value = -value;
3276  is_sign = true;
3277  }
3278 
3279  FromUInt(ulint(value));
3280 
3281  if( is_sign )
3282  SetSign();
3283 
3284  return 0;
3285  }
3286 
3287 
3291  Big(ulint value)
3292  {
3293  FromUInt(value);
3294  }
3295 
3296 
3301  {
3302  FromUInt(value);
3303 
3304  return *this;
3305  }
3306 
3307 
3311  Big(slint value)
3312  {
3313  FromInt(value);
3314  }
3315 
3316 
3321  {
3322  FromInt(value);
3323 
3324  return *this;
3325  }
3326 
3327 #endif
3328 
3329 
3330 
3331 #ifdef TTMATH_PLATFORM64
3332 
3333 
3339  uint ToUInt(unsigned int & result) const
3340  {
3341  uint result_uint;
3342 
3343  uint c = ToUInt(result_uint);
3344  result = (unsigned int)result_uint;
3345 
3346  if( c || result_uint != uint(result) )
3347  return 1;
3348 
3349  return 0;
3350  }
3351 
3352 
3358  uint ToInt(unsigned int & result) const
3359  {
3360  return ToUInt(result);
3361  }
3362 
3363 
3369  uint ToInt(signed int & result) const
3370  {
3371  sint result_sint;
3372 
3373  uint c = ToInt(result_sint);
3374  result = (signed int)result_sint;
3375 
3376  if( c || result_sint != sint(result) )
3377  return 1;
3378 
3379  return 0;
3380  }
3381 
3382 
3383  /*
3384  this method converts 32 bit unsigned int to this class
3385  ***this method is created only on a 64bit platform***
3386  */
3387  uint FromUInt(unsigned int value)
3388  {
3389  return FromUInt(uint(value));
3390  }
3391 
3392 
3393  /*
3394  this method converts 32 bit unsigned int to this class
3395  ***this method is created only on a 64bit platform***
3396  */
3397  uint FromInt(unsigned int value)
3398  {
3399  return FromUInt(uint(value));
3400  }
3401 
3402 
3403  /*
3404  this method converts 32 bit signed int to this class
3405  ***this method is created only on a 64bit platform***
3406  */
3407  uint FromInt(signed int value)
3408  {
3409  return FromInt(sint(value));
3410  }
3411 
3412 
3417  Big<exp, man> & operator=(unsigned int value)
3418  {
3419  FromUInt(value);
3420 
3421  return *this;
3422  }
3423 
3424 
3429  Big(unsigned int value)
3430  {
3431  FromUInt(value);
3432  }
3433 
3434 
3439  Big<exp, man> & operator=(signed int value)
3440  {
3441  FromInt(value);
3442 
3443  return *this;
3444  }
3445 
3446 
3451  Big(signed int value)
3452  {
3453  FromInt(value);
3454  }
3455 
3456 #endif
3457 
3458 
3459 private:
3460 
3468  template<uint int_size>
3469  uint FromUIntOrInt(const UInt<int_size> & value, sint compensation)
3470  {
3471  uint minimum_size = (int_size < man)? int_size : man;
3472  exponent = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation;
3473 
3474  // copying the highest words
3475  uint i;
3476  for(i=1 ; i<=minimum_size ; ++i)
3477  mantissa.table[man-i] = value.table[int_size-i];
3478 
3479  // setting the rest of mantissa.table into zero (if some has left)
3480  for( ; i<=man ; ++i)
3481  mantissa.table[man-i] = 0;
3482 
3483  // the highest bit is either one or zero (when the whole mantissa is zero)
3484  // we can only call CorrectZero()
3485  CorrectZero();
3486 
3487  return 0;
3488  }
3489 
3490 
3491 public:
3492 
3496  template<uint int_size>
3498  {
3499  info = 0;
3500  sint compensation = (sint)value.CompensationToLeft();
3501 
3502  return FromUIntOrInt(value, compensation);
3503  }
3504 
3505 
3509  template<uint int_size>
3510  uint FromInt(const UInt<int_size> & value)
3511  {
3512  return FromUInt(value);
3513  }
3514 
3515 
3519  template<uint int_size>
3521  {
3522  info = 0;
3523  bool is_sign = false;
3524 
3525  if( value.IsSign() )
3526  {
3527  value.ChangeSign();
3528  is_sign = true;
3529  }
3530 
3531  sint compensation = (sint)value.CompensationToLeft();
3532  FromUIntOrInt(value, compensation);
3533 
3534  if( is_sign )
3535  SetSign();
3536 
3537  return 0;
3538  }
3539 
3540 
3544  template<uint int_size>
3546  {
3547  FromInt(value);
3548 
3549  return *this;
3550  }
3551 
3552 
3556  template<uint int_size>
3557  Big(const Int<int_size> & value)
3558  {
3559  FromInt(value);
3560  }
3561 
3562 
3566  template<uint int_size>
3568  {
3569  FromUInt(value);
3570 
3571  return *this;
3572  }
3573 
3574 
3578  template<uint int_size>
3579  Big(const UInt<int_size> & value)
3580  {
3581  FromUInt(value);
3582  }
3583 
3584 
3588  template<uint another_exp, uint another_man>
3590  {
3591  FromBig(value);
3592 
3593  return *this;
3594  }
3595 
3596 
3600  template<uint another_exp, uint another_man>
3602  {
3603  FromBig(value);
3604  }
3605 
3606 
3618  {
3619  #ifdef TTMATH_BIG_DEFAULT_CLEAR
3620 
3621  SetZeroNan();
3622 
3623  #else
3624 
3625  info = TTMATH_BIG_NAN;
3626  // we're directly setting 'info' (instead of calling SetNan())
3627  // in order to get rid of a warning saying that 'info' is uninitialized
3628 
3629  #endif
3630  }
3631 
3632 
3637  {
3638  }
3639 
3640 
3645  {
3646  info = value.info;
3647  exponent = value.exponent;
3648  mantissa = value.mantissa;
3649 
3650  return *this;
3651  }
3652 
3653 
3658  Big(const Big<exp,man> & value)
3659  {
3660  operator=(value);
3661  }
3662 
3663 
3664 
3675  uint ToString( std::string & result,
3676  uint base = 10,
3677  bool scient = false,
3678  sint scient_from = 15,
3679  sint round = -1,
3680  bool trim_zeroes = true,
3681  char comma = '.' ) const
3682  {
3683  Conv conv;
3684 
3685  conv.base = base;
3686  conv.scient = scient;
3687  conv.scient_from = scient_from;
3688  conv.round = round;
3689  conv.trim_zeroes = trim_zeroes;
3690  conv.comma = static_cast<uint>(comma);
3691 
3692  return ToStringBase<std::string, char>(result, conv);
3693  }
3694 
3695 
3700  uint ToString(std::string & result, const Conv & conv) const
3701  {
3702  return ToStringBase<std::string, char>(result, conv);
3703  }
3704 
3705 
3710  std::string ToString(const Conv & conv) const
3711  {
3712  std::string result;
3713  ToStringBase<std::string, char>(result, conv);
3714 
3715  return result;
3716  }
3717 
3718 
3723  std::string ToString(uint base = 10) const
3724  {
3725  Conv conv;
3726  conv.base = base;
3727 
3728  return ToString(conv);
3729  }
3730 
3731 
3732 
3733 #ifndef TTMATH_DONT_USE_WCHAR
3734 
3735 
3740  uint ToString( std::wstring & result,
3741  uint base = 10,
3742  bool scient = false,
3743  sint scient_from = 15,
3744  sint round = -1,
3745  bool trim_zeroes = true,
3746  wchar_t comma = '.' ) const
3747  {
3748  Conv conv;
3749 
3750  conv.base = base;
3751  conv.scient = scient;
3752  conv.scient_from = scient_from;
3753  conv.round = round;
3754  conv.trim_zeroes = trim_zeroes;
3755  conv.comma = static_cast<uint>(comma);
3756 
3757  return ToStringBase<std::wstring, wchar_t>(result, conv);
3758  }
3759 
3760 
3765  uint ToString(std::wstring & result, const Conv & conv) const
3766  {
3767  return ToStringBase<std::wstring, wchar_t>(result, conv);
3768  }
3769 
3770 
3775  std::wstring ToWString(const Conv & conv) const
3776  {
3777  std::wstring result;
3778  ToStringBase<std::wstring, wchar_t>(result, conv);
3779 
3780  return result;
3781  }
3782 
3783 
3788  std::wstring ToWString(uint base = 10) const
3789  {
3790  Conv conv;
3791  conv.base = base;
3792 
3793  return ToWString(conv);
3794  }
3795 
3796 #endif
3797 
3798 
3799 
3800 private:
3801 
3802 
3806  template<class string_type, class char_type>
3807  uint ToStringBase(string_type & result, const Conv & conv) const
3808  {
3809  static char error_overflow_msg[] = "overflow";
3810  static char error_nan_msg[] = "NaN";
3811  result.erase();
3812 
3813  if( IsNan() )
3814  {
3815  Misc::AssignString(result, error_nan_msg);
3816  return 0;
3817  }
3818 
3819  if( conv.base<2 || conv.base>16 )
3820  {
3821  Misc::AssignString(result, error_overflow_msg);
3822  return 1;
3823  }
3824 
3825  if( IsZero() )
3826  {
3827  result = '0';
3828 
3829  return 0;
3830  }
3831 
3832  /*
3833  since 'base' is greater or equal 2 that 'new_exp' of type 'Int<exp>' should
3834  hold the new value of exponent but we're using 'Int<exp+1>' because
3835  if the value for example would be 'max()' then we couldn't show it
3836 
3837  max() -> 11111111 * 2 ^ 11111111111 (bin)(the mantissa and exponent have all bits set)
3838  if we were using 'Int<exp>' we couldn't show it in this format:
3839  1,1111111 * 2 ^ 11111111111 (bin)
3840  because we have to add something to the mantissa and because
3841  mantissa is full we can't do it and it'll be a carry
3842  (look at ToString_SetCommaAndExponent(...))
3843 
3844  when the base would be greater than two (for example 10)
3845  we could use 'Int<exp>' here
3846  */
3847  Int<exp+1> new_exp;
3848 
3849  if( ToString_CreateNewMantissaAndExponent<string_type, char_type>(result, conv, new_exp) )
3850  {
3851  Misc::AssignString(result, error_overflow_msg);
3852  return 1;
3853  }
3854 
3855 
3856  if( ToString_SetCommaAndExponent<string_type, char_type>(result, conv, new_exp) )
3857  {
3858  Misc::AssignString(result, error_overflow_msg);
3859  return 1;
3860  }
3861 
3862  if( IsSign() )
3863  result.insert(result.begin(), '-');
3864 
3865 
3866  // converted successfully
3867  return 0;
3868  }
3869 
3870 
3871 
3877  friend class Big<exp-1,man>;
3878 
3879 
3942  template<class string_type, class char_type>
3943  uint ToString_CreateNewMantissaAndExponent( string_type & new_man, const Conv & conv,
3944  Int<exp+1> & new_exp) const
3945  {
3946  uint c = 0;
3947 
3948  if( conv.base<2 || conv.base>16 )
3949  return 1;
3950 
3951  // special method for base equal 2
3952  if( conv.base == 2 )
3953  return ToString_CreateNewMantissaAndExponent_Base2(new_man, new_exp);
3954 
3955  // special method for base equal 4
3956  if( conv.base == 4 )
3957  return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 2);
3958 
3959  // special method for base equal 8
3960  if( conv.base == 8 )
3961  return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 3);
3962 
3963  // special method for base equal 16
3964  if( conv.base == 16 )
3965  return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 4);
3966 
3967 
3968  // this = mantissa * 2^exponent
3969 
3970  // temp = +1 * 2^exponent
3971  // we're using a bigger type than 'big<exp,man>' (look below)
3972  Big<exp+1,man> temp;
3973  temp.info = 0;
3974  temp.exponent = exponent;
3975  temp.mantissa.SetOne();
3976  c += temp.Standardizing();
3977 
3978  // new_exp_ = log base (2^exponent)
3979  // if new_exp_ is positive and with fraction then we add one
3980  Big<exp+1,man> new_exp_;
3981  c += new_exp_.ToString_Log(temp, conv.base); // this logarithm isn't very complicated
3982 
3983  // rounding up to the nearest integer
3984  if( !new_exp_.IsInteger() )
3985  {
3986  if( !new_exp_.IsSign() )
3987  c += new_exp_.AddOne(); // new_exp_ > 0 and with fraction
3988 
3989  new_exp_.SkipFraction();
3990  }
3991 
3992  if( ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp) )
3993  {
3994  // in very rare cases there can be an overflow from ToString_CreateNewMantissaTryExponent
3995  // it means that new_exp_ was too small (the problem comes from floating point numbers precision)
3996  // so we increse new_exp_ and try again
3997  new_exp_.AddOne();
3998  c += ToString_CreateNewMantissaTryExponent<string_type, char_type>(new_man, conv, new_exp_, new_exp);
3999  }
4000 
4001  return (c==0)? 0 : 1;
4002  }
4003 
4004 
4005 
4012  template<class string_type, class char_type>
4013  uint ToString_CreateNewMantissaTryExponent( string_type & new_man, const Conv & conv,
4014  const Big<exp+1,man> & new_exp_, Int<exp+1> & new_exp) const
4015  {
4016  uint c = 0;
4017 
4018  // because 'base^new_exp' is >= '2^exponent' then
4019  // because base is >= 2 then we've got:
4020  // 'new_exp_' must be smaller or equal 'new_exp'
4021  // and we can pass it into the Int<exp> type
4022  // (in fact we're using a greater type then it'll be ok)
4023  c += new_exp_.ToInt(new_exp);
4024 
4025  // base_ = base
4026  Big<exp+1,man> base_(conv.base);
4027 
4028  // base_ = base_ ^ new_exp_
4029  c += base_.Pow( new_exp_ ); // use new_exp_ so Pow(Big<> &) version will be used
4030  // if we hadn't used a bigger type than 'Big<exp,man>' then the result
4031  // of this formula 'Pow(...)' would have been with an overflow
4032 
4033  // temp = mantissa * 2^exponent / base_^new_exp_
4034  Big<exp+1,man> temp;
4035  temp.info = 0;
4036  temp.mantissa = mantissa;
4037  temp.exponent = exponent;
4038  c += temp.Div(base_);
4039 
4040  // moving all bits of the mantissa into the right
4041  // (how many times to move depend on the exponent)
4042  c += temp.ToString_MoveMantissaIntoRight();
4043 
4044  // because we took 'new_exp' as small as it was
4045  // possible ([log base (2^exponent)] + 1) that after the division
4046  // (temp.Div( base_ )) the value of exponent should be equal zero or
4047  // minimum smaller than zero then we've got the mantissa which has
4048  // maximum valid bits
4049  temp.mantissa.ToString(new_man, conv.base);
4050 
4051  if( IsInteger() )
4052  {
4053  // making sure the new mantissa will be without fraction (integer)
4054  ToString_CheckMantissaInteger<string_type, char_type>(new_man, new_exp);
4055  }
4056  else
4057  if( conv.base_round )
4058  {
4059  c += ToString_BaseRound<string_type, char_type>(new_man, conv, new_exp);
4060  }
4061 
4062  return (c==0)? 0 : 1;
4063  }
4064 
4065 
4079  uint ToString_Log(const Big<exp,man> & x, uint base)
4080  {
4082  TTMATH_ASSERT( base>=2 && base<=16 )
4083 
4084  Big<exp,man> temp;
4085  temp.SetOne();
4086 
4087  if( x == temp )
4088  {
4089  // log(1) is 0
4090  SetZero();
4091 
4092  return 0;
4093  }
4094 
4095  // there can be only a carry
4096  // because the 'x' is in '1+2*exponent' form then
4097  // the long formula from LnSurrounding1() will not be calculated
4098  // (LnSurrounding1() will return one immediately)
4099  uint c = Ln(x);
4100 
4101  if( base==10 && man<=TTMATH_BUILTIN_VARIABLES_SIZE )
4102  {
4103  // for the base equal 10 we're using SetLn10() instead of calculating it
4104  // (only if we have the constant sufficient big)
4105  temp.SetLn10();
4106  }
4107  else
4108  {
4109  c += ToString_LogBase(base, temp);
4110  }
4111 
4112  c += Div( temp );
4113 
4114  return (c==0)? 0 : 1;
4115  }
4116 
4117 
4118 #ifndef TTMATH_MULTITHREADS
4119 
4124  uint ToString_LogBase(uint base, Big<exp,man> & result)
4125  {
4126  TTMATH_ASSERT( base>=2 && base<=16 )
4127 
4128  // this guardians are initialized before the program runs (static POD types)
4129  static int guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4130  static Big<exp,man> log_history[15];
4131  uint index = base - 2;
4132  uint c = 0;
4133 
4134  if( guardians[index] == 0 )
4135  {
4136  Big<exp,man> base_(base);
4137  c += log_history[index].Ln(base_);
4138  guardians[index] = 1;
4139  }
4140 
4141  result = log_history[index];
4142 
4143  return (c==0)? 0 : 1;
4144  }
4145 
4146 #else
4147 
4152  uint ToString_LogBase(uint base, Big<exp,man> & result)
4153  {
4154  TTMATH_ASSERT( base>=2 && base<=16 )
4155 
4156  // this guardians are initialized before the program runs (static POD types)
4157  volatile static sig_atomic_t guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4158  static Big<exp,man> * plog_history;
4159  uint index = base - 2;
4160  uint c = 0;
4161 
4162  // double-checked locking
4163  if( guardians[index] == 0 )
4164  {
4165  ThreadLock thread_lock;
4166 
4167  // locking
4168  if( thread_lock.Lock() )
4169  {
4170  static Big<exp,man> log_history[15];
4171 
4172  if( guardians[index] == 0 )
4173  {
4174  plog_history = log_history;
4175 
4176  Big<exp,man> base_(base);
4177  c += log_history[index].Ln(base_);
4178  guardians[index] = 1;
4179  }
4180  }
4181  else
4182  {
4183  // there was a problem with locking, we store the result directly in 'result' object
4184  Big<exp,man> base_(base);
4185  c += result.Ln(base_);
4186 
4187  return (c==0)? 0 : 1;
4188  }
4189 
4190  // automatically unlocking
4191  }
4192 
4193  result = plog_history[index];
4194 
4195  return (c==0)? 0 : 1;
4196  }
4197 
4198 #endif
4199 
4206  uint ToString_MoveMantissaIntoRight()
4207  {
4208  if( exponent.IsZero() )
4209  return 0;
4210 
4211  // exponent can't be greater than zero
4212  // because we would cat the highest bits of the mantissa
4213  if( !exponent.IsSign() )
4214  return 1;
4215 
4216 
4217  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
4218  // if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
4219  // it means that we must cut the whole mantissa
4220  // (there'll not be any of the valid bits)
4221  return 1;
4222 
4223  // e will be from (-man*TTMATH_BITS_PER_UINT, 0>
4224  sint e = -( exponent.ToInt() );
4225  mantissa.Rcr(e,0);
4226 
4227  return 0;
4228  }
4229 
4230 
4239  template<class string_type>
4240  uint ToString_CreateNewMantissaAndExponent_Base2( string_type & new_man,
4241  Int<exp+1> & new_exp ) const
4242  {
4243  for( sint i=man-1 ; i>=0 ; --i )
4244  {
4245  uint value = mantissa.table[i];
4246 
4247  for( uint bit=0 ; bit<TTMATH_BITS_PER_UINT ; ++bit )
4248  {
4249  if( (value & TTMATH_UINT_HIGHEST_BIT) != 0 )
4250  new_man += '1';
4251  else
4252  new_man += '0';
4253 
4254  value <<= 1;
4255  }
4256  }
4257 
4258  new_exp = exponent;
4259 
4260  return 0;
4261  }
4262 
4263 
4273  template<class string_type>
4274  uint ToString_CreateNewMantissaAndExponent_BasePow2( string_type & new_man,
4275  Int<exp+1> & new_exp,
4276  uint bits) const
4277  {
4278  sint move; // how many times move the mantissa
4279  UInt<man+1> man_temp(mantissa); // man+1 for moving
4280  new_exp = exponent;
4281  new_exp.DivInt((sint)bits, move);
4282 
4283  if( move != 0 )
4284  {
4285  // we're moving the man_temp to left-hand side
4286  if( move < 0 )
4287  {
4288  move = sint(bits) + move;
4289  new_exp.SubOne(); // when move is < than 0 then new_exp is < 0 too
4290  }
4291 
4292  man_temp.Rcl(move);
4293  }
4294 
4295 
4296  if( bits == 3 )
4297  {
4298  // base 8
4299  // now 'move' is greater than or equal 0
4300  uint len = man*TTMATH_BITS_PER_UINT + move;
4301  return ToString_CreateNewMantissaAndExponent_Base8(new_man, man_temp, len, bits);
4302  }
4303  else
4304  {
4305  // base 4 or 16
4306  return ToString_CreateNewMantissaAndExponent_Base4or16(new_man, man_temp, bits);
4307  }
4308  }
4309 
4310 
4320  template<class string_type>
4321  uint ToString_CreateNewMantissaAndExponent_Base8( string_type & new_man,
4322  UInt<man+1> & man_temp,
4323  uint len,
4324  uint bits) const
4325  {
4326  uint shift = TTMATH_BITS_PER_UINT - bits;
4327  uint mask = TTMATH_UINT_MAX_VALUE >> shift;
4328  uint i;
4329 
4330  for( i=0 ; i<len ; i+=bits )
4331  {
4332  uint digit = man_temp.table[0] & mask;
4333  new_man.insert(new_man.begin(), static_cast<char>(Misc::DigitToChar(digit)));
4334 
4335  man_temp.Rcr(bits);
4336  }
4337 
4338  TTMATH_ASSERT( man_temp.IsZero() )
4339 
4340  return 0;
4341  }
4342 
4343 
4352  template<class string_type>
4353  uint ToString_CreateNewMantissaAndExponent_Base4or16( string_type & new_man,
4354  UInt<man+1> & man_temp,
4355  uint bits) const
4356  {
4357  TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 2 == 0 )
4358  TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 4 == 0 )
4359 
4360  uint shift = TTMATH_BITS_PER_UINT - bits;
4361  uint mask = TTMATH_UINT_MAX_VALUE << shift;
4362  uint digit;
4363 
4364  // table[man] - last word - is different from zero if we moved man_temp
4365  digit = man_temp.table[man];
4366 
4367  if( digit != 0 )
4368  new_man += static_cast<char>(Misc::DigitToChar(digit));
4369 
4370 
4371  for( int i=man-1 ; i>=0 ; --i )
4372  {
4373  uint shift_local = shift;
4374  uint mask_local = mask;
4375 
4376  while( mask_local != 0 )
4377  {
4378  digit = man_temp.table[i] & mask_local;
4379 
4380  if( shift_local != 0 )
4381  digit = digit >> shift_local;
4382 
4383  new_man += static_cast<char>(Misc::DigitToChar(digit));
4384  mask_local = mask_local >> bits;
4385  shift_local = shift_local - bits;
4386  }
4387  }
4388 
4389  return 0;
4390  }
4391 
4392 
4396  template<class string_type, class char_type>
4397  bool ToString_RoundMantissaWouldBeInteger(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
4398  {
4399  // if new_exp is greater or equal to zero then we have an integer value,
4400  // if new_exp is equal -1 then we have only one digit after the comma
4401  // and after rounding it would be an integer value
4402  if( !new_exp.IsSign() || new_exp == -1 )
4403  return true;
4404 
4405  if( new_man.size() >= TTMATH_UINT_HIGHEST_BIT || new_man.size() < 2 )
4406  return true; // oops, the mantissa is too large for calculating (or too small) - we are not doing the base rounding
4407 
4408  uint i = 0;
4409  char_type digit;
4410 
4411  if( new_exp >= -sint(new_man.size()) )
4412  {
4413  uint new_exp_abs = -new_exp.ToInt();
4414  i = new_man.size() - new_exp_abs; // start from the first digit after the comma operator
4415  }
4416 
4417  if( Misc::CharToDigit(new_man[new_man.size()-1]) >= conv.base/2 )
4418  {
4419  if( new_exp < -sint(new_man.size()) )
4420  {
4421  // there are some zeroes after the comma operator
4422  // (between the comma and the first digit from the mantissa)
4423  // and the result value will never be an integer
4424  return false;
4425  }
4426 
4427  digit = static_cast<char_type>( Misc::DigitToChar(conv.base-1) );
4428  }
4429  else
4430  {
4431  digit = '0';
4432  }
4433 
4434  for( ; i < new_man.size()-1 ; ++i)
4435  if( new_man[i] != digit )
4436  return false; // it will not be an integer
4437 
4438  return true; // it will be integer after rounding
4439  }
4440 
4441 
4454  template<class string_type, class char_type>
4455  void ToString_CheckMantissaInteger(string_type & new_man, const Int<exp+1> & new_exp) const
4456  {
4457  if( !new_exp.IsSign() )
4458  return; // return if new_exp >= 0
4459 
4460  uint i = 0;
4461  uint man_size = new_man.size();
4462 
4463  if( man_size >= TTMATH_UINT_HIGHEST_BIT )
4464  return; // ops, the mantissa is too long
4465 
4466  sint sman_size = -sint(man_size);
4467 
4468  if( new_exp >= sman_size )
4469  {
4470  sint e = new_exp.ToInt();
4471  e = -e;
4472  // now e means how many last digits from the mantissa should be equal zero
4473 
4474  i = man_size - uint(e);
4475  }
4476 
4477  for( ; i<man_size ; ++i)
4478  new_man[i] = '0';
4479  }
4480 
4481 
4488  template<class string_type, class char_type>
4489  uint ToString_BaseRound(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
4490  {
4491  // we must have minimum two characters
4492  if( new_man.size() < 2 )
4493  return 0;
4494 
4495  // assert that there will not be an integer after rounding
4496  if( ToString_RoundMantissaWouldBeInteger<string_type, char_type>(new_man, conv, new_exp) )
4497  return 0;
4498 
4499  typename string_type::size_type i = new_man.length() - 1;
4500 
4501  // we're erasing the last character
4502  uint digit = Misc::CharToDigit( new_man[i] );
4503  new_man.erase(i, 1);
4504  uint c = new_exp.AddOne();
4505 
4506  // if the last character is greater or equal 'base/2'
4507  // we are adding one into the new mantissa
4508  if( digit >= conv.base / 2 )
4509  ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
4510 
4511  return c;
4512  }
4513 
4514 
4520  template<class string_type, class char_type>
4521  void ToString_RoundMantissa_AddOneIntoMantissa(string_type & new_man, const Conv & conv) const
4522  {
4523  if( new_man.empty() )
4524  return;
4525 
4526  sint i = sint( new_man.length() ) - 1;
4527  bool was_carry = true;
4528 
4529  for( ; i>=0 && was_carry ; --i )
4530  {
4531  // we can have the comma as well because
4532  // we're using this method later in ToString_CorrectDigitsAfterComma_Round()
4533  // (we're only ignoring it)
4534  if( new_man[i] == static_cast<char_type>(conv.comma) )
4535  continue;
4536 
4537  // we're adding one
4538  uint digit = Misc::CharToDigit( new_man[i] ) + 1;
4539 
4540  if( digit == conv.base )
4541  digit = 0;
4542  else
4543  was_carry = false;
4544 
4545  new_man[i] = static_cast<char_type>( Misc::DigitToChar(digit) );
4546  }
4547 
4548  if( i<0 && was_carry )
4549  new_man.insert( new_man.begin() , '1' );
4550  }
4551 
4552 
4553 
4560  template<class string_type, class char_type>
4561  uint ToString_SetCommaAndExponent(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
4562  {
4563  uint carry = 0;
4564 
4565  if( new_man.empty() )
4566  return carry;
4567 
4568  Int<exp+1> scientific_exp( new_exp );
4569 
4570  // 'new_exp' depends on the 'new_man' which is stored like this e.g:
4571  // 32342343234 (the comma is at the end)
4572  // we'd like to show it in this way:
4573  // 3.2342343234 (the 'scientific_exp' is connected with this example)
4574 
4575  sint offset = sint( new_man.length() ) - 1;
4576  carry += scientific_exp.Add( offset );
4577  // there shouldn't have been a carry because we're using
4578  // a greater type -- 'Int<exp+1>' instead of 'Int<exp>'
4579 
4580  bool print_scientific = conv.scient;
4581 
4582  if( !print_scientific )
4583  {
4584  if( scientific_exp > conv.scient_from || scientific_exp < -sint(conv.scient_from) )
4585  print_scientific = true;
4586  }
4587 
4588  if( !print_scientific )
4589  ToString_SetCommaAndExponent_Normal<string_type, char_type>(new_man, conv, new_exp);
4590  else
4591  // we're passing the 'scientific_exp' instead of 'new_exp' here
4592  ToString_SetCommaAndExponent_Scientific<string_type, char_type>(new_man, conv, scientific_exp);
4593 
4594  return (carry==0)? 0 : 1;
4595  }
4596 
4597 
4601  template<class string_type, class char_type>
4602  void ToString_SetCommaAndExponent_Normal(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp ) const
4603  {
4604  if( !new_exp.IsSign() ) // it means: if( new_exp >= 0 )
4605  ToString_SetCommaAndExponent_Normal_AddingZero<string_type, char_type>(new_man, new_exp);
4606  else
4607  ToString_SetCommaAndExponent_Normal_SetCommaInside<string_type, char_type>(new_man, conv, new_exp);
4608 
4609 
4610  ToString_Group_man<string_type, char_type>(new_man, conv);
4611  }
4612 
4613 
4617  template<class string_type, class char_type>
4618  void ToString_SetCommaAndExponent_Normal_AddingZero(string_type & new_man,
4619  Int<exp+1> & new_exp) const
4620  {
4621  // we're adding zero characters at the end
4622  // 'i' will be smaller than 'when_scientific' (or equal)
4623  uint i = new_exp.ToInt();
4624 
4625  if( new_man.length() + i > new_man.capacity() )
4626  // about 6 characters more (we'll need it for the comma or something)
4627  new_man.reserve( new_man.length() + i + 6 );
4628 
4629  for( ; i>0 ; --i)
4630  new_man += '0';
4631  }
4632 
4633 
4637  template<class string_type, class char_type>
4638  void ToString_SetCommaAndExponent_Normal_SetCommaInside(
4639  string_type & new_man,
4640  const Conv & conv,
4641  Int<exp+1> & new_exp ) const
4642  {
4643  // new_exp is < 0
4644 
4645  sint new_man_len = sint(new_man.length()); // 'new_man_len' with a sign
4646  sint e = -( new_exp.ToInt() ); // 'e' will be positive
4647 
4648  if( new_exp > -new_man_len )
4649  {
4650  // we're setting the comma within the mantissa
4651 
4652  sint index = new_man_len - e;
4653  new_man.insert( new_man.begin() + index, static_cast<char_type>(conv.comma));
4654  }
4655  else
4656  {
4657  // we're adding zero characters before the mantissa
4658 
4659  uint how_many = e - new_man_len;
4660  string_type man_temp(how_many+1, '0');
4661 
4662  man_temp.insert( man_temp.begin()+1, static_cast<char_type>(conv.comma));
4663  new_man.insert(0, man_temp);
4664  }
4665 
4666  ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
4667  }
4668 
4669 
4673  template<class string_type, class char_type>
4674  void ToString_SetCommaAndExponent_Scientific( string_type & new_man,
4675  const Conv & conv,
4676  Int<exp+1> & scientific_exp ) const
4677  {
4678  if( new_man.empty() )
4679  return;
4680 
4681  if( new_man.size() > 1 )
4682  {
4683  new_man.insert( new_man.begin()+1, static_cast<char_type>(conv.comma) );
4684  ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
4685  }
4686 
4687  ToString_Group_man<string_type, char_type>(new_man, conv);
4688 
4689  if( conv.base == 10 )
4690  {
4691  new_man += 'e';
4692 
4693  if( !scientific_exp.IsSign() )
4694  new_man += '+';
4695  }
4696  else
4697  {
4698  // the 10 here is meant as the base 'base'
4699  // (no matter which 'base' we're using there'll always be 10 here)
4700  Misc::AddString(new_man, "*10^");
4701  }
4702 
4703  string_type temp_exp;
4704  scientific_exp.ToString( temp_exp, conv.base );
4705 
4706  new_man += temp_exp;
4707  }
4708 
4709 
4713  template<class string_type, class char_type>
4714  void ToString_Group_man(string_type & new_man, const Conv & conv) const
4715  {
4716  typedef typename string_type::size_type StrSize;
4717 
4718  if( conv.group == 0 )
4719  return;
4720 
4721  // first we're looking for the comma operator
4722  StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
4723 
4724  if( index == string_type::npos )
4725  index = new_man.size();
4726 
4727  ToString_Group_man_before_comma<string_type, char_type>(new_man, conv, index);
4728  ToString_Group_man_after_comma<string_type, char_type>(new_man, conv, index+1);
4729  }
4730 
4731 
4732 
4736  template<class string_type, class char_type>
4737  void ToString_Group_man_before_comma( string_type & new_man, const Conv & conv,
4738  typename string_type::size_type & index) const
4739  {
4740  typedef typename string_type::size_type StrSize;
4741 
4742  uint group = 0;
4743  StrSize i = index;
4744  uint group_digits = conv.group_digits;
4745 
4746  if( group_digits < 1 )
4747  group_digits = 1;
4748 
4749  // adding group characters before the comma operator
4750  // i>0 because on the first position we don't put any additional grouping characters
4751  for( ; i>0 ; --i, ++group)
4752  {
4753  if( group >= group_digits )
4754  {
4755  group = 0;
4756  new_man.insert(i, 1, static_cast<char_type>(conv.group));
4757  ++index;
4758  }
4759  }
4760  }
4761 
4762 
4766  template<class string_type, class char_type>
4767  void ToString_Group_man_after_comma(string_type & new_man, const Conv & conv,
4768  typename string_type::size_type index) const
4769  {
4770  uint group = 0;
4771  uint group_digits = conv.group_digits;
4772 
4773  if( group_digits < 1 )
4774  group_digits = 1;
4775 
4776  for( ; index<new_man.size() ; ++index, ++group)
4777  {
4778  if( group >= group_digits )
4779  {
4780  group = 0;
4781  new_man.insert(index, 1, static_cast<char_type>(conv.group));
4782  ++index;
4783  }
4784  }
4785  }
4786 
4787 
4791  template<class string_type, class char_type>
4792  void ToString_CorrectDigitsAfterComma( string_type & new_man,
4793  const Conv & conv ) const
4794  {
4795  if( conv.round >= 0 )
4796  ToString_CorrectDigitsAfterComma_Round<string_type, char_type>(new_man, conv);
4797 
4798  if( conv.trim_zeroes )
4799  ToString_CorrectDigitsAfterComma_CutOffZeroCharacters<string_type, char_type>(new_man, conv);
4800  }
4801 
4802 
4806  template<class string_type, class char_type>
4807  void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
4808  string_type & new_man,
4809  const Conv & conv) const
4810  {
4811  // minimum two characters
4812  if( new_man.length() < 2 )
4813  return;
4814 
4815  // we're looking for the index of the last character which is not zero
4816  uint i = uint( new_man.length() ) - 1;
4817  for( ; i>0 && new_man[i]=='0' ; --i );
4818 
4819  // if there is another character than zero at the end
4820  // we're finishing
4821  if( i == new_man.length() - 1 )
4822  return;
4823 
4824  // we must have a comma
4825  // (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
4826  // which is called before)
4827  if( new_man.find_last_of(static_cast<char_type>(conv.comma), i) == string_type::npos )
4828  return;
4829 
4830  // if directly before the first zero is the comma operator
4831  // we're cutting it as well
4832  if( i>0 && new_man[i]==static_cast<char_type>(conv.comma) )
4833  --i;
4834 
4835  new_man.erase(i+1, new_man.length()-i-1);
4836  }
4837 
4838 
4842  template<class string_type, class char_type>
4843  void ToString_CorrectDigitsAfterComma_Round(
4844  string_type & new_man,
4845  const Conv & conv ) const
4846  {
4847  typedef typename string_type::size_type StrSize;
4848 
4849  // first we're looking for the comma operator
4850  StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
4851 
4852  if( index == string_type::npos )
4853  // nothing was found (actually there can't be this situation)
4854  return;
4855 
4856  // we're calculating how many digits there are at the end (after the comma)
4857  // 'after_comma' will be greater than zero because at the end
4858  // we have at least one digit
4859  StrSize after_comma = new_man.length() - index - 1;
4860 
4861  // if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
4862  // we don't have anything for cutting
4863  if( static_cast<StrSize>(conv.round) >= after_comma )
4864  return;
4865 
4866  uint last_digit = Misc::CharToDigit( new_man[ index + conv.round + 1 ], conv.base );
4867 
4868  // we're cutting the rest of the string
4869  new_man.erase(index + conv.round + 1, after_comma - conv.round);
4870 
4871  if( conv.round == 0 )
4872  {
4873  // we're cutting the comma operator as well
4874  // (it's not needed now because we've cut the whole rest after the comma)
4875  new_man.erase(index, 1);
4876  }
4877 
4878  if( last_digit >= conv.base / 2 )
4879  // we must round here
4880  ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
4881  }
4882 
4883 
4884 
4885 public:
4886 
4907  uint FromString(const char * source, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
4908  {
4909  Conv conv;
4910  conv.base = base;
4911 
4912  return FromStringBase(source, conv, after_source, value_read);
4913  }
4914 
4915 
4919  uint FromString(const char * source, const Conv & conv, const char ** after_source = 0, bool * value_read = 0)
4920  {
4921  return FromStringBase(source, conv, after_source, value_read);
4922  }
4923 
4924 
4928  uint FromString(const std::string & string, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
4929  {
4930  return FromString(string.c_str(), base, after_source, value_read);
4931  }
4932 
4933 
4937  uint FromString(const std::string & string, const Conv & conv, const char ** after_source = 0, bool * value_read = 0)
4938  {
4939  return FromString(string.c_str(), conv, after_source, value_read);
4940  }
4941 
4942 
4943 #ifndef TTMATH_DONT_USE_WCHAR
4944 
4948  uint FromString(const wchar_t * source, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
4949  {
4950  Conv conv;
4951  conv.base = base;
4952 
4953  return FromStringBase(source, conv, after_source, value_read);
4954  }
4955 
4956 
4960  uint FromString(const wchar_t * source, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
4961  {
4962  return FromStringBase(source, conv, after_source, value_read);
4963  }
4964 
4965 
4969  uint FromString(const std::wstring & string, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
4970  {
4971  return FromString(string.c_str(), base, after_source, value_read);
4972  }
4973 
4974 
4978  uint FromString(const std::wstring & string, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
4979  {
4980  return FromString(string.c_str(), conv, after_source, value_read);
4981  }
4982 
4983 #endif
4984 
4985 
4986 private:
4987 
4988 
4992  template<class char_type>
4993  uint FromStringBase(const char_type * source, const Conv & conv, const char_type ** after_source = 0, bool * value_read = 0)
4994  {
4995  bool is_sign;
4996  bool value_read_temp = false;
4997 
4998  if( conv.base<2 || conv.base>16 )
4999  {
5000  SetNan();
5001 
5002  if( after_source )
5003  *after_source = source;
5004 
5005  if( value_read )
5006  *value_read = value_read_temp;
5007 
5008  return 1;
5009  }
5010 
5011  SetZero();
5012  FromString_TestSign( source, is_sign );
5013 
5014  uint c = FromString_ReadPartBeforeComma( source, conv, value_read_temp );
5015 
5016  if( FromString_TestCommaOperator(source, conv) )
5017  c += FromString_ReadPartAfterComma( source, conv, value_read_temp );
5018 
5019  if( value_read_temp && conv.base == 10 )
5020  c += FromString_ReadScientificIfExists( source );
5021 
5022  if( is_sign && !IsZero() )
5023  ChangeSign();
5024 
5025  if( after_source )
5026  *after_source = source;
5027 
5028  if( value_read )
5029  *value_read = value_read_temp;
5030 
5031  return CheckCarry(c);
5032  }
5033 
5034 
5040  template<class char_type>
5041  void FromString_TestSign( const char_type * & source, bool & is_sign )
5042  {
5043  Misc::SkipWhiteCharacters(source);
5044 
5045  is_sign = false;
5046 
5047  if( *source == '-' )
5048  {
5049  is_sign = true;
5050  ++source;
5051  }
5052  else
5053  if( *source == '+' )
5054  {
5055  ++source;
5056  }
5057  }
5058 
5059 
5063  template<class char_type>
5064  bool FromString_TestCommaOperator(const char_type * & source, const Conv & conv)
5065  {
5066  if( (*source == static_cast<char_type>(conv.comma)) ||
5067  (*source == static_cast<char_type>(conv.comma2) && conv.comma2 != 0 ) )
5068  {
5069  ++source;
5070 
5071  return true;
5072  }
5073 
5074  return false;
5075  }
5076 
5077 
5082  template<class char_type>
5083  uint FromString_ReadPartBeforeComma( const char_type * & source, const Conv & conv, bool & value_read )
5084  {
5085  sint character;
5086  Big<exp, man> temp;
5087  Big<exp, man> base_( conv.base );
5088 
5089  Misc::SkipWhiteCharacters( source );
5090 
5091  for( ; true ; ++source )
5092  {
5093  if( conv.group!=0 && *source==static_cast<char>(conv.group) )
5094  continue;
5095 
5096  character = Misc::CharToDigit(*source, conv.base);
5097 
5098  if( character == -1 )
5099  break;
5100 
5101  value_read = true;
5102  temp = character;
5103 
5104  if( Mul(base_) )
5105  return 1;
5106 
5107  if( Add(temp) )
5108  return 1;
5109  }
5110 
5111  return 0;
5112  }
5113 
5114 
5119  template<class char_type>
5120  uint FromString_ReadPartAfterComma( const char_type * & source, const Conv & conv, bool & value_read )
5121  {
5122  sint character;
5123  uint c = 0, power = 0;
5124  UInt<1> power_;
5125  Big<exp, man> sum, base_(conv.base);
5126 
5127  // we don't remove any white characters here
5128  sum.SetZero();
5129 
5130  for( ; sum.exponent.IsSign() || sum.exponent.IsZero() ; ++source )
5131  {
5132  if( conv.group!=0 && *source==static_cast<char>(conv.group) )
5133  continue;
5134 
5135  character = Misc::CharToDigit(*source, conv.base);
5136 
5137  if( character == -1 )
5138  break;
5139 
5140  value_read = true;
5141 
5142  // there actually shouldn't be a carry here
5143  c += sum.Mul(base_);
5144  c += sum.Add(character);
5145  power += 1;
5146 
5147  if( power == 0 )
5148  c += 1;
5149  }
5150 
5151  // we could break the parsing somewhere in the middle of the string,
5152  // but the result (value) still can be good
5153  // we should set a correct value of 'source' now
5154  for( ; Misc::CharToDigit(*source, conv.base) != -1 ; ++source );
5155 
5156  power_ = power;
5157  c += base_.Pow(power_);
5158  c += sum.Div(base_);
5159  c += Add(sum);
5160 
5161  return (c==0)? 0 : 1;
5162  }
5163 
5164 
5170  template<class char_type>
5171  uint FromString_ReadScientificIfExists(const char_type * & source)
5172  {
5173  uint c = 0;
5174 
5175  bool scientific_read = false;
5176  const char_type * before_scientific = source;
5177 
5178  if( FromString_TestScientific(source) )
5179  c += FromString_ReadPartScientific( source, scientific_read );
5180 
5181  if( !scientific_read )
5182  source = before_scientific;
5183 
5184  return (c==0)? 0 : 1;
5185  }
5186 
5187 
5188 
5194  template<class char_type>
5195  bool FromString_TestScientific(const char_type * & source)
5196  {
5197  Misc::SkipWhiteCharacters(source);
5198 
5199  if( *source=='e' || *source=='E' )
5200  {
5201  ++source;
5202 
5203  return true;
5204  }
5205 
5206  return false;
5207  }
5208 
5209 
5214  template<class char_type>
5215  uint FromString_ReadPartScientific( const char_type * & source, bool & scientific_read )
5216  {
5217  uint c = 0;
5218  Big<exp, man> new_exponent, temp;
5219  bool was_sign = false;
5220 
5221  FromString_TestSign( source, was_sign );
5222  c += FromString_ReadPartScientific_ReadExponent( source, new_exponent, scientific_read );
5223 
5224  if( scientific_read )
5225  {
5226  if( was_sign )
5227  new_exponent.ChangeSign();
5228 
5229  temp = 10;
5230  c += temp.Pow( new_exponent );
5231  c += Mul(temp);
5232  }
5233 
5234  return (c==0)? 0 : 1;
5235  }
5236 
5237 
5242  template<class char_type>
5243  uint FromString_ReadPartScientific_ReadExponent( const char_type * & source, Big<exp, man> & new_exponent, bool & scientific_read )
5244  {
5245  sint character;
5246  Big<exp, man> base, temp;
5247 
5248  Misc::SkipWhiteCharacters(source);
5249 
5250  new_exponent.SetZero();
5251  base = 10;
5252 
5253  for( ; (character=Misc::CharToDigit(*source, 10)) != -1 ; ++source )
5254  {
5255  scientific_read = true;
5256 
5257  temp = character;
5258 
5259  if( new_exponent.Mul(base) )
5260  return 1;
5261 
5262  if( new_exponent.Add(temp) )
5263  return 1;
5264  }
5265 
5266  return 0;
5267  }
5268 
5269 
5270 public:
5271 
5272 
5276  Big(const char * string)
5277  {
5278  FromString( string );
5279  }
5280 
5281 
5285  Big(const std::string & string)
5286  {
5287  FromString( string.c_str() );
5288  }
5289 
5290 
5294  Big<exp, man> & operator=(const char * string)
5295  {
5296  FromString( string );
5297 
5298  return *this;
5299  }
5300 
5301 
5305  Big<exp, man> & operator=(const std::string & string)
5306  {
5307  FromString( string.c_str() );
5308 
5309  return *this;
5310  }
5311 
5312 
5313 
5314 #ifndef TTMATH_DONT_USE_WCHAR
5315 
5319  Big(const wchar_t * string)
5320  {
5321  FromString( string );
5322  }
5323 
5324 
5328  Big(const std::wstring & string)
5329  {
5330  FromString( string.c_str() );
5331  }
5332 
5333 
5337  Big<exp, man> & operator=(const wchar_t * string)
5338  {
5339  FromString( string );
5340 
5341  return *this;
5342  }
5343 
5344 
5348  Big<exp, man> & operator=(const std::wstring & string)
5349  {
5350  FromString( string.c_str() );
5351 
5352  return *this;
5353  }
5354 
5355 
5356 #endif
5357 
5358 
5359 
5374  bool SmallerWithoutSignThan(const Big<exp,man> & ss2) const
5375  {
5376  if( IsZero() )
5377  {
5378  if( ss2.IsZero() )
5379  // we've got two zeroes
5380  return false;
5381  else
5382  // this==0 and ss2!=0
5383  return true;
5384  }
5385 
5386  if( ss2.IsZero() )
5387  // this!=0 and ss2==0
5388  return false;
5389 
5390  // we're using the fact that all bits in mantissa are pushed
5391  // into the left side -- Standardizing()
5392  if( exponent == ss2.exponent )
5393  return mantissa < ss2.mantissa;
5394 
5395  return exponent < ss2.exponent;
5396  }
5397 
5398 
5406  bool GreaterWithoutSignThan(const Big<exp,man> & ss2) const
5407  {
5408  if( IsZero() )
5409  {
5410  if( ss2.IsZero() )
5411  // we've got two zeroes
5412  return false;
5413  else
5414  // this==0 and ss2!=0
5415  return false;
5416  }
5417 
5418  if( ss2.IsZero() )
5419  // this!=0 and ss2==0
5420  return true;
5421 
5422  // we're using the fact that all bits in mantissa are pushed
5423  // into the left side -- Standardizing()
5424  if( exponent == ss2.exponent )
5425  return mantissa > ss2.mantissa;
5426 
5427  return exponent > ss2.exponent;
5428  }
5429 
5430 
5438  bool EqualWithoutSign(const Big<exp,man> & ss2) const
5439  {
5440  if( IsZero() )
5441  {
5442  if( ss2.IsZero() )
5443  // we've got two zeroes
5444  return true;
5445  else
5446  // this==0 and ss2!=0
5447  return false;
5448  }
5449 
5450  if( ss2.IsZero() )
5451  // this!=0 and ss2==0
5452  return false;
5453 
5454  if( exponent==ss2.exponent && mantissa==ss2.mantissa )
5455  return true;
5456 
5457  return false;
5458  }
5459 
5460 
5461  bool operator<(const Big<exp,man> & ss2) const
5462  {
5463  if( IsSign() && !ss2.IsSign() )
5464  // this<0 and ss2>=0
5465  return true;
5466 
5467  if( !IsSign() && ss2.IsSign() )
5468  // this>=0 and ss2<0
5469  return false;
5470 
5471  // both signs are the same
5472 
5473  if( IsSign() )
5474  return ss2.SmallerWithoutSignThan( *this );
5475 
5476  return SmallerWithoutSignThan( ss2 );
5477  }
5478 
5479 
5480  bool operator==(const Big<exp,man> & ss2) const
5481  {
5482  if( IsSign() != ss2.IsSign() )
5483  return false;
5484 
5485  return EqualWithoutSign( ss2 );
5486  }
5487 
5488 
5489  bool operator>(const Big<exp,man> & ss2) const
5490  {
5491  if( IsSign() && !ss2.IsSign() )
5492  // this<0 and ss2>=0
5493  return false;
5494 
5495  if( !IsSign() && ss2.IsSign() )
5496  // this>=0 and ss2<0
5497  return true;
5498 
5499  // both signs are the same
5500 
5501  if( IsSign() )
5502  return ss2.GreaterWithoutSignThan( *this );
5503 
5504  return GreaterWithoutSignThan( ss2 );
5505  }
5506 
5507 
5508  bool operator>=(const Big<exp,man> & ss2) const
5509  {
5510  return !operator<( ss2 );
5511  }
5512 
5513 
5514  bool operator<=(const Big<exp,man> & ss2) const
5515  {
5516  return !operator>( ss2 );
5517  }
5518 
5519 
5520  bool operator!=(const Big<exp,man> & ss2) const
5521  {
5522  return !operator==(ss2);
5523  }
5524 
5525 
5526 
5527 
5528 
5542  {
5543  Big<exp,man> temp(*this);
5544 
5545  temp.ChangeSign();
5546 
5547  return temp;
5548  }
5549 
5550 
5552  {
5553  Big<exp,man> temp(*this);
5554 
5555  temp.Sub(ss2);
5556 
5557  return temp;
5558  }
5559 
5561  {
5562  Sub(ss2);
5563 
5564  return *this;
5565  }
5566 
5567 
5569  {
5570  Big<exp,man> temp(*this);
5571 
5572  temp.Add(ss2);
5573 
5574  return temp;
5575  }
5576 
5577 
5579  {
5580  Add(ss2);
5581 
5582  return *this;
5583  }
5584 
5585 
5587  {
5588  Big<exp,man> temp(*this);
5589 
5590  temp.Mul(ss2);
5591 
5592  return temp;
5593  }
5594 
5595 
5597  {
5598  Mul(ss2);
5599 
5600  return *this;
5601  }
5602 
5603 
5605  {
5606  Big<exp,man> temp(*this);
5607 
5608  temp.Div(ss2);
5609 
5610  return temp;
5611  }
5612 
5613 
5615  {
5616  Div(ss2);
5617 
5618  return *this;
5619  }
5620 
5621 
5626  {
5627  AddOne();
5628 
5629  return *this;
5630  }
5631 
5632 
5637  {
5638  Big<exp,man> temp( *this );
5639 
5640  AddOne();
5641 
5642  return temp;
5643  }
5644 
5645 
5647  {
5648  SubOne();
5649 
5650  return *this;
5651  }
5652 
5653 
5655  {
5656  Big<exp,man> temp( *this );
5657 
5658  SubOne();
5659 
5660  return temp;
5661  }
5662 
5663 
5664 
5673  {
5674  Big<exp,man> temp( *this );
5675 
5676  temp.BitAnd(p2);
5677 
5678  return temp;
5679  }
5680 
5681 
5683  {
5684  BitAnd(p2);
5685 
5686  return *this;
5687  }
5688 
5689 
5691  {
5692  Big<exp,man> temp( *this );
5693 
5694  temp.BitOr(p2);
5695 
5696  return temp;
5697  }
5698 
5699 
5701  {
5702  BitOr(p2);
5703 
5704  return *this;
5705  }
5706 
5707 
5709  {
5710  Big<exp,man> temp( *this );
5711 
5712  temp.BitXor(p2);
5713 
5714  return temp;
5715  }
5716 
5717 
5719  {
5720  BitXor(p2);
5721 
5722  return *this;
5723  }
5724 
5725 
5726 
5727 
5728 
5729 
5742  {
5743  if( IsNan() || IsZero() )
5744  return;
5745 
5746  if( !exponent.IsSign() )
5747  // exponent >=0 -- the value don't have any fractions
5748  return;
5749 
5750  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
5751  {
5752  // the value is from (-1,1), we return zero
5753  SetZero();
5754  return;
5755  }
5756 
5757  // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
5758  sint e = exponent.ToInt();
5759 
5760  mantissa.ClearFirstBits( -e );
5761 
5762  // we don't have to standardize 'Standardizing()' the value because
5763  // there's at least one bit in the mantissa
5764  // (the highest bit which we didn't touch)
5765  }
5766 
5767 
5776  {
5777  if( IsNan() || IsZero() )
5778  return;
5779 
5780  if( !exponent.IsSign() )
5781  {
5782  // exponent >= 0 -- the value doesn't have any fractions
5783  // we return zero
5784  SetZero();
5785  return;
5786  }
5787 
5788  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
5789  {
5790  // the value is from (-1,1)
5791  // we don't make anything with the value
5792  return;
5793  }
5794 
5795  // e will be from (-man*TTMATH_BITS_PER_UINT, 0)
5796  sint e = exponent.ToInt();
5797 
5798  sint how_many_bits_leave = sint(man*TTMATH_BITS_PER_UINT) + e; // there'll be a subtraction -- e is negative
5799  mantissa.Rcl( how_many_bits_leave, 0);
5800 
5801  // there'll not be a carry because the exponent is too small
5802  exponent.Sub( how_many_bits_leave );
5803 
5804  // we must call Standardizing() here
5805  Standardizing();
5806  }
5807 
5808 
5809 
5816  bool IsInteger() const
5817  {
5818  if( IsZero() )
5819  return true;
5820 
5821  if( !exponent.IsSign() )
5822  // exponent >=0 -- the value don't have any fractions
5823  return true;
5824 
5825  if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
5826  // the value is from (-1,1)
5827  return false;
5828 
5829  // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
5830  sint e = exponent.ToInt();
5831  e = -e; // e means how many bits we must check
5832 
5833  uint len = e / TTMATH_BITS_PER_UINT;
5834  uint rest = e % TTMATH_BITS_PER_UINT;
5835  uint i = 0;
5836 
5837  for( ; i<len ; ++i )
5838  if( mantissa.table[i] != 0 )
5839  return false;
5840 
5841  if( rest > 0 )
5842  {
5843  uint rest_mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
5844  if( (mantissa.table[i] & rest_mask) != 0 )
5845  return false;
5846  }
5847 
5848  return true;
5849  }
5850 
5851 
5864  {
5865  Big<exp,man> half;
5866  uint c;
5867 
5868  if( IsNan() )
5869  return 1;
5870 
5871  if( IsZero() )
5872  return 0;
5873 
5874  half.Set05();
5875 
5876  if( IsSign() )
5877  {
5878  // 'this' is < 0
5879  c = Sub( half );
5880  }
5881  else
5882  {
5883  // 'this' is > 0
5884  c = Add( half );
5885  }
5886 
5887  SkipFraction();
5888 
5889  return CheckCarry(c);
5890  }
5891 
5892 
5893 
5900 private:
5901 
5905  template<class ostream_type, class string_type>
5906  static ostream_type & OutputToStream(ostream_type & s, const Big<exp,man> & l)
5907  {
5908  string_type ss;
5909 
5910  l.ToString(ss);
5911  s << ss;
5912 
5913  return s;
5914  }
5915 
5916 
5917 public:
5918 
5919 
5923  friend std::ostream & operator<<(std::ostream & s, const Big<exp,man> & l)
5924  {
5925  return OutputToStream<std::ostream, std::string>(s, l);
5926  }
5927 
5928 
5929 #ifndef TTMATH_DONT_USE_WCHAR
5930 
5934  friend std::wostream & operator<<(std::wostream & s, const Big<exp,man> & l)
5935  {
5936  return OutputToStream<std::wostream, std::wstring>(s, l);
5937  }
5938 
5939 #endif
5940 
5941 
5942 
5943 private:
5944 
5948  template<class istream_type, class string_type, class char_type>
5949  static istream_type & InputFromStream(istream_type & s, Big<exp,man> & l)
5950  {
5951  string_type ss;
5952 
5953  // char or wchar_t for operator>>
5954  char_type z, old_z;
5955  bool was_comma = false;
5956  bool was_e = false;
5957 
5958 
5959  // operator>> omits white characters if they're set for ommiting
5960  s >> z;
5961 
5962  if( z=='-' || z=='+' )
5963  {
5964  ss += z;
5965  s >> z; // we're reading a next character (white characters can be ommited)
5966  }
5967 
5968  old_z = 0;
5969 
5970  // we're reading only digits (base=10) and only one comma operator
5971  for( ; s.good() ; z=static_cast<char_type>(s.get()) )
5972  {
5973  if( z=='.' || z==',' )
5974  {
5975  if( was_comma || was_e )
5976  // second comma operator or comma operator after 'e' character
5977  break;
5978 
5979  was_comma = true;
5980  }
5981  else
5982  if( z == 'e' || z == 'E' )
5983  {
5984  if( was_e )
5985  // second 'e' character
5986  break;
5987 
5988  was_e = true;
5989  }
5990  else
5991  if( z == '+' || z == '-' )
5992  {
5993  if( old_z != 'e' && old_z != 'E' )
5994  // '+' or '-' is allowed only after 'e' character
5995  break;
5996  }
5997  else
5998  if( Misc::CharToDigit(z, 10) < 0 )
5999  break;
6000 
6001 
6002  ss += z;
6003  old_z = z;
6004  }
6005 
6006  // we're leaving the last read character
6007  // (it's not belonging to the value)
6008  s.unget();
6009 
6010  l.FromString( ss );
6011 
6012  return s;
6013  }
6014 
6015 
6016 
6017 public:
6018 
6022  friend std::istream & operator>>(std::istream & s, Big<exp,man> & l)
6023  {
6024  return InputFromStream<std::istream, std::string, char>(s, l);
6025  }
6026 
6027 
6028 #ifndef TTMATH_DONT_USE_WCHAR
6029 
6033  friend std::wistream & operator>>(std::wistream & s, Big<exp,man> & l)
6034  {
6035  return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
6036  }
6037 
6038 #endif
6039 
6040 };
6041 
6042 
6043 } // namespace
6044 
6045 #endif
Big< exp, man > operator+(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5568
uint PowFrac(const Big< exp, man > &pow)
Definition: ttmathbig.h:1739
void SetLn10()
Definition: ttmathbig.h:552
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:3589
Big< exp, man > & operator=(uint value)
Definition: ttmathbig.h:3089
uint FromInt(sint value)
Definition: ttmathbig.h:2537
Big< exp, man > & operator=(float value)
Definition: ttmathbig.h:3100
Definition: ttmathtypes.h:385
uint FromInt(Int< int_size > value)
Definition: ttmathbig.h:3520
void SetZeroNan()
Definition: ttmathbig.h:306
Big< exp, man > & operator=(ulint value)
Definition: ttmathbig.h:3300
static void SkipWhiteCharacters(const char_type *&c)
Definition: ttmathmisc.h:160
std::string ToString(uint base=10) const
Definition: ttmathbig.h:3723
static uint CharToDigit(uint c)
Definition: ttmathmisc.h:181
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:3675
uint FromInt(slint value)
Definition: ttmathbig.h:3269
static const char * LibTypeStr()
#define TTMATH_ARITHMETIC_MAX_LOOP
Definition: ttmathtypes.h:289
Big< exp, man > & operator*=(const Big< exp, man > &ss2)
Definition: ttmathbig.h:5596
void RemainFraction()
Definition: ttmathbig.h:5775
NetworKit::index index
Definition: BloomFilter.h:16
uint CheckCarry(uint c)
Definition: ttmathbig.h:121
sint scient_from
Definition: ttmathtypes.h:408
static LibTypeCode LibType()
Definition: ttmathbig.h:154
bool scient
Definition: ttmathtypes.h:399
uint FromString(const wchar_t *source, const Conv &conv, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4960
static void AddString(std::string &result, const char *str)
Definition: ttmathmisc.h:135
bool GreaterWithoutSignThan(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5406
uint ToUInt(uint &result) const
Definition: ttmathbig.h:2315
sint ToInt() const
Definition: ttmathint.h:1131
bool operator>=(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5508
uint table[value_size]
Definition: ttmathuint.h:81
std::string ToString(const Conv &conv) const
Definition: ttmathbig.h:3710
Big()
Definition: ttmathbig.h:3617
uint FromUInt(ulint value)
Definition: ttmathbig.h:3199
uint FromString(const std::wstring &string, uint base=10, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4969
bool IsSign() const
Definition: ttmathbig.h:652
uint ToInt(Int< int_size > &result) const
Definition: ttmathbig.h:2480
Big< exp, man > & operator=(const std::wstring &string)
Definition: ttmathbig.h:5348
Big< exp, man > & operator--()
Definition: ttmathbig.h:5646
Big(const wchar_t *string)
Definition: ttmathbig.h:5319
uint FromString(const wchar_t *source, uint base=10, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4948
static LibTypeCode LibType()
uint FromInt(const Int< argument_size > &p)
Definition: ttmathint.h:696
uint FromString(const char *source, uint base=10, const char **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4907
void SetSign()
Definition: ttmathbig.h:718
static uint DigitToChar(uint digit)
Definition: ttmathmisc.h:236
int64_t slint
Definition: ttmathtypes.h:178
Big(double value)
Definition: ttmathbig.h:3139
uint Sub(const UInt< value_size > &ss2, uint c=0)
uint Pow(UInt< pow_size > pow)
Definition: ttmathbig.h:1556
uint Add(const UInt< value_size > &ss2, uint c=0)
uint Ln(const Big< exp, man > &x)
Definition: ttmathbig.h:2109
void ClearInfoBit(unsigned char bit)
Definition: ttmathbig.h:224
Big< exp, man > operator-() const
Definition: ttmathbig.h:5541
Big< exp, man > & operator=(const wchar_t *string)
Definition: ttmathbig.h:5337
uint FromUInt(uint value)
Definition: ttmathbig.h:2502
Big(const Big< exp, man > &value)
Definition: ttmathbig.h:3658
unsigned char info
Definition: ttmathbig.h:89
uint Abs()
Definition: ttmathint.h:167
Big< exp, man > & operator^=(const Big< exp, man > &p2)
Definition: ttmathbig.h:5718
bool EqualWithoutSign(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5438
uint Mod(const Big< exp, man > &ss2)
Definition: ttmathbig.h:1511
void SetNan()
Definition: ttmathbig.h:296
Big< exp, man > operator*(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5586
std::wstring ToWString(const Conv &conv) const
Definition: ttmathbig.h:3775
#define TTMATH_BIG_NAN
Definition: ttmathbig.h:104
uint ToInt(UInt< int_size > &result) const
Definition: ttmathbig.h:2468
void SetOne()
Definition: ttmathbig.h:271
uint ToInt(slint &result) const
Definition: ttmathbig.h:3185
Big< exp, man > & operator&=(const Big< exp, man > &p2)
Definition: ttmathbig.h:5682
uint Pow(const Big< exp, man > &pow)
Definition: ttmathbig.h:1769
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:4937
void Abs()
Definition: ttmathbig.h:676
uint ToInt(uint &result) const
Definition: ttmathbig.h:2345
uint FromFloat(float value)
Definition: ttmathbig.h:2797
void SetMax()
Definition: ttmathuint.h:215
uint FromDouble(double value)
Definition: ttmathbig.h:2587
uint Exp(const Big< exp, man > &x)
Definition: ttmathbig.h:1934
uint ToUInt(ulint &result) const
Definition: ttmathbig.h:3160
bool IsTheLowestBitSet() const
Definition: ttmathuint.h:2532
uint AddOne()
Definition: ttmathint.h:326
uint MulInt(sint ss2)
Definition: ttmathbig.h:1204
std::wstring ToWString(uint base=10) const
Definition: ttmathbig.h:3788
Big(slint value)
Definition: ttmathbig.h:3311
uint ToFloat(float &result) const
Definition: ttmathbig.h:2901
uint Sqrt()
Definition: ttmathbig.h:1806
#define TTMATH_UINT_HIGHEST_BIT
Definition: ttmathtypes.h:189
void SetE()
Definition: ttmathbig.h:427
uint Pow(Int< pow_size > pow)
Definition: ttmathbig.h:1608
uint MulInt(uint ss2)
Definition: ttmathuint.h:835
uint base
Definition: ttmathtypes.h:391
#define TTMATH_BIG_ZERO
Definition: ttmathbig.h:113
uint PowUInt(Big< exp, man > pow)
Definition: ttmathbig.h:1647
Big< exp, man > operator/(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5604
uint Mul(const Big< exp, man > &ss2, bool round=true)
Definition: ttmathbig.h:1344
uint BitOr(Big< exp, man > ss2)
Definition: ttmathbig.h:1043
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:3740
void SetMax()
Definition: ttmathint.h:71
bool operator==(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5480
signed int sint
Definition: ttmathtypes.h:164
static void AssignString(std::string &result, const char *str)
Definition: ttmathmisc.h:72
uint GetBit(uint bit_index) const
Definition: ttmathuint.h:706
LibTypeCode
Definition: ttmathtypes.h:335
void ChangeSign()
Definition: ttmathbig.h:732
uint ToDouble(double &result) const
Definition: ttmathbig.h:2938
uint ToString(std::string &result, const Conv &conv) const
Definition: ttmathbig.h:3700
float ToFloat() const
Definition: ttmathbig.h:2881
uint Div(const Big< exp, man > &ss2, bool round=true)
Definition: ttmathbig.h:1441
Big(ulint value)
Definition: ttmathbig.h:3291
Big< exp, man > operator&(const Big< exp, man > &p2) const
Definition: ttmathbig.h:5672
void SetFromTable(const uint *temp_table, uint temp_table_len)
Definition: ttmathuint.h:266
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:4928
uint ToUInt() const
Definition: ttmathuint.h:3079
Big(const std::wstring &string)
Definition: ttmathbig.h:5328
Big< exp, man > operator-(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5551
uint FromBig(const Big< another_exp, another_man > &another)
Definition: ttmathbig.h:2204
uint ToUInt(UInt< int_size > &result) const
Definition: ttmathbig.h:2448
bool operator!=(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5520
#define TTMATH_UINT_MAX_VALUE
Definition: ttmathtypes.h:195
bool IsNan() const
Definition: ttmathbig.h:661
static sint FindLeadingBitInWord(uint x)
Big(uint value)
Definition: ttmathbig.h:3130
Big< exp, man > & operator/=(const Big< exp, man > &ss2)
Definition: ttmathbig.h:5614
void BitAnd(const UInt< value_size > &ss2)
Definition: ttmathuint.h:743
#define TTMATH_BUILTIN_VARIABLES_SIZE
Definition: ttmathtypes.h:202
bool SmallerWithoutSignThan(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5374
uint Rcr(uint bits, uint c=0)
Definition: ttmathuint.h:555
uint Sub(const Big< exp, man > &ss2, bool round=true)
Definition: ttmathbig.h:970
uint ToInt(sint &result) const
Definition: ttmathbig.h:2356
#define TTMATH_ASSERT(expression)
Definition: ttmathtypes.h:660
Big(float value)
Definition: ttmathbig.h:3148
sint ToInt() const
Definition: ttmathbig.h:2330
void BitOr(const UInt< value_size > &ss2)
Definition: ttmathuint.h:755
Big< exp, man > & operator=(double value)
Definition: ttmathbig.h:3111
template class Int<uint>
uint Mod2() const
Definition: ttmathbig.h:1531
uint Round()
Definition: ttmathbig.h:5863
uint SubOne()
Definition: ttmathint.h:339
Big< exp, man > & operator=(const Int< int_size > &value)
Definition: ttmathbig.h:3545
bool operator>(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5489
Big(const std::string &string)
Definition: ttmathbig.h:5285
Big(const Big< another_exp, another_man > &value)
Definition: ttmathbig.h:3601
uint Add(const Int< value_size > &ss2)
Definition: ttmathint.h:219
uint AddInt(uint value, uint index=0)
Definition: ttmathint.h:236
Big< exp, man > & operator=(const UInt< int_size > &value)
Definition: ttmathbig.h:3567
static const char * LibTypeStr()
Definition: ttmathbig.h:145
#define TTMATH_BITS_PER_UINT
Definition: ttmathtypes.h:184
uint FromUInt(UInt< int_size > value)
Definition: ttmathbig.h:3497
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:5294
uint CompensationToLeft()
Definition: ttmathuint.h:598
Big< exp, man > & operator|=(const Big< exp, man > &p2)
Definition: ttmathbig.h:5700
bool IsSign() const
Definition: ttmathint.h:155
Big(const char *string)
Definition: ttmathbig.h:5276
uint FromInt(const UInt< int_size > &value)
Definition: ttmathbig.h:3510
Big(sint value)
Definition: ttmathbig.h:3122
uint comma
Definition: ttmathtypes.h:454
void Set2Pi()
Definition: ttmathbig.h:415
void SetPi()
Definition: ttmathbig.h:393
Big(const Int< int_size > &value)
Definition: ttmathbig.h:3557
Big< exp, man > & operator=(const Big< exp, man > &value)
Definition: ttmathbig.h:3644
uint64_t ulint
Definition: ttmathtypes.h:177
uint PowInt(const Big< exp, man > &pow)
Definition: ttmathbig.h:1703
#define TTMATH_BIG_SIGN
Definition: ttmathbig.h:97
bool operator<(const Big< exp, man > &ss2) const
Definition: ttmathbig.h:5461
void SetInfoBit(unsigned char bit)
Definition: ttmathbig.h:236
void Sgn()
Definition: ttmathbig.h:688
~Big()
Definition: ttmathbig.h:3636
Big< exp, man > & operator=(const std::string &string)
Definition: ttmathbig.h:5305
uint BitXor(Big< exp, man > ss2)
Definition: ttmathbig.h:1098
uint DivInt(sint ss2, sint *remainder=0)
Definition: ttmathint.h:523
uint Div(Int< value_size > ss2, Int< value_size > *remainder=0)
Definition: ttmathint.h:479
bool IsInfoBit(unsigned char bit) const
Definition: ttmathbig.h:247
bool IsZero() const
Definition: ttmathbig.h:642
Big(const UInt< int_size > &value)
Definition: ttmathbig.h:3579
uint FromInt(ulint value)
Definition: ttmathbig.h:3260
uint FromString(const std::wstring &string, const Conv &conv, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4978
Big< exp, man > operator^(const Big< exp, man > &p2) const
Definition: ttmathbig.h:5708
Big< exp, man > operator|(const Big< exp, man > &p2) const
Definition: ttmathbig.h:5690
uint Add(Big< exp, man > ss2, bool round=true, bool adding=true)
Definition: ttmathbig.h:922
Big< exp, man > & operator++()
Definition: ttmathbig.h:5625
void ClearFirstBits(uint n)
Definition: ttmathuint.h:2484
uint ToUInt() const
Definition: ttmathbig.h:2300
Big< exp, man > & operator=(sint value)
Definition: ttmathbig.h:3078
uint MulUInt(uint ss2)
Definition: ttmathbig.h:1150
Some objects used in multithreads environment.
void SkipFraction()
Definition: ttmathbig.h:5741
unsigned int uint
Definition: ttmathtypes.h:163
uint AddOne()
Definition: ttmathuint.h:386
void SetOne()
Definition: ttmathuint.h:202
bool IsInteger() const
Definition: ttmathbig.h:5816
uint BitAnd(Big< exp, man > ss2)
Definition: ttmathbig.h:985
UInt< man > mantissa
Definition: ttmathbig.h:88
uint Standardizing()
Definition: ttmathbig.h:173
Big< exp, man > & operator+=(const Big< exp, man > &ss2)
Definition: ttmathbig.h:5578
uint ToString(std::wstring &result, const Conv &conv) const
Definition: ttmathbig.h:3765
void SetLn2()
Definition: ttmathbig.h:484
Big implements the floating point numbers.
Definition: ttmathbig.h:63
Big< exp, man > & operator=(slint value)
Definition: ttmathbig.h:3320
uint Log(const Big< exp, man > &x, const Big< exp, man > &base)
Definition: ttmathbig.h:2153
bool IsTheHighestBitSet() const
Definition: ttmathuint.h:2523
uint SubInt(uint value, uint index=0)
Definition: ttmathint.h:313
double ToDouble() const
Definition: ttmathbig.h:2811
Big< exp, man > operator++(int)
Definition: ttmathbig.h:5636
Big< exp, man > operator--(int)
Definition: ttmathbig.h:5654
void Set05Pi()
Definition: ttmathbig.h:404
void SetMax()
Definition: ttmathbig.h:612
bool IsZero() const
Definition: ttmathuint.h:2581
bool trim_zeroes
Definition: ttmathtypes.h:447
uint FromString(const char *source, const Conv &conv, const char **after_source=0, bool *value_read=0)
Definition: ttmathbig.h:4919
Int< exp > exponent
Definition: ttmathbig.h:87
#define TTMATH_REFERENCE_ASSERT(expression)
Definition: ttmathtypes.h:659
Big< exp, man > & operator-=(const Big< exp, man > &ss2)
Definition: ttmathbig.h:5560
void SetZero()
Definition: ttmathbig.h:256
uint FromInt(uint value)
Definition: ttmathbig.h:2528
void Swap(UInt< value_size > &ss2)
Definition: ttmathuint.h:239
void SetMin()
Definition: ttmathbig.h:626
friend std::wistream & operator>>(std::wistream &s, Big< exp, man > &l)
Definition: ttmathbig.h:6033
uint Sub(const Int< value_size > &ss2)
Definition: ttmathint.h:298
uint ToInt(ulint &result) const
Definition: ttmathbig.h:3175
void Swap(Big< exp, man > &ss2)
Definition: ttmathbig.h:316
friend std::istream & operator>>(std::istream &s, Big< exp, man > &l)
Definition: ttmathbig.h:6022
uint SubOne()
Definition: ttmathuint.h:395
sint round
Definition: ttmathtypes.h:438