GEOS  3.8.0dev
ttmathint.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TTMath Bignum Library
3  * and is distributed under the 3-Clause BSD Licence.
4  * Author: Tomasz Sowa <t.sowa@ttmath.org>
5  */
6 
7 /*
8  * Copyright (c) 2006-2017, Tomasz Sowa
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are met:
13  *
14  * * Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  *
17  * * Redistributions in binary form must reproduce the above copyright
18  * notice, this list of conditions and the following disclaimer in the
19  * documentation and/or other materials provided with the distribution.
20  *
21  * * Neither the name Tomasz Sowa nor the names of contributors to this
22  * project may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 
39 
40 #ifndef headerfilettmathint
41 #define headerfilettmathint
42 
48 #include "ttmathuint.h"
49 
50 namespace ttmath
51 {
52 
53 
62 template<uint value_size>
63 class Int : public UInt<value_size>
64 {
65 public:
66 
71  void SetMax()
72  {
75  }
76 
77 
82  void SetMin()
83  {
86  }
87 
88 
93  void SetSignOne()
94  {
96  }
97 
98 
106  {
107  /*
108  if the value is equal that one which has been returned from SetMin
109  (only the highest bit is set) that means we can't change sign
110  because the value is too big (bigger about one)
111 
112  e.g. when value_size = 1 and value is -2147483648 we can't change it to the
113  2147483648 because the max value which can be held is 2147483647
114 
115  we don't change the value and we're using this fact somewhere in some methods
116  (if we look on our value without the sign we get the correct value
117  eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type)
118  */
120  return 1;
121 
122  UInt<value_size> temp(*this);
124  UInt<value_size>::Sub(temp);
125 
126  return 0;
127  }
128 
129 
130 
141  void SetSign()
142  {
143  if( IsSign() )
144  return;
145 
146  ChangeSign();
147  }
148 
149 
150 
156  bool IsSign() const
157  {
159  }
160 
161 
162 
169  {
170  if( !IsSign() )
171  return 0;
172 
173  return ChangeSign();
174  }
175 
176 
177 
178 
185 private:
186 
187  uint CorrectCarryAfterAdding(bool p1_is_sign, bool p2_is_sign)
188  {
189  if( !p1_is_sign && !p2_is_sign )
190  {
192  return 1;
193  }
194 
195  if( p1_is_sign && p2_is_sign )
196  {
197  if( ! UInt<value_size>::IsTheHighestBitSet() )
198  return 1;
199  }
200 
201  return 0;
202  }
203 
204 
205 public:
206 
220  uint Add(const Int<value_size> & ss2)
221  {
222  bool p1_is_sign = IsSign();
223  bool p2_is_sign = ss2.IsSign();
224 
225  UInt<value_size>::Add(ss2);
226 
227  return CorrectCarryAfterAdding(p1_is_sign, p2_is_sign);
228  }
229 
230 
237  uint AddInt(uint value, uint index = 0)
238  {
239  bool p1_is_sign = IsSign();
240 
241  UInt<value_size>::AddInt(value, index);
242 
243  return CorrectCarryAfterAdding(p1_is_sign, false);
244  }
245 
246 
256  uint AddTwoInts(uint x2, uint x1, uint index)
257  {
258  bool p1_is_sign = IsSign();
259 
260  UInt<value_size>::AddTwoInts(x2, x1, index);
261 
262  return CorrectCarryAfterAdding(p1_is_sign, false);
263  }
264 
265 private:
266 
267  uint CorrectCarryAfterSubtracting(bool p1_is_sign, bool p2_is_sign)
268  {
269  if( !p1_is_sign && p2_is_sign )
270  {
272  return 1;
273  }
274 
275  if( p1_is_sign && !p2_is_sign )
276  {
277  if( ! UInt<value_size>::IsTheHighestBitSet() )
278  return 1;
279  }
280 
281  return 0;
282  }
283 
284 public:
285 
299  uint Sub(const Int<value_size> & ss2)
300  {
301  bool p1_is_sign = IsSign();
302  bool p2_is_sign = ss2.IsSign();
303 
304  UInt<value_size>::Sub(ss2);
305 
306  return CorrectCarryAfterSubtracting(p1_is_sign, p2_is_sign);
307  }
308 
309 
314  uint SubInt(uint value, uint index = 0)
315  {
316  bool p1_is_sign = IsSign();
317 
318  UInt<value_size>::SubInt(value, index);
319 
320  return CorrectCarryAfterSubtracting(p1_is_sign, false);
321  }
322 
323 
328  {
329  bool p1_is_sign = IsSign();
330 
332 
333  return CorrectCarryAfterAdding(p1_is_sign, false);
334  }
335 
336 
341  {
342  bool p1_is_sign = IsSign();
343 
345 
346  return CorrectCarryAfterSubtracting(p1_is_sign, false);
347  }
348 
349 
350 private:
351 
352 
353  uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign)
354  {
355  /*
356  we have to examine the sign of the result now
357  but if the result is with the sign then:
358  1. if the signs were the same that means the result is too big
359  (the result must be without a sign)
360  2. if the signs were different that means if the result
361  is different from that one which has been returned from SetMin()
362  that is carry (result too big) but if the result is equal SetMin()
363  there'll be ok (and the next SetSign will has no effect because
364  the value is actually negative -- look at description of that case
365  in ChangeSign())
366  */
367  if( IsSign() )
368  {
369  if( ss1_is_sign != ss2_is_sign )
370  {
371  /*
372  there can be one case where signs are different and
373  the result will be equal the value from SetMin() (only the highest bit is set)
374  (this situation is ok)
375  */
377  return 1;
378  }
379  else
380  {
381  // signs were the same
382  return 1;
383  }
384  }
385 
386  return 0;
387  }
388 
389 
390 public:
391 
392 
398  uint MulInt(sint ss2)
399  {
400  bool ss1_is_sign, ss2_is_sign;
401  uint c;
402 
403  ss1_is_sign = IsSign();
404 
405  /*
406  we don't have to check the carry from Abs (values will be correct
407  because next we're using the method MulInt from the base class UInt
408  which is without a sign)
409  */
410  Abs();
411 
412  if( ss2 < 0 )
413  {
414  ss2 = -ss2;
415  ss2_is_sign = true;
416  }
417  else
418  {
419  ss2_is_sign = false;
420  }
421 
422  c = UInt<value_size>::MulInt((uint)ss2);
423  c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
424 
425  if( ss1_is_sign != ss2_is_sign )
426  SetSign();
427 
428  return c;
429  }
430 
431 
432 
441  {
442  bool ss1_is_sign, ss2_is_sign;
443  uint c;
444 
445  ss1_is_sign = IsSign();
446  ss2_is_sign = ss2.IsSign();
447 
448  /*
449  we don't have to check the carry from Abs (values will be correct
450  because next we're using the method Mul from the base class UInt
451  which is without a sign)
452  */
453  Abs();
454  ss2.Abs();
455 
456  c = UInt<value_size>::Mul(ss2);
457  c += CheckMinCarry(ss1_is_sign, ss2_is_sign);
458 
459  if( ss1_is_sign != ss2_is_sign )
460  SetSign();
461 
462  return c;
463  }
464 
465 
480  uint Div(Int<value_size> ss2, Int<value_size> * remainder = 0)
481  {
482  bool ss1_is_sign, ss2_is_sign;
483 
484  ss1_is_sign = IsSign();
485  ss2_is_sign = ss2.IsSign();
486 
487  /*
488  we don't have to test the carry from Abs as well as in Mul
489  */
490  Abs();
491  ss2.Abs();
492 
493  uint c = UInt<value_size>::Div(ss2, remainder);
494 
495  if( ss1_is_sign != ss2_is_sign )
496  SetSign();
497 
498  if( ss1_is_sign && remainder )
499  remainder->SetSign();
500 
501  return c;
502  }
503 
504  uint Div(const Int<value_size> & ss2, Int<value_size> & remainder)
505  {
506  return Div(ss2, &remainder);
507  }
508 
509 
524  uint DivInt(sint ss2, sint * remainder = 0)
525  {
526  bool ss1_is_sign, ss2_is_sign;
527 
528  ss1_is_sign = IsSign();
529 
530  /*
531  we don't have to test the carry from Abs as well as in Mul
532  */
533  Abs();
534 
535  if( ss2 < 0 )
536  {
537  ss2 = -ss2;
538  ss2_is_sign = true;
539  }
540  else
541  {
542  ss2_is_sign = false;
543  }
544 
545  uint rem;
546  uint c = UInt<value_size>::DivInt((uint)ss2, &rem);
547 
548  if( ss1_is_sign != ss2_is_sign )
549  SetSign();
550 
551  if( remainder )
552  {
553  if( ss1_is_sign )
554  *remainder = -sint(rem);
555  else
556  *remainder = sint(rem);
557  }
558 
559  return c;
560  }
561 
562 
563  uint DivInt(sint ss2, sint & remainder)
564  {
565  return DivInt(ss2, &remainder);
566  }
567 
568 
569 private:
570 
571 
577  uint Pow2(const Int<value_size> & pow)
578  {
579  bool was_sign = IsSign();
580  uint c = 0;
581 
582  if( was_sign )
583  c += Abs();
584 
585  uint c_temp = UInt<value_size>::Pow(pow);
586  if( c_temp > 0 )
587  return c_temp; // c_temp can be: 0, 1 or 2
588 
589  if( was_sign && (pow.table[0] & 1) == 1 )
590  // negative value to the power of odd number is negative
591  c += ChangeSign();
592 
593  return (c==0)? 0 : 1;
594  }
595 
596 
597 public:
598 
599 
609  {
610  if( !pow.IsSign() )
611  return Pow2(pow);
612 
614  // if 'pow' is negative then
615  // 'this' must be different from zero
616  return 2;
617 
618  if( pow.ChangeSign() )
619  return 1;
620 
621  Int<value_size> t(*this);
622  uint c_temp = t.Pow2(pow);
623  if( c_temp > 0 )
624  return c_temp;
625 
627  if( Div(t) )
628  return 1;
629 
630  return 0;
631  }
632 
633 
634 
640 private:
641 
642 
646  template<uint argument_size>
647  uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
648  {
649  uint min_size = (value_size < argument_size)? value_size : argument_size;
650  uint i;
651 
652  for(i=0 ; i<min_size ; ++i)
653  UInt<value_size>::table[i] = p.table[i];
654 
655 
656  if( value_size > argument_size )
657  {
658  uint fill;
659 
660  if( UInt_type )
661  fill = 0;
662  else
663  fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
665 
666  // 'this' is longer than 'p'
667  for( ; i<value_size ; ++i)
668  UInt<value_size>::table[i] = fill;
669  }
670  else
671  {
672  uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
674 
675  if( UInt_type && test!=0 )
676  return 1;
677 
678  for( ; i<argument_size ; ++i)
679  if( p.table[i] != test )
680  return 1;
681  }
682 
683  return 0;
684  }
685 
686 public:
687 
696  template<uint argument_size>
698  {
699  return FromUIntOrInt(p, false);
700  }
701 
702 
706  uint FromInt(sint value)
707  {
708  uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
709 
710  for(uint i=1 ; i<value_size ; ++i)
711  UInt<value_size>::table[i] = fill;
712 
713  UInt<value_size>::table[0] = uint(value);
714 
715  // there'll never be a carry here
716  return 0;
717  }
718 
719 
723  template<uint argument_size>
725  {
726  return FromUIntOrInt(p, true);
727  }
728 
729 
733  template<uint argument_size>
735  {
736  return FromUIntOrInt(p, true);
737  }
738 
739 
744  {
745  for(uint i=1 ; i<value_size ; ++i)
747 
748  UInt<value_size>::table[0] = value;
749 
750  // there can be a carry here when the size of this value is equal one word
751  // and the 'value' has the highest bit set
752  if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
753  return 1;
754 
755  return 0;
756  }
757 
758 
763  {
764  return FromUInt(value);
765  }
766 
767 
772  {
773  FromInt(p);
774 
775  return *this;
776  }
777 
778 
784  template<uint argument_size>
786  {
787  FromInt(p);
788 
789  return *this;
790  }
791 
792 
797  {
798  FromInt(i);
799 
800  return *this;
801  }
802 
803 
807  Int(sint i)
808  {
809  FromInt(i);
810  }
811 
812 
816  Int(const Int<value_size> & u) : UInt<value_size>()
817  {
818  FromInt(u);
819  }
820 
821 
825  template<uint argument_size>
827  {
828  // look that 'size' we still set as 'value_size' and not as u.value_size
829  FromInt(u);
830  }
831 
832 
833 
839  template<uint argument_size>
841  {
842  FromUInt(p);
843 
844  return *this;
845  }
846 
847 
852  {
853  FromUInt(i);
854 
855  return *this;
856  }
857 
858 
863  {
864  FromUInt(i);
865  }
866 
867 
871  template<uint argument_size>
873  {
874  // look that 'size' we still set as 'value_size' and not as u.value_size
875  FromUInt(u);
876  }
877 
878 
879 
880 #ifdef TTMATH_PLATFORM32
881 
882 
888  {
890 
891  if( c )
892  return 1;
893 
894  if( value_size == 1 )
895  return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
896 
897  if( value_size == 2 )
898  return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1;
899 
900  return 0;
901  }
902 
903 
909  {
910  return FromUInt(n);
911  }
912 
913 
918  uint FromInt(slint n)
919  {
920  uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0;
921 
923 
924  if( value_size == 1 )
925  {
926  if( uint(ulint(n) >> 32) != mask )
927  return 1;
928 
929  return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1;
930  }
931 
932  UInt<value_size>::table[1] = (uint)(ulint(n) >> 32);
933 
934  for(uint i=2 ; i<value_size ; ++i)
935  UInt<value_size>::table[i] = mask;
936 
937  return 0;
938  }
939 
940 
946  {
947  FromUInt(n);
948 
949  return *this;
950  }
951 
952 
958  {
959  FromUInt(n);
960  }
961 
962 
968  {
969  FromInt(n);
970 
971  return *this;
972  }
973 
974 
979  Int(slint n)
980  {
981  FromInt(n);
982  }
983 
984 #endif
985 
986 
987 
988 
989 #ifdef TTMATH_PLATFORM64
990 
995  uint FromUInt(unsigned int i)
996  {
997  return FromUInt(uint(i));
998  }
999 
1000 
1005  uint FromInt(unsigned int i)
1006  {
1007  return FromUInt(i);
1008  }
1009 
1010 
1015  uint FromInt(signed int i)
1016  {
1017  return FromInt(sint(i));
1018  }
1019 
1020 
1025  Int<value_size> & operator=(unsigned int i)
1026  {
1027  FromUInt(i);
1028 
1029  return *this;
1030  }
1031 
1032 
1037  Int(unsigned int i)
1038  {
1039  FromUInt(i);
1040  }
1041 
1042 
1047  Int<value_size> & operator=(signed int i)
1048  {
1049  FromInt(i);
1050 
1051  return *this;
1052  }
1053 
1054 
1059  Int(signed int i)
1060  {
1061  FromInt(i);
1062  }
1063 
1064 #endif
1065 
1066 
1067 
1071  Int(const char * s)
1072  {
1073  FromString(s);
1074  }
1075 
1076 
1080  Int(const std::string & s)
1081  {
1082  FromString( s.c_str() );
1083  }
1084 
1085 
1086 #ifndef TTMATH_DONT_USE_WCHAR
1087 
1091  Int(const wchar_t * s)
1092  {
1093  FromString(s);
1094  }
1095 
1096 
1100  Int(const std::wstring & s)
1101  {
1102  FromString( s.c_str() );
1103  }
1104 
1105 #endif
1106 
1107 
1114  {
1115  }
1116 
1117 
1122  {
1123  }
1124 
1125 
1132  sint ToInt() const
1133  {
1134  return sint( UInt<value_size>::table[0] );
1135  }
1136 
1137 
1142  uint ToUInt(uint & result) const
1143  {
1144  uint c = UInt<value_size>::ToUInt(result);
1145 
1146  if( value_size == 1 )
1147  return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
1148 
1149  return c;
1150  }
1151 
1152 
1157  uint ToInt(uint & result) const
1158  {
1159  return ToUInt(result);
1160  }
1161 
1162 
1167  uint ToInt(sint & result) const
1168  {
1169  result = sint( UInt<value_size>::table[0] );
1170  uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
1171 
1172  if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
1173  return 1;
1174 
1175  for(uint i=1 ; i<value_size ; ++i)
1176  if( UInt<value_size>::table[i] != mask )
1177  return 1;
1178 
1179  return 0;
1180  }
1181 
1182 
1183 #ifdef TTMATH_PLATFORM32
1184 
1190  uint ToUInt(ulint & result) const
1191  {
1192  uint c = UInt<value_size>::ToUInt(result);
1193 
1194  if( value_size == 1 )
1195  return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
1196 
1197  if( value_size == 2 )
1198  return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1;
1199 
1200  return c;
1201  }
1202 
1203 
1209  uint ToInt(ulint & result) const
1210  {
1211  return ToUInt(result);
1212  }
1213 
1214 
1220  uint ToInt(slint & result) const
1221  {
1222  if( value_size == 1 )
1223  {
1224  result = slint(sint(UInt<value_size>::table[0]));
1225  }
1226  else
1227  {
1228  uint low = UInt<value_size>::table[0];
1229  uint high = UInt<value_size>::table[1];
1230 
1231  result = low;
1232  result |= (ulint(high) << TTMATH_BITS_PER_UINT);
1233 
1234  uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
1235 
1236  if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) )
1237  return 1;
1238 
1239  for(uint i=2 ; i<value_size ; ++i)
1240  if( UInt<value_size>::table[i] != mask )
1241  return 1;
1242  }
1243 
1244  return 0;
1245  }
1246 
1247 #endif
1248 
1249 
1250 
1251 #ifdef TTMATH_PLATFORM64
1252 
1258  uint ToUInt(unsigned int & result) const
1259  {
1260  uint c = UInt<value_size>::ToUInt(result);
1261 
1262  if( c || IsSign() )
1263  return 1;
1264 
1265  return 0;
1266  }
1267 
1268 
1274  uint ToInt(unsigned int & result) const
1275  {
1276  return ToUInt(result);
1277  }
1278 
1279 
1285  uint ToInt(int & result) const
1286  {
1287  uint first = UInt<value_size>::table[0];
1288 
1289  result = int(first);
1290  uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0;
1291 
1292  if( (first >> 31) != (mask >> 31) )
1293  return 1;
1294 
1295  for(uint i=1 ; i<value_size ; ++i)
1296  if( UInt<value_size>::table[i] != mask )
1297  return 1;
1298 
1299  return 0;
1300  }
1301 
1302 #endif
1303 
1304 
1305 
1306 
1307 private:
1308 
1312  template<class string_type>
1313  void ToStringBase(string_type & result, uint b = 10) const
1314  {
1315  if( IsSign() )
1316  {
1317  Int<value_size> temp(*this);
1318  temp.Abs();
1319  temp.UInt<value_size>::ToStringBase(result, b, true);
1320  }
1321  else
1322  {
1323  UInt<value_size>::ToStringBase(result, b, false);
1324  }
1325  }
1326 
1327 public:
1328 
1332  void ToString(std::string & result, uint b = 10) const
1333  {
1334  return ToStringBase(result, b);
1335  }
1336 
1337 
1341  std::string ToString(uint b = 10) const
1342  {
1343  std::string result;
1344  ToStringBase(result, b);
1345 
1346  return result;
1347  }
1348 
1349 
1350 #ifndef TTMATH_DONT_USE_WCHAR
1351 
1355  void ToString(std::wstring & result, uint b = 10) const
1356  {
1357  return ToStringBase(result, b);
1358  }
1359 
1360 
1364  std::wstring ToWString(uint b = 10) const
1365  {
1366  std::wstring result;
1367  ToStringBase(result, b);
1368 
1369  return result;
1370  }
1371 
1372 #endif
1373 
1374 
1375 
1376 private:
1377 
1381  template<class char_type>
1382  uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
1383  {
1384  bool is_sign = false;
1385 
1386  Misc::SkipWhiteCharacters(s);
1387 
1388  if( *s == '-' )
1389  {
1390  is_sign = true;
1391  Misc::SkipWhiteCharacters(++s);
1392  }
1393  else
1394  if( *s == '+' )
1395  {
1396  Misc::SkipWhiteCharacters(++s);
1397  }
1398 
1399  if( UInt<value_size>::FromString(s,b,after_source,value_read) )
1400  return 1;
1401 
1402  if( is_sign )
1403  {
1404  Int<value_size> mmin;
1405 
1406  mmin.SetMin();
1407 
1408  /*
1409  the reference to mmin will be automatically converted to the reference
1410  to UInt type
1411  (this value can be equal mmin -- look at a description in ChangeSign())
1412  */
1413  if( UInt<value_size>::operator>( mmin ) )
1414  return 1;
1415 
1416  /*
1417  if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
1418  */
1419  ChangeSign();
1420  }
1421  else
1422  {
1423  Int<value_size> mmax;
1424 
1425  mmax.SetMax();
1426 
1427  if( UInt<value_size>::operator>( mmax ) )
1428  return 1;
1429  }
1430 
1431  return 0;
1432  }
1433 
1434 
1435 public:
1436 
1453  uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
1454  {
1455  return FromStringBase(s, b, after_source, value_read);
1456  }
1457 
1458 
1462  uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
1463  {
1464  return FromStringBase(s, b, after_source, value_read);
1465  }
1466 
1467 
1472  uint FromString(const std::string & s, uint b = 10)
1473  {
1474  return FromString( s.c_str(), b );
1475  }
1476 
1477 
1481  Int<value_size> & operator=(const char * s)
1482  {
1483  FromString(s);
1484 
1485  return *this;
1486  }
1487 
1488 
1489 #ifndef TTMATH_DONT_USE_WCHAR
1490 
1491 
1496  uint FromString(const std::wstring & s, uint b = 10)
1497  {
1498  return FromString( s.c_str(), b );
1499  }
1500 
1501 
1505  Int<value_size> & operator=(const wchar_t * s)
1506  {
1507  FromString(s);
1508 
1509  return *this;
1510  }
1511 
1512 
1516  Int<value_size> & operator=(const std::wstring & s)
1517  {
1518  FromString( s.c_str() );
1519 
1520  return *this;
1521  }
1522 
1523 #endif
1524 
1525 
1529  Int<value_size> & operator=(const std::string & s)
1530  {
1531  FromString( s.c_str() );
1532 
1533  return *this;
1534  }
1535 
1536 
1537 
1545  bool operator==(const Int<value_size> & l) const
1546  {
1547  return UInt<value_size>::operator==(l);
1548  }
1549 
1550  bool operator!=(const Int<value_size> & l) const
1551  {
1552  return UInt<value_size>::operator!=(l);
1553  }
1554 
1555  bool operator<(const Int<value_size> & l) const
1556  {
1557  sint i=value_size-1;
1558 
1559  sint a1 = sint(UInt<value_size>::table[i]);
1560  sint a2 = sint(l.table[i]);
1561 
1562  if( a1 != a2 )
1563  return a1 < a2;
1564 
1565 
1566  for(--i ; i>=0 ; --i)
1567  {
1568  if( UInt<value_size>::table[i] != l.table[i] )
1569  // comparison as unsigned int
1570  return UInt<value_size>::table[i] < l.table[i];
1571  }
1572 
1573  // they're equal
1574  return false;
1575  }
1576 
1577 
1578  bool operator>(const Int<value_size> & l) const
1579  {
1580  sint i=value_size-1;
1581 
1582  sint a1 = sint(UInt<value_size>::table[i]);
1583  sint a2 = sint(l.table[i]);
1584 
1585  if( a1 != a2 )
1586  return a1 > a2;
1587 
1588 
1589  for(--i ; i>=0 ; --i)
1590  {
1591  if( UInt<value_size>::table[i] != l.table[i] )
1592  // comparison as unsigned int
1593  return UInt<value_size>::table[i] > l.table[i];
1594  }
1595 
1596  // they're equal
1597  return false;
1598  }
1599 
1600 
1601  bool operator<=(const Int<value_size> & l) const
1602  {
1603  sint i=value_size-1;
1604 
1605  sint a1 = sint(UInt<value_size>::table[i]);
1606  sint a2 = sint(l.table[i]);
1607 
1608  if( a1 != a2 )
1609  return a1 < a2;
1610 
1611 
1612  for(--i ; i>=0 ; --i)
1613  {
1614  if( UInt<value_size>::table[i] != l.table[i] )
1615  // comparison as unsigned int
1616  return UInt<value_size>::table[i] < l.table[i];
1617  }
1618 
1619  // they're equal
1620  return true;
1621  }
1622 
1623 
1624  bool operator>=(const Int<value_size> & l) const
1625  {
1626  sint i=value_size-1;
1627 
1628  sint a1 = sint(UInt<value_size>::table[i]);
1629  sint a2 = sint(l.table[i]);
1630 
1631  if( a1 != a2 )
1632  return a1 > a2;
1633 
1634 
1635  for(--i ; i>=0 ; --i)
1636  {
1637  if( UInt<value_size>::table[i] != l.table[i] )
1638  // comparison as unsigned int
1639  return UInt<value_size>::table[i] > l.table[i];
1640  }
1641 
1642  // they're equal
1643  return true;
1644  }
1645 
1646 
1647 
1661  {
1662  Int<value_size> temp(*this);
1663 
1664  temp.ChangeSign();
1665 
1666  return temp;
1667  }
1668 
1669 
1670  Int<value_size> operator-(const Int<value_size> & p2) const
1671  {
1672  Int<value_size> temp(*this);
1673 
1674  temp.Sub(p2);
1675 
1676  return temp;
1677  }
1678 
1679 
1680  Int<value_size> & operator-=(const Int<value_size> & p2)
1681  {
1682  Sub(p2);
1683 
1684  return *this;
1685  }
1686 
1687 
1688  Int<value_size> operator+(const Int<value_size> & p2) const
1689  {
1690  Int<value_size> temp(*this);
1691 
1692  temp.Add(p2);
1693 
1694  return temp;
1695  }
1696 
1697 
1698  Int<value_size> & operator+=(const Int<value_size> & p2)
1699  {
1700  Add(p2);
1701 
1702  return *this;
1703  }
1704 
1705 
1706  Int<value_size> operator*(const Int<value_size> & p2) const
1707  {
1708  Int<value_size> temp(*this);
1709 
1710  temp.Mul(p2);
1711 
1712  return temp;
1713  }
1714 
1715 
1716  Int<value_size> & operator*=(const Int<value_size> & p2)
1717  {
1718  Mul(p2);
1719 
1720  return *this;
1721  }
1722 
1723 
1724  Int<value_size> operator/(const Int<value_size> & p2) const
1725  {
1726  Int<value_size> temp(*this);
1727 
1728  temp.Div(p2);
1729 
1730  return temp;
1731  }
1732 
1733 
1734  Int<value_size> & operator/=(const Int<value_size> & p2)
1735  {
1736  Div(p2);
1737 
1738  return *this;
1739  }
1740 
1741 
1742  Int<value_size> operator%(const Int<value_size> & p2) const
1743  {
1744  Int<value_size> temp(*this);
1745  Int<value_size> remainder;
1746 
1747  temp.Div(p2, remainder);
1748 
1749  return remainder;
1750  }
1751 
1752 
1753  Int<value_size> & operator%=(const Int<value_size> & p2)
1754  {
1755  Int<value_size> remainder;
1756 
1757  Div(p2, remainder);
1758  operator=(remainder);
1759 
1760  return *this;
1761  }
1762 
1763 
1768  {
1769  AddOne();
1770 
1771  return *this;
1772  }
1773 
1774 
1779  {
1780  UInt<value_size> temp( *this );
1781 
1782  AddOne();
1783 
1784  return temp;
1785  }
1786 
1787 
1788  UInt<value_size> & operator--()
1789  {
1790  SubOne();
1791 
1792  return *this;
1793  }
1794 
1795 
1796  UInt<value_size> operator--(int)
1797  {
1798  UInt<value_size> temp( *this );
1799 
1800  SubOne();
1801 
1802  return temp;
1803  }
1804 
1805 
1806 
1813 private:
1814 
1818  template<class ostream_type, class string_type>
1819  static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l)
1820  {
1821  string_type ss;
1822 
1823  l.ToString(ss);
1824  s << ss;
1825 
1826  return s;
1827  }
1828 
1829 
1830 
1831 public:
1832 
1833 
1837  friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
1838  {
1839  return OutputToStream<std::ostream, std::string>(s, l);
1840  }
1841 
1842 
1843 #ifndef TTMATH_DONT_USE_WCHAR
1844 
1848  friend std::wostream & operator<<(std::wostream & s, const Int<value_size> & l)
1849  {
1850  return OutputToStream<std::wostream, std::wstring>(s, l);
1851  }
1852 
1853 #endif
1854 
1855 
1856 
1857 private:
1858 
1862  template<class istream_type, class string_type, class char_type>
1863  static istream_type & InputFromStream(istream_type & s, Int<value_size> & l)
1864  {
1865  string_type ss;
1866 
1867  // char or wchar_t for operator>>
1868  char_type z;
1869 
1870  // operator>> omits white characters if they're set for ommiting
1871  s >> z;
1872 
1873  if( z=='-' || z=='+' )
1874  {
1875  ss += z;
1876  s >> z; // we're reading a next character (white characters can be ommited)
1877  }
1878 
1879  // we're reading only digits (base=10)
1880  while( s.good() && Misc::CharToDigit(z, 10)>=0 )
1881  {
1882  ss += z;
1883  z = static_cast<char_type>(s.get());
1884  }
1885 
1886  // we're leaving the last readed character
1887  // (it's not belonging to the value)
1888  s.unget();
1889 
1890  l.FromString(ss);
1891 
1892  return s;
1893  }
1894 
1895 
1896 public:
1897 
1901  friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
1902  {
1903  return InputFromStream<std::istream, std::string, char>(s, l);
1904  }
1905 
1906 
1907 #ifndef TTMATH_DONT_USE_WCHAR
1908 
1912  friend std::wistream & operator>>(std::wistream & s, Int<value_size> & l)
1913  {
1914  return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l);
1915  }
1916 #endif
1917 
1918 
1919 };
1920 
1921 } // namespace
1922 
1923 #endif
Int implements a big integer value with a sign.
Definition: ttmathint.h:63
Int(const Int< argument_size > &u)
Definition: ttmathint.h:826
Int(const char *s)
Definition: ttmathint.h:1071
Int< value_size > & operator=(slint n)
Definition: ttmathint.h:967
uint SubOne()
Definition: ttmathint.h:340
Int(sint i)
Definition: ttmathint.h:807
Int< value_size > & operator=(const Int< argument_size > &p)
Definition: ttmathint.h:785
uint FromInt(ulint n)
Definition: ttmathint.h:908
Int(const std::wstring &s)
Definition: ttmathint.h:1100
uint FromUInt(const UInt< argument_size > &p)
Definition: ttmathuint.h:2657
std::wstring ToWString(uint b=10) const
Definition: ttmathint.h:1364
UInt implements a big integer value without a sign.
Definition: ttmathuint.h:73
Int< value_size > operator-() const
Definition: ttmathint.h:1660
void ToStringBase(string_type &result, uint b=10, bool negative=false) const
Definition: ttmathuint.h:3316
Int(const std::string &s)
Definition: ttmathint.h:1080
template class UInt
uint SubOne()
Definition: ttmathuint.h:395
Int< value_size > & operator=(uint i)
Definition: ttmathint.h:851
uint FromString(const std::wstring &s, uint b=10)
Definition: ttmathint.h:1496
Int(const Int< value_size > &u)
Definition: ttmathint.h:816
Int< value_size > & operator=(const UInt< argument_size > &p)
Definition: ttmathint.h:840
sint ToInt() const
Definition: ttmathint.h:1132
uint Sub(const Int< value_size > &ss2)
Definition: ttmathint.h:299
static uint CharToDigit(uint c)
Definition: ttmathmisc.h:181
Int()
Definition: ttmathint.h:1113
void ToString(std::string &result, uint b=10) const
Definition: ttmathint.h:1332
friend std::wistream & operator>>(std::wistream &s, Int< value_size > &l)
Definition: ttmathint.h:1912
void SetSignOne()
Definition: ttmathint.h:93
void SetMax()
Definition: ttmathuint.h:215
uint ToInt(sint &result) const
Definition: ttmathint.h:1167
uint Div(const UInt< value_size > &divisor, UInt< value_size > *remainder=0, uint algorithm=3)
Definition: ttmathuint.h:1626
uint FromString(const char *s, uint b=10, const char **after_source=0, bool *value_read=0)
Definition: ttmathint.h:1453
Int< value_size > & operator=(const char *s)
Definition: ttmathint.h:1481
uint Mul(Int< value_size > ss2)
Definition: ttmathint.h:440
uint ToInt(ulint &result) const
Definition: ttmathint.h:1209
std::string ToString(uint b=10) const
Definition: ttmathint.h:1341
#define TTMATH_UINT_HIGHEST_BIT
Definition: ttmathtypes.h:212
UInt< value_size > & operator++()
Definition: ttmathint.h:1767
uint MulInt(sint ss2)
Definition: ttmathint.h:398
Int< value_size > & operator=(const Int< value_size > &p)
Definition: ttmathint.h:771
uint Pow(UInt< value_size > pow)
Definition: ttmathuint.h:2425
Int< value_size > & operator=(sint i)
Definition: ttmathint.h:796
uint ToUInt(ulint &result) const
Definition: ttmathint.h:1190
Int(const UInt< argument_size > &u)
Definition: ttmathint.h:872
uint Abs()
Definition: ttmathint.h:168
a namespace for the TTMath library
Definition: ttmath.h:62
Int(slint n)
Definition: ttmathint.h:979
void SetZero()
Definition: ttmathuint.h:188
uint AddOne()
Definition: ttmathuint.h:386
#define TTMATH_UINT_MAX_VALUE
Definition: ttmathtypes.h:218
void SetSign()
Definition: ttmathint.h:141
uint Mul(const UInt< value_size > &ss2, uint algorithm=100)
Definition: ttmathuint.h:923
uint DivInt(uint divisor, uint *remainder=0)
Definition: ttmathuint.h:1568
uint AddInt(uint value, uint index=0)
Definition: ttmathint.h:237
uint AddTwoInts(uint x2, uint x1, uint index)
Definition: ttmathint.h:256
uint ChangeSign()
Definition: ttmathint.h:105
Int< value_size > & operator=(ulint n)
Definition: ttmathint.h:945
bool operator==(const Int< value_size > &l) const
Definition: ttmathint.h:1545
uint FromString(const wchar_t *s, uint b=10, const wchar_t **after_source=0, bool *value_read=0)
Definition: ttmathint.h:1462
uint FromInt(const UInt< argument_size > &p)
Definition: ttmathint.h:734
void SetOne()
Definition: ttmathuint.h:202
uint FromInt(const Int< argument_size > &p)
Definition: ttmathint.h:697
uint FromUInt(ulint n)
Definition: ttmathint.h:887
uint FromInt(slint n)
Definition: ttmathint.h:918
uint FromInt(sint value)
Definition: ttmathint.h:706
#define TTMATH_BITS_PER_UINT
Definition: ttmathtypes.h:207
uint FromUInt(uint value)
Definition: ttmathint.h:743
void SetMax()
Definition: ttmathint.h:71
uint Pow(Int< value_size > pow)
Definition: ttmathint.h:608
Int(ulint n)
Definition: ttmathint.h:957
uint FromString(const std::string &s, uint b=10)
Definition: ttmathint.h:1472
Int< value_size > & operator=(const std::string &s)
Definition: ttmathint.h:1529
Int< value_size > & operator=(const std::wstring &s)
Definition: ttmathint.h:1516
uint SubInt(uint value, uint index=0)
Definition: ttmathint.h:314
uint64_t ulint
Definition: ttmathtypes.h:200
~Int()
Definition: ttmathint.h:1121
uint ToInt(slint &result) const
Definition: ttmathint.h:1220
uint table[value_size]
Definition: ttmathuint.h:81
uint MulInt(uint ss2)
Definition: ttmathuint.h:835
Int(uint i)
Definition: ttmathint.h:862
uint ToUInt(uint &result) const
Definition: ttmathint.h:1142
friend std::istream & operator>>(std::istream &s, Int< value_size > &l)
Definition: ttmathint.h:1901
uint Div(Int< value_size > ss2, Int< value_size > *remainder=0)
Definition: ttmathint.h:480
unsigned int uint
Definition: ttmathtypes.h:186
Int< value_size > & operator=(const wchar_t *s)
Definition: ttmathint.h:1505
void SetMin()
Definition: ttmathint.h:82
uint AddOne()
Definition: ttmathint.h:327
void ToString(std::wstring &result, uint b=10) const
Definition: ttmathint.h:1355
UInt< value_size > operator++(int)
Definition: ttmathint.h:1778
uint ToUInt() const
Definition: ttmathuint.h:3103
uint DivInt(sint ss2, sint *remainder=0)
Definition: ttmathint.h:524
uint FromUInt(const UInt< argument_size > &p)
Definition: ttmathint.h:724
bool IsTheHighestBitSet() const
Definition: ttmathuint.h:2547
bool IsSign() const
Definition: ttmathint.h:156
Int(const wchar_t *s)
Definition: ttmathint.h:1091
uint Add(const Int< value_size > &ss2)
Definition: ttmathint.h:220
uint ToInt(uint &result) const
Definition: ttmathint.h:1157
uint FromInt(uint value)
Definition: ttmathint.h:762