Library for big numbers from http://www.ttmath.org/
Dependents: PIDHeater82 Conceptcontroller_v_1_0 AlarmClockApp COG4050_adxl355_tilt ... more
ttmathint.h
00001 /* 00002 * This file is a part of TTMath Bignum Library 00003 * and is distributed under the (new) BSD licence. 00004 * Author: Tomasz Sowa <t.sowa@ttmath.org> 00005 */ 00006 00007 /* 00008 * Copyright (c) 2006-2011, Tomasz Sowa 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without 00012 * modification, are permitted provided that the following conditions are met: 00013 * 00014 * * Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 00017 * * Redistributions in binary form must reproduce the above copyright 00018 * notice, this list of conditions and the following disclaimer in the 00019 * documentation and/or other materials provided with the distribution. 00020 * 00021 * * Neither the name Tomasz Sowa nor the names of contributors to this 00022 * project may be used to endorse or promote products derived 00023 * from this software without specific prior written permission. 00024 * 00025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00028 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00029 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00030 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00031 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00032 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00033 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00034 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00035 * THE POSSIBILITY OF SUCH DAMAGE. 00036 */ 00037 00038 00039 00040 #ifndef headerfilettmathint 00041 #define headerfilettmathint 00042 00043 /*! 00044 \file ttmathint.h 00045 \brief template class Int<uint> 00046 */ 00047 00048 #include "ttmathuint.h" 00049 00050 namespace ttmath 00051 { 00052 00053 00054 /*! 00055 \brief Int implements a big integer value with a sign 00056 00057 value_size - how many bytes specify our value 00058 on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits 00059 on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits 00060 value_size = 1,2,3,4,5,6.... 00061 */ 00062 template<uint value_size> 00063 class Int : public UInt<value_size> 00064 { 00065 public: 00066 00067 /*! 00068 this method sets the max value which this class can hold 00069 (all bits will be one besides the last one) 00070 */ 00071 void SetMax () 00072 { 00073 UInt<value_size>::SetMax (); 00074 UInt<value_size>::table[value_size-1] = ~ TTMATH_UINT_HIGHEST_BIT; 00075 } 00076 00077 00078 /*! 00079 this method sets the min value which this class can hold 00080 (all bits will be zero besides the last one which is one) 00081 */ 00082 void SetMin () 00083 { 00084 UInt<value_size>::SetZero (); 00085 UInt<value_size>::table[value_size-1] = TTMATH_UINT_HIGHEST_BIT; 00086 } 00087 00088 00089 /*! 00090 this method sets -1 as the value 00091 (-1 is equal the max value in an unsigned type) 00092 */ 00093 void SetSignOne () 00094 { 00095 UInt<value_size>::SetMax (); 00096 } 00097 00098 00099 /*! 00100 we change the sign of the value 00101 00102 if it isn't possible to change the sign this method returns 1 00103 else return 0 and changing the sign 00104 */ 00105 uint ChangeSign () 00106 { 00107 /* 00108 if the value is equal that one which has been returned from SetMin 00109 (only the highest bit is set) that means we can't change sign 00110 because the value is too big (bigger about one) 00111 00112 e.g. when value_size = 1 and value is -2147483648 we can't change it to the 00113 2147483648 because the max value which can be held is 2147483647 00114 00115 we don't change the value and we're using this fact somewhere in some methods 00116 (if we look on our value without the sign we get the correct value 00117 eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type) 00118 */ 00119 if( UInt<value_size>::IsOnlyTheHighestBitSet() ) 00120 return 1; 00121 00122 UInt<value_size> temp(*this); 00123 UInt<value_size>::SetZero (); 00124 UInt<value_size>::Sub (temp); 00125 00126 return 0; 00127 } 00128 00129 00130 00131 /*! 00132 this method sets the sign 00133 00134 e.g. 1 -> -1 00135 -2 -> -2 00136 00137 from a positive value we make a negative value, 00138 if the value is negative we do nothing 00139 */ 00140 void SetSign () 00141 { 00142 if( IsSign () ) 00143 return; 00144 00145 ChangeSign (); 00146 } 00147 00148 00149 00150 /*! 00151 this method returns true if there's the sign 00152 00153 (the highest bit will be converted to the bool) 00154 */ 00155 bool IsSign () const 00156 { 00157 return UInt<value_size>::IsTheHighestBitSet (); 00158 } 00159 00160 00161 00162 /*! 00163 it sets an absolute value 00164 00165 it can return carry (1) (look on ChangeSign() for details) 00166 */ 00167 uint Abs () 00168 { 00169 if( !IsSign () ) 00170 return 0; 00171 00172 return ChangeSign (); 00173 } 00174 00175 00176 00177 00178 /*! 00179 * 00180 * basic mathematic functions 00181 * 00182 */ 00183 00184 private: 00185 00186 uint CorrectCarryAfterAdding(bool p1_is_sign, bool p2_is_sign) 00187 { 00188 if( !p1_is_sign && !p2_is_sign ) 00189 { 00190 if( UInt<value_size>::IsTheHighestBitSet() ) 00191 return 1; 00192 } 00193 00194 if( p1_is_sign && p2_is_sign ) 00195 { 00196 if( ! UInt<value_size>::IsTheHighestBitSet() ) 00197 return 1; 00198 } 00199 00200 return 0; 00201 } 00202 00203 00204 public: 00205 00206 /*! 00207 this method adds two value with a sign and returns a carry 00208 00209 we're using methods from the base class because values are stored with U2 00210 we must only make the carry correction 00211 00212 this = p1(=this) + p2 00213 00214 when p1>=0 i p2>=0 carry is set when the highest bit of value is set 00215 when p1<0 i p2<0 carry is set when the highest bit of value is clear 00216 when p1>=0 i p2<0 carry will never be set 00217 when p1<0 i p2>=0 carry will never be set 00218 */ 00219 uint Add (const Int<value_size> & ss2) 00220 { 00221 bool p1_is_sign = IsSign (); 00222 bool p2_is_sign = ss2.IsSign (); 00223 00224 UInt<value_size>::Add (ss2); 00225 00226 return CorrectCarryAfterAdding(p1_is_sign, p2_is_sign); 00227 } 00228 00229 00230 /*! 00231 this method adds one *unsigned* word (at a specific position) 00232 and returns a carry (if it was) 00233 00234 look at a description in UInt<>::AddInt(...) 00235 */ 00236 uint AddInt (uint value, uint index = 0) 00237 { 00238 bool p1_is_sign = IsSign (); 00239 00240 UInt<value_size>::AddInt (value, index); 00241 00242 return CorrectCarryAfterAdding(p1_is_sign, false); 00243 } 00244 00245 00246 /*! 00247 this method adds two *unsigned* words to the existing value 00248 and these words begin on the 'index' position 00249 00250 index should be equal or smaller than value_size-2 (index <= value_size-2) 00251 x1 - lower word, x2 - higher word 00252 00253 look at a description in UInt<>::AddTwoInts(...) 00254 */ 00255 uint AddTwoInts (uint x2, uint x1, uint index) 00256 { 00257 bool p1_is_sign = IsSign (); 00258 00259 UInt<value_size>::AddTwoInts (x2, x1, index); 00260 00261 return CorrectCarryAfterAdding(p1_is_sign, false); 00262 } 00263 00264 private: 00265 00266 uint CorrectCarryAfterSubtracting(bool p1_is_sign, bool p2_is_sign) 00267 { 00268 if( !p1_is_sign && p2_is_sign ) 00269 { 00270 if( UInt<value_size>::IsTheHighestBitSet() ) 00271 return 1; 00272 } 00273 00274 if( p1_is_sign && !p2_is_sign ) 00275 { 00276 if( ! UInt<value_size>::IsTheHighestBitSet() ) 00277 return 1; 00278 } 00279 00280 return 0; 00281 } 00282 00283 public: 00284 00285 /*! 00286 this method subtracts two values with a sign 00287 00288 we don't use the previous Add because the method ChangeSign can 00289 sometimes return carry 00290 00291 this = p1(=this) - p2 00292 00293 when p1>=0 i p2>=0 carry will never be set 00294 when p1<0 i p2<0 carry will never be set 00295 when p1>=0 i p2<0 carry is set when the highest bit of value is set 00296 when p1<0 i p2>=0 carry is set when the highest bit of value is clear 00297 */ 00298 uint Sub (const Int<value_size> & ss2) 00299 { 00300 bool p1_is_sign = IsSign (); 00301 bool p2_is_sign = ss2.IsSign (); 00302 00303 UInt<value_size>::Sub (ss2); 00304 00305 return CorrectCarryAfterSubtracting(p1_is_sign, p2_is_sign); 00306 } 00307 00308 00309 /*! 00310 this method subtracts one *unsigned* word (at a specific position) 00311 and returns a carry (if it was) 00312 */ 00313 uint SubInt (uint value, uint index = 0) 00314 { 00315 bool p1_is_sign = IsSign (); 00316 00317 UInt<value_size>::SubInt (value, index); 00318 00319 return CorrectCarryAfterSubtracting(p1_is_sign, false); 00320 } 00321 00322 00323 /*! 00324 this method adds one to the value and returns carry 00325 */ 00326 uint AddOne () 00327 { 00328 bool p1_is_sign = IsSign (); 00329 00330 UInt<value_size>::AddOne (); 00331 00332 return CorrectCarryAfterAdding(p1_is_sign, false); 00333 } 00334 00335 00336 /*! 00337 this method subtracts one from the value and returns carry 00338 */ 00339 uint SubOne () 00340 { 00341 bool p1_is_sign = IsSign (); 00342 00343 UInt<value_size>::SubOne (); 00344 00345 return CorrectCarryAfterSubtracting(p1_is_sign, false); 00346 } 00347 00348 00349 private: 00350 00351 00352 uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign) 00353 { 00354 /* 00355 we have to examine the sign of the result now 00356 but if the result is with the sign then: 00357 1. if the signs were the same that means the result is too big 00358 (the result must be without a sign) 00359 2. if the signs were different that means if the result 00360 is different from that one which has been returned from SetMin() 00361 that is carry (result too big) but if the result is equal SetMin() 00362 there'll be ok (and the next SetSign will has no effect because 00363 the value is actually negative -- look at description of that case 00364 in ChangeSign()) 00365 */ 00366 if( IsSign () ) 00367 { 00368 if( ss1_is_sign != ss2_is_sign ) 00369 { 00370 /* 00371 there can be one case where signs are different and 00372 the result will be equal the value from SetMin() (only the highest bit is set) 00373 (this situation is ok) 00374 */ 00375 if( !UInt<value_size>::IsOnlyTheHighestBitSet() ) 00376 return 1; 00377 } 00378 else 00379 { 00380 // signs were the same 00381 return 1; 00382 } 00383 } 00384 00385 return 0; 00386 } 00387 00388 00389 public: 00390 00391 00392 /*! 00393 multiplication: this = this * ss2 00394 00395 it can return a carry 00396 */ 00397 uint MulInt (sint ss2) 00398 { 00399 bool ss1_is_sign, ss2_is_sign; 00400 uint c; 00401 00402 ss1_is_sign = IsSign (); 00403 00404 /* 00405 we don't have to check the carry from Abs (values will be correct 00406 because next we're using the method MulInt from the base class UInt 00407 which is without a sign) 00408 */ 00409 Abs (); 00410 00411 if( ss2 < 0 ) 00412 { 00413 ss2 = -ss2; 00414 ss2_is_sign = true; 00415 } 00416 else 00417 { 00418 ss2_is_sign = false; 00419 } 00420 00421 c = UInt<value_size>::MulInt ((uint )ss2); 00422 c += CheckMinCarry(ss1_is_sign, ss2_is_sign); 00423 00424 if( ss1_is_sign != ss2_is_sign ) 00425 SetSign (); 00426 00427 return c; 00428 } 00429 00430 00431 00432 /*! 00433 multiplication this = this * ss2 00434 00435 it returns carry if the result is too big 00436 (we're using the method from the base class but we have to make 00437 one correction in account of signs) 00438 */ 00439 uint Mul (Int<value_size> ss2) 00440 { 00441 bool ss1_is_sign, ss2_is_sign; 00442 uint c; 00443 00444 ss1_is_sign = IsSign (); 00445 ss2_is_sign = ss2.IsSign (); 00446 00447 /* 00448 we don't have to check the carry from Abs (values will be correct 00449 because next we're using the method Mul from the base class UInt 00450 which is without a sign) 00451 */ 00452 Abs (); 00453 ss2.Abs (); 00454 00455 c = UInt<value_size>::Mul (ss2); 00456 c += CheckMinCarry(ss1_is_sign, ss2_is_sign); 00457 00458 if( ss1_is_sign != ss2_is_sign ) 00459 SetSign (); 00460 00461 return c; 00462 } 00463 00464 00465 /*! 00466 division this = this / ss2 00467 returned values: 00468 0 - ok 00469 1 - division by zero 00470 00471 for example: (result means 'this') 00472 20 / 3 --> result: 6 remainder: 2 00473 -20 / 3 --> result: -6 remainder: -2 00474 20 / -3 --> result: -6 remainder: 2 00475 -20 / -3 --> result: 6 remainder: -2 00476 00477 in other words: this(old) = ss2 * this(new)(result) + remainder 00478 */ 00479 uint Div (Int<value_size> ss2, Int<value_size> * remainder = 0) 00480 { 00481 bool ss1_is_sign, ss2_is_sign; 00482 00483 ss1_is_sign = IsSign (); 00484 ss2_is_sign = ss2.IsSign (); 00485 00486 /* 00487 we don't have to test the carry from Abs as well as in Mul 00488 */ 00489 Abs (); 00490 ss2.Abs (); 00491 00492 uint c = UInt<value_size>::Div (ss2, remainder); 00493 00494 if( ss1_is_sign != ss2_is_sign ) 00495 SetSign (); 00496 00497 if( ss1_is_sign && remainder ) 00498 remainder->SetSign(); 00499 00500 return c; 00501 } 00502 00503 uint Div (const Int<value_size> & ss2, Int<value_size> & remainder) 00504 { 00505 return Div (ss2, &remainder); 00506 } 00507 00508 00509 /*! 00510 division this = this / ss2 (ss2 is int) 00511 returned values: 00512 0 - ok 00513 1 - division by zero 00514 00515 for example: (result means 'this') 00516 20 / 3 --> result: 6 remainder: 2 00517 -20 / 3 --> result: -6 remainder: -2 00518 20 / -3 --> result: -6 remainder: 2 00519 -20 / -3 --> result: 6 remainder: -2 00520 00521 in other words: this(old) = ss2 * this(new)(result) + remainder 00522 */ 00523 uint DivInt (sint ss2, sint * remainder = 0) 00524 { 00525 bool ss1_is_sign, ss2_is_sign; 00526 00527 ss1_is_sign = IsSign (); 00528 00529 /* 00530 we don't have to test the carry from Abs as well as in Mul 00531 */ 00532 Abs (); 00533 00534 if( ss2 < 0 ) 00535 { 00536 ss2 = -ss2; 00537 ss2_is_sign = true; 00538 } 00539 else 00540 { 00541 ss2_is_sign = false; 00542 } 00543 00544 uint rem; 00545 uint c = UInt<value_size>::DivInt ((uint )ss2, &rem); 00546 00547 if( ss1_is_sign != ss2_is_sign ) 00548 SetSign (); 00549 00550 if( remainder ) 00551 { 00552 if( ss1_is_sign ) 00553 *remainder = -sint(rem); 00554 else 00555 *remainder = sint(rem); 00556 } 00557 00558 return c; 00559 } 00560 00561 00562 uint DivInt (sint ss2, sint & remainder) 00563 { 00564 return DivInt (ss2, &remainder); 00565 } 00566 00567 00568 private: 00569 00570 00571 /*! 00572 power this = this ^ pow 00573 this can be negative 00574 pow is >= 0 00575 */ 00576 uint Pow2(const Int<value_size> & pow) 00577 { 00578 bool was_sign = IsSign (); 00579 uint c = 0; 00580 00581 if( was_sign ) 00582 c += Abs (); 00583 00584 uint c_temp = UInt<value_size>::Pow (pow); 00585 if( c_temp > 0 ) 00586 return c_temp; // c_temp can be: 0, 1 or 2 00587 00588 if( was_sign && (pow.table[0] & 1) == 1 ) 00589 // negative value to the power of odd number is negative 00590 c += ChangeSign (); 00591 00592 return (c==0)? 0 : 1; 00593 } 00594 00595 00596 public: 00597 00598 00599 /*! 00600 power this = this ^ pow 00601 00602 return values: 00603 0 - ok 00604 1 - carry 00605 2 - incorrect arguments 0^0 or 0^(-something) 00606 */ 00607 uint Pow (Int<value_size> pow) 00608 { 00609 if( !pow.IsSign () ) 00610 return Pow2(pow); 00611 00612 if( UInt<value_size>::IsZero() ) 00613 // if 'pow' is negative then 00614 // 'this' must be different from zero 00615 return 2; 00616 00617 if( pow.ChangeSign () ) 00618 return 1; 00619 00620 Int<value_size> t(*this); 00621 uint c_temp = t.Pow2(pow); 00622 if( c_temp > 0 ) 00623 return c_temp; 00624 00625 UInt<value_size>::SetOne (); 00626 if( Div (t) ) 00627 return 1; 00628 00629 return 0; 00630 } 00631 00632 00633 00634 /*! 00635 * 00636 * convertion methods 00637 * 00638 */ 00639 private: 00640 00641 00642 /*! 00643 an auxiliary method for converting both from UInt and Int 00644 */ 00645 template<uint argument_size> 00646 uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type) 00647 { 00648 uint min_size = (value_size < argument_size)? value_size : argument_size; 00649 uint i; 00650 00651 for(i=0 ; i<min_size ; ++i) 00652 UInt<value_size>::table[i] = p.table [i]; 00653 00654 00655 if( value_size > argument_size ) 00656 { 00657 uint fill; 00658 00659 if( UInt_type ) 00660 fill = 0; 00661 else 00662 fill = (p.table [argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? 00663 TTMATH_UINT_MAX_VALUE : 0; 00664 00665 // 'this' is longer than 'p' 00666 for( ; i<value_size ; ++i) 00667 UInt<value_size>::table[i] = fill; 00668 } 00669 else 00670 { 00671 uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? 00672 TTMATH_UINT_MAX_VALUE : 0; 00673 00674 if( UInt_type && test!=0 ) 00675 return 1; 00676 00677 for( ; i<argument_size ; ++i) 00678 if( p.table [i] != test ) 00679 return 1; 00680 } 00681 00682 return 0; 00683 } 00684 00685 public: 00686 00687 /*! 00688 this method converts an Int<another_size> type into this class 00689 00690 this operation has mainly sense if the value from p 00691 can be held in this type 00692 00693 it returns a carry if the value 'p' is too big 00694 */ 00695 template<uint argument_size> 00696 uint FromInt (const Int<argument_size> & p) 00697 { 00698 return FromUIntOrInt(p, false); 00699 } 00700 00701 00702 /*! 00703 this method converts the sint type into this class 00704 */ 00705 uint FromInt (sint value) 00706 { 00707 uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0; 00708 00709 for(uint i=1 ; i<value_size ; ++i) 00710 UInt<value_size>::table[i] = fill; 00711 00712 UInt<value_size>::table[0] = uint (value); 00713 00714 // there'll never be a carry here 00715 return 0; 00716 } 00717 00718 00719 /*! 00720 this method converts UInt<another_size> into this class 00721 */ 00722 template<uint argument_size> 00723 uint FromUInt (const UInt<argument_size> & p) 00724 { 00725 return FromUIntOrInt(p, true); 00726 } 00727 00728 00729 /*! 00730 this method converts UInt<another_size> into this class 00731 */ 00732 template<uint argument_size> 00733 uint FromInt (const UInt<argument_size> & p) 00734 { 00735 return FromUIntOrInt(p, true); 00736 } 00737 00738 00739 /*! 00740 this method converts the uint type into this class 00741 */ 00742 uint FromUInt (uint value) 00743 { 00744 for(uint i=1 ; i<value_size ; ++i) 00745 UInt<value_size>::table[i] = 0; 00746 00747 UInt<value_size>::table[0] = value; 00748 00749 // there can be a carry here when the size of this value is equal one word 00750 // and the 'value' has the highest bit set 00751 if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 ) 00752 return 1; 00753 00754 return 0; 00755 } 00756 00757 00758 /*! 00759 this method converts the uint type into this class 00760 */ 00761 uint FromInt (uint value) 00762 { 00763 return FromUInt (value); 00764 } 00765 00766 00767 /*! 00768 the default assignment operator 00769 */ 00770 Int<value_size> & operator= (const Int<value_size> & p) 00771 { 00772 FromInt (p); 00773 00774 return *this; 00775 } 00776 00777 00778 /*! 00779 this operator converts an Int<another_size> type to this class 00780 00781 it doesn't return a carry 00782 */ 00783 template<uint argument_size> 00784 Int<value_size> & operator= (const Int<argument_size> & p) 00785 { 00786 FromInt (p); 00787 00788 return *this; 00789 } 00790 00791 00792 /*! 00793 this method converts the sint type to this class 00794 */ 00795 Int<value_size> & operator= (sint i) 00796 { 00797 FromInt (i); 00798 00799 return *this; 00800 } 00801 00802 00803 /*! 00804 a constructor for converting the uint to this class 00805 */ 00806 Int (sint i) 00807 { 00808 FromInt (i); 00809 } 00810 00811 00812 /*! 00813 a copy constructor 00814 */ 00815 Int (const Int<value_size> & u) 00816 { 00817 FromInt (u); 00818 } 00819 00820 00821 /*! 00822 a constructor for copying from another types 00823 */ 00824 template<uint argument_size> 00825 Int (const Int<argument_size> & u) 00826 { 00827 // look that 'size' we still set as 'value_size' and not as u.value_size 00828 FromInt (u); 00829 } 00830 00831 00832 00833 /*! 00834 this operator converts an UInt<another_size> type to this class 00835 00836 it doesn't return a carry 00837 */ 00838 template<uint argument_size> 00839 Int<value_size> & operator= (const UInt<argument_size> & p) 00840 { 00841 FromUInt (p); 00842 00843 return *this; 00844 } 00845 00846 00847 /*! 00848 this method converts the Uint type to this class 00849 */ 00850 Int<value_size> & operator= (uint i) 00851 { 00852 FromUInt (i); 00853 00854 return *this; 00855 } 00856 00857 00858 /*! 00859 a constructor for converting the uint to this class 00860 */ 00861 Int (uint i) 00862 { 00863 FromUInt (i); 00864 } 00865 00866 00867 /*! 00868 a constructor for copying from another types 00869 */ 00870 template<uint argument_size> 00871 Int (const UInt<argument_size> & u) 00872 { 00873 // look that 'size' we still set as 'value_size' and not as u.value_size 00874 FromUInt (u); 00875 } 00876 00877 00878 00879 #ifdef TTMATH_PLATFORM32 00880 00881 00882 /*! 00883 this method converts unsigned 64 bit int type to this class 00884 ***this method is created only on a 32bit platform*** 00885 */ 00886 uint FromUInt (ulint n) 00887 { 00888 uint c = UInt<value_size>::FromUInt (n); 00889 00890 if( c ) 00891 return 1; 00892 00893 if( value_size == 1 ) 00894 return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1; 00895 00896 if( value_size == 2 ) 00897 return ((UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1; 00898 00899 return 0; 00900 } 00901 00902 00903 /*! 00904 this method converts unsigned 64 bit int type to this class 00905 ***this method is created only on a 32bit platform*** 00906 */ 00907 uint FromInt (ulint n) 00908 { 00909 return FromUInt (n); 00910 } 00911 00912 00913 /*! 00914 this method converts signed 64 bit int type to this class 00915 ***this method is created only on a 32bit platform*** 00916 */ 00917 uint FromInt (slint n) 00918 { 00919 uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0; 00920 00921 UInt<value_size>::table[0] = (uint )(ulint )n; 00922 00923 if( value_size == 1 ) 00924 { 00925 if( uint (ulint (n) >> 32) != mask ) 00926 return 1; 00927 00928 return ((UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1; 00929 } 00930 00931 UInt<value_size>::table[1] = (uint )(ulint (n) >> 32); 00932 00933 for(uint i=2 ; i<value_size ; ++i) 00934 UInt<value_size>::table[i] = mask; 00935 00936 return 0; 00937 } 00938 00939 00940 /*! 00941 this operator converts unsigned 64 bit int type to this class 00942 ***this operator is created only on a 32bit platform*** 00943 */ 00944 Int<value_size> & operator= (ulint n) 00945 { 00946 FromUInt (n); 00947 00948 return *this; 00949 } 00950 00951 00952 /*! 00953 a constructor for converting unsigned 64 bit int to this class 00954 ***this constructor is created only on a 32bit platform*** 00955 */ 00956 Int (ulint n) 00957 { 00958 FromUInt (n); 00959 } 00960 00961 00962 /*! 00963 this operator converts signed 64 bit int type to this class 00964 ***this operator is created only on a 32bit platform*** 00965 */ 00966 Int<value_size> & operator= (slint n) 00967 { 00968 FromInt (n); 00969 00970 return *this; 00971 } 00972 00973 00974 /*! 00975 a constructor for converting signed 64 bit int to this class 00976 ***this constructor is created only on a 32bit platform*** 00977 */ 00978 Int (slint n) 00979 { 00980 FromInt (n); 00981 } 00982 00983 #endif 00984 00985 00986 00987 00988 #ifdef TTMATH_PLATFORM64 00989 00990 /*! 00991 this method converts 32 bit unsigned int type to this class 00992 ***this operator is created only on a 64bit platform*** 00993 */ 00994 uint FromUInt (unsigned int i) 00995 { 00996 return FromUInt (uint (i)); 00997 } 00998 00999 01000 /*! 01001 this method converts 32 bit unsigned int type to this class 01002 ***this operator is created only on a 64bit platform*** 01003 */ 01004 uint FromInt (unsigned int i) 01005 { 01006 return FromUInt (i); 01007 } 01008 01009 01010 /*! 01011 this method converts 32 bit signed int type to this class 01012 ***this operator is created only on a 64bit platform*** 01013 */ 01014 uint FromInt (signed int i) 01015 { 01016 return FromInt (sint(i)); 01017 } 01018 01019 01020 /*! 01021 this method converts 32 bit unsigned int type to this class 01022 ***this operator is created only on a 64bit platform*** 01023 */ 01024 Int<value_size> & operator= (unsigned int i) 01025 { 01026 FromUInt (i); 01027 01028 return *this; 01029 } 01030 01031 01032 /*! 01033 a constructor for converting 32 bit unsigned int to this class 01034 ***this constructor is created only on a 64bit platform*** 01035 */ 01036 Int (unsigned int i) 01037 { 01038 FromUInt (i); 01039 } 01040 01041 01042 /*! 01043 this operator converts 32 bit signed int type to this class 01044 ***this operator is created only on a 64bit platform*** 01045 */ 01046 Int<value_size> & operator= (signed int i) 01047 { 01048 FromInt (i); 01049 01050 return *this; 01051 } 01052 01053 01054 /*! 01055 a constructor for converting 32 bit signed int to this class 01056 ***this constructor is created only on a 64bit platform*** 01057 */ 01058 Int (signed int i) 01059 { 01060 FromInt (i); 01061 } 01062 01063 #endif 01064 01065 01066 01067 /*! 01068 a constructor for converting string to this class (with the base=10) 01069 */ 01070 Int (const char * s) 01071 { 01072 FromString (s); 01073 } 01074 01075 01076 /*! 01077 a constructor for converting a string to this class (with the base=10) 01078 */ 01079 Int (const std::string & s) 01080 { 01081 FromString ( s.c_str() ); 01082 } 01083 01084 01085 #ifndef TTMATH_DONT_USE_WCHAR 01086 01087 /*! 01088 a constructor for converting string to this class (with the base=10) 01089 */ 01090 Int (const wchar_t * s) 01091 { 01092 FromString (s); 01093 } 01094 01095 01096 /*! 01097 a constructor for converting a string to this class (with the base=10) 01098 */ 01099 Int (const std::wstring & s) 01100 { 01101 FromString ( s.c_str() ); 01102 } 01103 01104 #endif 01105 01106 01107 /*! 01108 a default constructor 01109 01110 we don't clear table etc. 01111 */ 01112 Int () 01113 { 01114 } 01115 01116 01117 /*! 01118 the destructor 01119 */ 01120 ~Int () 01121 { 01122 } 01123 01124 01125 /*! 01126 this method returns the lowest value from table with a sign 01127 01128 we must be sure when we using this method whether the value 01129 will hold in an sint type or not (the rest value from table must be zero or -1) 01130 */ 01131 sint ToInt () const 01132 { 01133 return sint( UInt<value_size>::table[0] ); 01134 } 01135 01136 01137 /*! 01138 this method converts the value to uint type 01139 can return a carry if the value is too long to store it in uint type 01140 */ 01141 uint ToUInt (uint & result) const 01142 { 01143 uint c = UInt<value_size>::ToUInt (result); 01144 01145 if( value_size == 1 ) 01146 return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1; 01147 01148 return c; 01149 } 01150 01151 01152 /*! 01153 this method converts the value to uint type 01154 can return a carry if the value is too long to store it in uint type 01155 */ 01156 uint ToInt (uint & result) const 01157 { 01158 return ToUInt (result); 01159 } 01160 01161 01162 /*! 01163 this method converts the value to sint type 01164 can return a carry if the value is too long to store it in sint type 01165 */ 01166 uint ToInt (sint & result) const 01167 { 01168 result = sint( UInt<value_size>::table[0] ); 01169 uint mask = IsSign () ? TTMATH_UINT_MAX_VALUE : 0; 01170 01171 if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) ) 01172 return 1; 01173 01174 for(uint i=1 ; i<value_size ; ++i) 01175 if( UInt<value_size>::table[i] != mask ) 01176 return 1; 01177 01178 return 0; 01179 } 01180 01181 01182 #ifdef TTMATH_PLATFORM32 01183 01184 /*! 01185 this method converts the value to ulint type (64 bit unsigned integer) 01186 can return a carry if the value is too long to store it in ulint type 01187 *** this method is created only on a 32 bit platform *** 01188 */ 01189 uint ToUInt (ulint & result) const 01190 { 01191 uint c = UInt<value_size>::ToUInt (result); 01192 01193 if( value_size == 1 ) 01194 return (UInt<value_size>::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1; 01195 01196 if( value_size == 2 ) 01197 return (UInt<value_size>::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1; 01198 01199 return c; 01200 } 01201 01202 01203 /*! 01204 this method converts the value to ulint type (64 bit unsigned integer) 01205 can return a carry if the value is too long to store it in ulint type 01206 *** this method is created only on a 32 bit platform *** 01207 */ 01208 uint ToInt (ulint & result) const 01209 { 01210 return ToUInt (result); 01211 } 01212 01213 01214 /*! 01215 this method converts the value to slint type (64 bit signed integer) 01216 can return a carry if the value is too long to store it in slint type 01217 *** this method is created only on a 32 bit platform *** 01218 */ 01219 uint ToInt (slint & result) const 01220 { 01221 if( value_size == 1 ) 01222 { 01223 result = slint(sint(UInt<value_size>::table[0])); 01224 } 01225 else 01226 { 01227 uint low = UInt<value_size>::table[0]; 01228 uint high = UInt<value_size>::table[1]; 01229 01230 result = low; 01231 result |= (ulint (high) << TTMATH_BITS_PER_UINT); 01232 01233 uint mask = IsSign () ? TTMATH_UINT_MAX_VALUE : 0; 01234 01235 if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) ) 01236 return 1; 01237 01238 for(uint i=2 ; i<value_size ; ++i) 01239 if( UInt<value_size>::table[i] != mask ) 01240 return 1; 01241 } 01242 01243 return 0; 01244 } 01245 01246 #endif 01247 01248 01249 01250 #ifdef TTMATH_PLATFORM64 01251 01252 /*! 01253 this method converts the value to a 32 bit unsigned integer 01254 can return a carry if the value is too long to store it in this type 01255 *** this method is created only on a 64 bit platform *** 01256 */ 01257 uint ToUInt (unsigned int & result) const 01258 { 01259 uint c = UInt<value_size>::ToUInt (result); 01260 01261 if( c || IsSign () ) 01262 return 1; 01263 01264 return 0; 01265 } 01266 01267 01268 /*! 01269 this method converts the value to a 32 bit unsigned integer 01270 can return a carry if the value is too long to store it in this type 01271 *** this method is created only on a 64 bit platform *** 01272 */ 01273 uint ToInt (unsigned int & result) const 01274 { 01275 return ToUInt (result); 01276 } 01277 01278 01279 /*! 01280 this method converts the value to a 32 bit signed integer 01281 can return a carry if the value is too long to store it in this type 01282 *** this method is created only on a 64 bit platform *** 01283 */ 01284 uint ToInt (int & result) const 01285 { 01286 uint first = UInt<value_size>::table[0]; 01287 01288 result = int(first); 01289 uint mask = IsSign () ? TTMATH_UINT_MAX_VALUE : 0; 01290 01291 if( (first >> 31) != (mask >> 31) ) 01292 return 1; 01293 01294 for(uint i=1 ; i<value_size ; ++i) 01295 if( UInt<value_size>::table[i] != mask ) 01296 return 1; 01297 01298 return 0; 01299 } 01300 01301 #endif 01302 01303 01304 01305 01306 private: 01307 01308 /*! 01309 an auxiliary method for converting to a string 01310 */ 01311 template<class string_type> 01312 void ToStringBase(string_type & result, uint b = 10) const 01313 { 01314 if( IsSign () ) 01315 { 01316 Int<value_size> temp(*this); 01317 temp.Abs(); 01318 temp.UInt<value_size>::ToStringBase(result, b, true); 01319 } 01320 else 01321 { 01322 UInt<value_size>::ToStringBase(result, b, false); 01323 } 01324 } 01325 01326 public: 01327 01328 /*! 01329 this method converts the value to a string with a base equal 'b' 01330 */ 01331 void ToString (std::string & result, uint b = 10) const 01332 { 01333 return ToStringBase(result, b); 01334 } 01335 01336 01337 /*! 01338 this method converts the value to a string with a base equal 'b' 01339 */ 01340 std::string ToString (uint b = 10) const 01341 { 01342 std::string result; 01343 ToStringBase(result, b); 01344 01345 return result; 01346 } 01347 01348 01349 #ifndef TTMATH_DONT_USE_WCHAR 01350 01351 /*! 01352 this method converts the value to a string with a base equal 'b' 01353 */ 01354 void ToString (std::wstring & result, uint b = 10) const 01355 { 01356 return ToStringBase(result, b); 01357 } 01358 01359 01360 /*! 01361 this method converts the value to a string with a base equal 'b' 01362 */ 01363 std::wstring ToWString (uint b = 10) const 01364 { 01365 std::wstring result; 01366 ToStringBase(result, b); 01367 01368 return result; 01369 } 01370 01371 #endif 01372 01373 01374 01375 private: 01376 01377 /*! 01378 an auxiliary method for converting from a string 01379 */ 01380 template<class char_type> 01381 uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0) 01382 { 01383 bool is_sign = false; 01384 01385 Misc::SkipWhiteCharacters(s); 01386 01387 if( *s == '-' ) 01388 { 01389 is_sign = true; 01390 Misc::SkipWhiteCharacters(++s); 01391 } 01392 else 01393 if( *s == '+' ) 01394 { 01395 Misc::SkipWhiteCharacters(++s); 01396 } 01397 01398 if( UInt<value_size>::FromString(s,b,after_source,value_read) ) 01399 return 1; 01400 01401 if( is_sign ) 01402 { 01403 Int<value_size> mmin; 01404 01405 mmin.SetMin(); 01406 01407 /* 01408 the reference to mmin will be automatically converted to the reference 01409 to UInt type 01410 (this value can be equal mmin -- look at a description in ChangeSign()) 01411 */ 01412 if( UInt<value_size>::operator>( mmin ) ) 01413 return 1; 01414 01415 /* 01416 if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it) 01417 */ 01418 ChangeSign (); 01419 } 01420 else 01421 { 01422 Int<value_size> mmax; 01423 01424 mmax.SetMax(); 01425 01426 if( UInt<value_size>::operator>( mmax ) ) 01427 return 1; 01428 } 01429 01430 return 0; 01431 } 01432 01433 01434 public: 01435 01436 /*! 01437 this method converts a string into its value 01438 it returns carry=1 if the value will be too big or an incorrect base 'b' is given 01439 01440 string is ended with a non-digit value, for example: 01441 "-12" will be translated to -12 01442 as well as: 01443 "- 12foo" will be translated to -12 too 01444 01445 existing first white characters will be ommited 01446 (between '-' and a first digit can be white characters too) 01447 01448 after_source (if exists) is pointing at the end of the parsed string 01449 01450 value_read (if exists) tells whether something has actually been read (at least one digit) 01451 */ 01452 uint FromString (const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0) 01453 { 01454 return FromStringBase(s, b, after_source, value_read); 01455 } 01456 01457 01458 /*! 01459 this method converts a string into its value 01460 */ 01461 uint FromString (const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0) 01462 { 01463 return FromStringBase(s, b, after_source, value_read); 01464 } 01465 01466 01467 /*! 01468 this method converts a string into its value 01469 it returns carry=1 if the value will be too big or an incorrect base 'b' is given 01470 */ 01471 uint FromString (const std::string & s, uint b = 10) 01472 { 01473 return FromString ( s.c_str(), b ); 01474 } 01475 01476 01477 /*! 01478 this operator converts a string into its value (with base = 10) 01479 */ 01480 Int<value_size> & operator= (const char * s) 01481 { 01482 FromString (s); 01483 01484 return *this; 01485 } 01486 01487 01488 #ifndef TTMATH_DONT_USE_WCHAR 01489 01490 01491 /*! 01492 this method converts a string into its value 01493 it returns carry=1 if the value will be too big or an incorrect base 'b' is given 01494 */ 01495 uint FromString (const std::wstring & s, uint b = 10) 01496 { 01497 return FromString ( s.c_str(), b ); 01498 } 01499 01500 01501 /*! 01502 this operator converts a string into its value (with base = 10) 01503 */ 01504 Int<value_size> & operator= (const wchar_t * s) 01505 { 01506 FromString (s); 01507 01508 return *this; 01509 } 01510 01511 01512 /*! 01513 this operator converts a string into its value (with base = 10) 01514 */ 01515 Int<value_size> & operator= (const std::wstring & s) 01516 { 01517 FromString ( s.c_str() ); 01518 01519 return *this; 01520 } 01521 01522 #endif 01523 01524 01525 /*! 01526 this operator converts a string into its value (with base = 10) 01527 */ 01528 Int<value_size> & operator= (const std::string & s) 01529 { 01530 FromString ( s.c_str() ); 01531 01532 return *this; 01533 } 01534 01535 01536 01537 /*! 01538 * 01539 * methods for comparing 01540 * 01541 * 01542 */ 01543 01544 bool operator== (const Int<value_size> & l) const 01545 { 01546 return UInt<value_size>::operator== (l); 01547 } 01548 01549 bool operator!=(const Int<value_size> & l) const 01550 { 01551 return UInt<value_size>::operator!=(l); 01552 } 01553 01554 bool operator<(const Int<value_size> & l) const 01555 { 01556 sint i=value_size-1; 01557 01558 sint a1 = sint(UInt<value_size>::table[i]); 01559 sint a2 = sint(l.table[i]); 01560 01561 if( a1 != a2 ) 01562 return a1 < a2; 01563 01564 01565 for(--i ; i>=0 ; --i) 01566 { 01567 if( UInt<value_size>::table[i] != l.table[i] ) 01568 // comparison as unsigned int 01569 return UInt<value_size>::table[i] < l.table[i]; 01570 } 01571 01572 // they're equal 01573 return false; 01574 } 01575 01576 01577 bool operator>(const Int<value_size> & l) const 01578 { 01579 sint i=value_size-1; 01580 01581 sint a1 = sint(UInt<value_size>::table[i]); 01582 sint a2 = sint(l.table[i]); 01583 01584 if( a1 != a2 ) 01585 return a1 > a2; 01586 01587 01588 for(--i ; i>=0 ; --i) 01589 { 01590 if( UInt<value_size>::table[i] != l.table[i] ) 01591 // comparison as unsigned int 01592 return UInt<value_size>::table[i] > l.table[i]; 01593 } 01594 01595 // they're equal 01596 return false; 01597 } 01598 01599 01600 bool operator<=(const Int<value_size> & l) const 01601 { 01602 sint i=value_size-1; 01603 01604 sint a1 = sint(UInt<value_size>::table[i]); 01605 sint a2 = sint(l.table[i]); 01606 01607 if( a1 != a2 ) 01608 return a1 < a2; 01609 01610 01611 for(--i ; i>=0 ; --i) 01612 { 01613 if( UInt<value_size>::table[i] != l.table[i] ) 01614 // comparison as unsigned int 01615 return UInt<value_size>::table[i] < l.table[i]; 01616 } 01617 01618 // they're equal 01619 return true; 01620 } 01621 01622 01623 bool operator>=(const Int<value_size> & l) const 01624 { 01625 sint i=value_size-1; 01626 01627 sint a1 = sint(UInt<value_size>::table[i]); 01628 sint a2 = sint(l.table[i]); 01629 01630 if( a1 != a2 ) 01631 return a1 > a2; 01632 01633 01634 for(--i ; i>=0 ; --i) 01635 { 01636 if( UInt<value_size>::table[i] != l.table[i] ) 01637 // comparison as unsigned int 01638 return UInt<value_size>::table[i] > l.table[i]; 01639 } 01640 01641 // they're equal 01642 return true; 01643 } 01644 01645 01646 01647 /*! 01648 * 01649 * standard mathematical operators 01650 * 01651 */ 01652 01653 01654 /*! 01655 an operator for changing the sign 01656 01657 it's not changing 'this' but the changed value will be returned 01658 */ 01659 Int<value_size> operator- () const 01660 { 01661 Int<value_size> temp(*this); 01662 01663 temp.ChangeSign (); 01664 01665 return temp; 01666 } 01667 01668 01669 Int<value_size> operator- (const Int<value_size> & p2) const 01670 { 01671 Int<value_size> temp(*this); 01672 01673 temp.Sub(p2); 01674 01675 return temp; 01676 } 01677 01678 01679 Int<value_size> & operator-=(const Int<value_size> & p2) 01680 { 01681 Sub (p2); 01682 01683 return *this; 01684 } 01685 01686 01687 Int<value_size> operator+(const Int<value_size> & p2) const 01688 { 01689 Int<value_size> temp(*this); 01690 01691 temp.Add(p2); 01692 01693 return temp; 01694 } 01695 01696 01697 Int<value_size> & operator+=(const Int<value_size> & p2) 01698 { 01699 Add (p2); 01700 01701 return *this; 01702 } 01703 01704 01705 Int<value_size> operator*(const Int<value_size> & p2) const 01706 { 01707 Int<value_size> temp(*this); 01708 01709 temp.Mul(p2); 01710 01711 return temp; 01712 } 01713 01714 01715 Int<value_size> & operator*=(const Int<value_size> & p2) 01716 { 01717 Mul (p2); 01718 01719 return *this; 01720 } 01721 01722 01723 Int<value_size> operator/(const Int<value_size> & p2) const 01724 { 01725 Int<value_size> temp(*this); 01726 01727 temp.Div(p2); 01728 01729 return temp; 01730 } 01731 01732 01733 Int<value_size> & operator/=(const Int<value_size> & p2) 01734 { 01735 Div (p2); 01736 01737 return *this; 01738 } 01739 01740 01741 Int<value_size> operator%(const Int<value_size> & p2) const 01742 { 01743 Int<value_size> temp(*this); 01744 Int<value_size> remainder; 01745 01746 temp.Div(p2, remainder); 01747 01748 return remainder; 01749 } 01750 01751 01752 Int<value_size> & operator%=(const Int<value_size> & p2) 01753 { 01754 Int<value_size> remainder; 01755 01756 Div (p2, remainder); 01757 operator= (remainder); 01758 01759 return *this; 01760 } 01761 01762 01763 /*! 01764 Prefix operator e.g. ++variable 01765 */ 01766 UInt<value_size> & operator++ () 01767 { 01768 AddOne (); 01769 01770 return *this; 01771 } 01772 01773 01774 /*! 01775 Postfix operator e.g. variable++ 01776 */ 01777 UInt<value_size> operator++ (int) 01778 { 01779 UInt<value_size> temp( *this ); 01780 01781 AddOne (); 01782 01783 return temp; 01784 } 01785 01786 01787 UInt<value_size> & operator--() 01788 { 01789 SubOne (); 01790 01791 return *this; 01792 } 01793 01794 01795 UInt<value_size> operator--(int) 01796 { 01797 UInt<value_size> temp( *this ); 01798 01799 SubOne (); 01800 01801 return temp; 01802 } 01803 01804 01805 01806 /*! 01807 * 01808 * input/output operators for standard streams 01809 * 01810 */ 01811 01812 private: 01813 01814 /*! 01815 an auxiliary method for outputing to standard streams 01816 */ 01817 template<class ostream_type, class string_type> 01818 static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l) 01819 { 01820 string_type ss; 01821 01822 l.ToString(ss); 01823 s << ss; 01824 01825 return s; 01826 } 01827 01828 01829 01830 public: 01831 01832 01833 /*! 01834 output to standard streams 01835 */ 01836 friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l) 01837 { 01838 return OutputToStream<std::ostream, std::string>(s, l); 01839 } 01840 01841 01842 #ifndef TTMATH_DONT_USE_WCHAR 01843 01844 /*! 01845 output to standard streams 01846 */ 01847 friend std::wostream & operator<<(std::wostream & s, const Int<value_size> & l) 01848 { 01849 return OutputToStream<std::wostream, std::wstring>(s, l); 01850 } 01851 01852 #endif 01853 01854 01855 01856 private: 01857 01858 /*! 01859 an auxiliary method for converting from a string 01860 */ 01861 template<class istream_type, class string_type, class char_type> 01862 static istream_type & InputFromStream(istream_type & s, Int<value_size> & l) 01863 { 01864 string_type ss; 01865 01866 // char or wchar_t for operator>> 01867 char_type z; 01868 01869 // operator>> omits white characters if they're set for ommiting 01870 s >> z; 01871 01872 if( z=='-' || z=='+' ) 01873 { 01874 ss += z; 01875 s >> z; // we're reading a next character (white characters can be ommited) 01876 } 01877 01878 // we're reading only digits (base=10) 01879 while( s.good() && Misc::CharToDigit (z, 10)>=0 ) 01880 { 01881 ss += z; 01882 z = static_cast<char_type>(s.get()); 01883 } 01884 01885 // we're leaving the last readed character 01886 // (it's not belonging to the value) 01887 s.unget(); 01888 01889 l.FromString (ss); 01890 01891 return s; 01892 } 01893 01894 01895 public: 01896 01897 /*! 01898 input from standard streams 01899 */ 01900 friend std::istream & operator>> (std::istream & s, Int<value_size> & l) 01901 { 01902 return InputFromStream<std::istream, std::string, char>(s, l); 01903 } 01904 01905 01906 #ifndef TTMATH_DONT_USE_WCHAR 01907 01908 /*! 01909 input from standard streams 01910 */ 01911 friend std::wistream & operator>> (std::wistream & s, Int<value_size> & l) 01912 { 01913 return InputFromStream<std::wistream, std::wstring, wchar_t>(s, l); 01914 } 01915 #endif 01916 01917 01918 }; 01919 01920 } // namespace 01921 01922 #endif 01923
Generated on Tue Jul 12 2022 14:03:18 by 1.7.2