├── old ├── Supports.txt ├── new │ ├── SignedBiasNumber.h │ └── HugeFloat.h ├── test │ ├── compare_file.h │ └── tests.h ├── main.cpp ├── HugeLongNumber.h ├── Helper.h ├── InterTests.txt ├── UnsignedHugeLong.h ├── SignedHugeLong.h ├── Tests.txt ├── HugeNumberBase.h └── bak.txt ├── xcode └── HugeNumber.xcodeproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── HugeNumber.xccheckout │ ├── xcuserdata │ └── daidodo.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── HugeNumber.xcscheme │ └── project.pbxproj ├── test ├── Makefile ├── 1000.cpp └── unit_test.cpp ├── vs2015 ├── HugeNumber.vcxproj.filters ├── HugeNumber.sln └── HugeNumber.vcxproj ├── README.md ├── LICENSE └── huge_number.h /old/Supports.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daidodo/huge-long-number/HEAD/old/Supports.txt -------------------------------------------------------------------------------- /old/new/SignedBiasNumber.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daidodo/huge-long-number/HEAD/old/new/SignedBiasNumber.h -------------------------------------------------------------------------------- /xcode/HugeNumber.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = $(SRC:.cpp=) 2 | 3 | CXXFLAGS := --std=c++14 -g -Wall -I.. #-O2 -DNDEBUG 4 | 5 | SRC := $(wildcard *.cpp) 6 | DEP := $(SRC:.cpp=.d) 7 | 8 | CXXFLAGS += -MD 9 | 10 | all: clean $(TARGET) 11 | 12 | clean: 13 | $(RM) $(TARGET) *.o *.d 14 | $(RM) -r *.dSYM 15 | 16 | .PHONY: all clean 17 | -------------------------------------------------------------------------------- /test/1000.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "huge_number.h" 3 | 4 | using namespace std; 5 | using namespace dozerg; 6 | 7 | int main() 8 | { 9 | HugeNumber a(1); 10 | for (int i = 2; i <= 1000; ++i) 11 | a *= i; 12 | cout << "1000! = \n" 13 | << a << endl; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /xcode/HugeNumber.xcodeproj/xcuserdata/daidodo.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HugeNumber.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C7AD877A1B63AD4D00E1D838 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /old/test/compare_file.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void compare_file(const char * name1,const char * name2){ 8 | using namespace std; 9 | ifstream if1(name1); 10 | ifstream if2(name2); 11 | if(!if1.is_open() || !if2.is_open()) 12 | return; 13 | const int MAX_LEN = 1024; 14 | char buf1[MAX_LEN],buf2[MAX_LEN]; 15 | int line = 1,ret = 1; 16 | while(!if1.eof() && !if2.eof()){ 17 | if1.getline(buf1,MAX_LEN - 1); 18 | if2.getline(buf2,MAX_LEN - 1); 19 | if(strcmp(buf1,buf2)){ 20 | cout<<"Line "< 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | 23 | 24 | Source Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /old/main.cpp: -------------------------------------------------------------------------------- 1 | //#define TEST //enable test 2 | #define TEST_HUGE //test Huge Number or POD 3 | #define TEST_SIGNED //test signed or unsigned 4 | #define TEST_FILE //use file compare or output directly 5 | 6 | #ifndef __GNUC__ 7 | # define __DZ_COMPILE_IN_VC8 8 | #endif 9 | 10 | #include 11 | #include "HugeLongNumber.h" 12 | 13 | using namespace std; 14 | 15 | #ifdef TEST 16 | # ifdef TEST_HUGE 17 | # ifdef TEST_SIGNED 18 | typedef DoZerg::SignedHugeLong<4,short> __TestType; 19 | # else 20 | typedef DoZerg::UnsignedHugeLong<4,short> __TestType; 21 | # endif 22 | # else 23 | # ifdef TEST_SIGNED 24 | typedef long long __TestType; 25 | # else 26 | typedef unsigned long long __TestType; 27 | # endif 28 | # endif 29 | # include 30 | #else 31 | const int TOTAL_BYTES = 1067; 32 | typedef long Signed; 33 | typedef DoZerg::UnsignedHugeLong<(TOTAL_BYTES + sizeof(Signed) - 1) / sizeof(Signed), Signed> Int; 34 | 35 | #endif 36 | 37 | int main() 38 | { 39 | #ifdef TEST 40 | test(); 41 | #else 42 | long N = 1000; 43 | Int r = 1; 44 | for(long i = 2;i <= N;++i) 45 | r *= i; 46 | cout< ulong0; 15 | typedef UnsignedHugeLong<2> ulong1; 16 | typedef UnsignedHugeLong<4> ulong2; 17 | typedef UnsignedHugeLong<8> ulong3; 18 | typedef UnsignedHugeLong<16> ulong4; 19 | typedef UnsignedHugeLong<32> ulong5; 20 | typedef UnsignedHugeLong<64> ulong6; 21 | typedef UnsignedHugeLong<128> ulong7; 22 | typedef UnsignedHugeLong<256> ulong8; 23 | typedef UnsignedHugeLong<512> ulong9; 24 | typedef UnsignedHugeLong<1024> ulong10; 25 | //typedefs: 26 | typedef SignedHugeLong<1> slong0; 27 | typedef SignedHugeLong<2> slong1; 28 | typedef SignedHugeLong<4> slong2; 29 | typedef SignedHugeLong<8> slong3; 30 | typedef SignedHugeLong<16> slong4; 31 | typedef SignedHugeLong<32> slong5; 32 | typedef SignedHugeLong<64> slong6; 33 | typedef SignedHugeLong<128> slong7; 34 | typedef SignedHugeLong<256> slong8; 35 | typedef SignedHugeLong<512> slong9; 36 | typedef SignedHugeLong<1024> slong10; 37 | }//namespace DoZerg 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /vs2015/HugeNumber.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HugeNumber", "HugeNumber.vcxproj", "{3F2165BF-AD3F-41C5-9131-E931328127AA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Debug|x64.ActiveCfg = Debug|x64 17 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Debug|x64.Build.0 = Debug|x64 18 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Debug|x86.Build.0 = Debug|Win32 20 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Release|x64.ActiveCfg = Release|x64 21 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Release|x64.Build.0 = Release|x64 22 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Release|x86.ActiveCfg = Release|Win32 23 | {3F2165BF-AD3F-41C5-9131-E931328127AA}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /xcode/HugeNumber.xcodeproj/project.xcworkspace/xcshareddata/HugeNumber.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 0A64761E-A0EB-47EC-A93C-B1B4322314AB 9 | IDESourceControlProjectName 10 | HugeNumber 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 5ADDD8A2740797EB962191DC4D5CA95690B4A073 14 | https://github.com/daidodo/huge-long-number/ 15 | 16 | IDESourceControlProjectPath 17 | xcode/HugeNumber.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 5ADDD8A2740797EB962191DC4D5CA95690B4A073 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/daidodo/huge-long-number/ 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 5ADDD8A2740797EB962191DC4D5CA95690B4A073 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 5ADDD8A2740797EB962191DC4D5CA95690B4A073 36 | IDESourceControlWCCName 37 | huge-long-number 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /old/new/HugeFloat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 by DoZerg. ALL RIGHTS RESERVED. 3 | * Consult your license regarding permissions and restrictions. 4 | */ 5 | #pragma once 6 | #include "UnsignedHugeLong.h" 7 | #include "SignedBiasNumber.h" 8 | 9 | namespace DoZerg{ 10 | /*/declaration 11 | templateclass HugeFloat{ 12 | SignedBiasNumber exp_; //the first bit is Sign-Bit,else are exponent,using Biased Representation 13 | UnsignedHugeLong data_; //fraction 14 | static const unsigned long SignBit; 15 | static const long ExpBytes; //bytes of exp_ 16 | static const long DataBytes; //bytes of data_ 17 | public: 18 | HugeFloat(){}; 19 | ~HugeFloat(){} 20 | HugeFloat(double); 21 | HugeFloat(const std::string &); 22 | const HugeFloat & operator =(const std::string &); 23 | 24 | //temporary functions 25 | void show() const{ 26 | cout<<"Exp: "< 34 | const unsigned long HugeFloat::SignBit = 1<<((sizeof(unsigned long)<<3)-1); 35 | template 36 | const long HugeFloat::ExpBytes = E * sizeof(unsigned long); 37 | template 38 | const long HugeFloat::DataBytes = N * sizeof(unsigned long); 39 | //public: 40 | template 41 | HugeFloat::HugeFloat(double value):exp_(value<0,DoubleHelper::DoubleExp(value)){ 42 | } 43 | template 44 | HugeFloat::HugeFloat(const std::string & value){ 45 | } 46 | 47 | 48 | typedef HugeFloat<1,2> hfloat3; 49 | typedef HugeFloat<1,4> hfloat5; 50 | typedef HugeFloat<1,8> hfloat9; 51 | typedef HugeFloat<1,16> hfloat17; //*/ 52 | }//namespace DoZerg 53 | -------------------------------------------------------------------------------- /xcode/HugeNumber.xcodeproj/xcuserdata/daidodo.xcuserdatad/xcschemes/HugeNumber.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Huge Long Number 2 | 3 | This is a library of arbitrary range of integers written in C++14. 4 | 5 | class *`HugeNumber`* can represent arbitrary range of signed integers. 6 | 7 | Here is an example of computing 1000!(=1\*2\*3\*...\*1000): 8 | 9 | ```C++ 10 | #include 11 | #include "huge_number.h" 12 | 13 | using namespace std; 14 | using namespace dozerg; 15 | 16 | int main() 17 | { 18 | HugeNumber a(1); 19 | for (int i = 2; i <= 1000; ++i) 20 | a *= i; 21 | cout << "1000! = \n" 22 | << a << endl; 23 | return 0; 24 | } 25 | ``` 26 | 27 | which produces the result: 28 | 29 | $ time ./1000 30 | 1000! = 31 | 40238726007709377354370243392300398571937486421071 32 | 46325437999104299385123986290205920442084869694048 33 | 00479988610197196058631666872994808558901323829669 34 | 94459099742450408707375991882362772718873251977950 35 | 59509952761208749754624970436014182780946464962910 36 | 56393887437886487337119181045825783647849977012476 37 | 63288983595573543251318532395846307555740911426241 38 | 74743493475534286465766116677973966688202912073791 39 | 43853719588249808126867838374559731746136085379534 40 | 52422158659320192809087829730843139284440328123155 41 | 86110369768013573042161687476096758713483120254785 42 | 89320767169132448426236131412508780208000261683151 43 | 02734182797770478463586817016436502415369139828126 44 | 48102130927612448963599287051149649754199093422215 45 | 66832572080821333186116811553615836546984046708975 46 | 60290095053761647584772842188967964624494516076535 47 | 34081989013854424879849599533191017233555566021394 48 | 50399736280750137837615307127761926849034352625200 49 | 01588853514733161170210396817592151090778801939317 50 | 81141945452572238655414610628921879602238389714760 51 | 88506276862967146674697562911234082439208160153780 52 | 88989396451826324367161676217916890977991190375403 53 | 12746222899880051954444142820121873617459926429565 54 | 81746628302955570299024324153181617210465832036786 55 | 90611726015878352075151628422554026517048330422614 56 | 39742869330616908979684825901254583271682264580665 57 | 26769958652682272807075781391858178889652208164348 58 | 34482599326604336766017699961283186078838615027946 59 | 59551311565520360939881806121385586003014356945272 60 | 24206344631797460594682573103790084024432438465657 61 | 24501440282188525247093519062092902313649327349756 62 | 55139587205596542287497740114133469627154228458623 63 | 77387538230483865688976461927383814900140767310446 64 | 64025989949022222176590433990188601856652648506179 65 | 97023561938970178600408118897299183110211712298459 66 | 01641921068884387121855646124960798722908519296819 67 | 37238864261483965738229112312502418664935314397013 68 | 74285319266498753372189406942814341185201580141233 69 | 44828015051399694290153483077644569099073152433278 70 | 28826986460278986432113908350621709500259738986355 71 | 42771967428222487575867657523442202075736305694988 72 | 25087968928162753848863396909959826280956121450994 73 | 87170124451646126037902930912088908694202851064018 74 | 21543994571568059418727489980942547421735824010636 75 | 77404595741785160829230135358081840096996372524230 76 | 56085590370062427124341690900415369010593398383577 77 | 79394109700277534720000000000000000000000000000000 78 | 00000000000000000000000000000000000000000000000000 79 | 00000000000000000000000000000000000000000000000000 80 | 00000000000000000000000000000000000000000000000000 81 | 00000000000000000000000000000000000000000000000000 82 | 000000000000000000 83 | 84 | real 0m0.044s 85 | user 0m0.042s 86 | sys 0m0.002s 87 | 88 | 89 | Well, you can check if it's right! 90 | 91 | Tested in VS2015, clang 3.6 and GCC 4.9. 92 | -------------------------------------------------------------------------------- /old/Helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 by DoZerg. ALL RIGHTS RESERVED. 3 | * Consult your license regarding permissions and restrictions. 4 | */ 5 | #ifndef DOZERG_HELPER_H_20080925 6 | #define DOZERG_HELPER_H_20080925 7 | 8 | #include 9 | 10 | namespace DoZerg{ 11 | namespace StringHelper{ 12 | int CheckBaseFromString(const std::string & value){ 13 | int base = 0; 14 | for(std::string::const_iterator v = value.begin();v != value.end() && base != -1; ++v) 15 | switch(base){ 16 | case 0: 17 | base = ('+'==*v || '-'==*v)?1:('0'==*v)?2:(*v>'0' && *v<='9')?10:-1; 18 | break; 19 | case 1: 20 | base = ('0'==*v)?2:(*v>'0' && *v<='9')?10:-1; //only '+' or '-' 21 | break; 22 | case 2: 23 | base = ('x'==*v || 'X'==*v)?3:(*v>='0' && *v<'8')?8:-1; //just 0 24 | break; 25 | case 3: 26 | base = ((*v>'0' && *v<='9')||(*v>='a' && *v<='f')||(*v>='A' && *v<='F'))?16:-1; //0x 27 | break; 28 | case 8: 29 | base = (*v>='0' && *v<'8')?8:-1; 30 | break; 31 | case 10: 32 | base = (*v>='0' && *v<='9')?10:-1; 33 | break; 34 | case 16: 35 | base = ((*v>='0' && *v<='9')||(*v>='a' && *v<='f')||(*v>='A' && *v<='F'))?16:-1; 36 | break; 37 | default:; 38 | } 39 | return base; 40 | } 41 | int DivideStringByTwo(std::string & value,bool & IsZero){ //return the highest bit,then divide the string by 2,in reverse order 42 | bool carry(false); 43 | for(std::string::reverse_iterator v = value.rbegin();v != value.rend();++v){ 44 | if(carry) 45 | *v += 10; 46 | carry = *v & 1; 47 | *v >>= 1; 48 | } 49 | std::string::size_type p(value.find_last_not_of(char(0)) + 1); 50 | IsZero =! p; 51 | value.erase(p); 52 | return (carry ? 1 : 0); 53 | } 54 | void MutiStringWithTwo(std::string & value,int AddNumber){ //multiple the string,then add the number(0 to 9),in reverse order 55 | int carry(AddNumber); 56 | for(std::string::iterator v = value.begin();v != value.end();++v){ 57 | *v = (*v << 1) + carry; 58 | if(carry = *v / 10) 59 | *v %= 10; 60 | } 61 | if(carry) 62 | value.push_back(carry); //this requires 0<=carry<=9 63 | } 64 | std::string & ReverseString(std::string & value,int AddValue = 0){ //reverse the string,and add AddValue to all elements 65 | std::string::size_type l=value.length(); 66 | if(l & 1) 67 | value[l / 2] += AddValue; 68 | for(std::string::size_type i = 0;i < l / 2;++i){ 69 | value[i] ^= value[l - i - 1]; 70 | value[l - i - 1] ^= value[i]; 71 | value[i] ^= value[l - i - 1]; 72 | value[i] += AddValue; 73 | value[l - i - 1] += AddValue; 74 | } 75 | return value; 76 | } 77 | }//namespace StringHelper 78 | #define SPECIFIED_DataTypeTrait_FOR_S(type) \ 79 | template<>struct DataTypeTrait{ \ 80 | typedef type __Signed; \ 81 | typedef unsigned type __Unsigned; \ 82 | }; \ 83 | template<>struct DataTypeTrait{ \ 84 | typedef type __Signed; \ 85 | typedef unsigned type __Unsigned; \ 86 | }; 87 | namespace DataTraits{ 88 | typedef long long __DefaultDataType; 89 | //struct DataType 90 | templatestruct DataTypeTrait{}; 91 | SPECIFIED_DataTypeTrait_FOR_S(long long); 92 | SPECIFIED_DataTypeTrait_FOR_S(long); 93 | SPECIFIED_DataTypeTrait_FOR_S(int); 94 | SPECIFIED_DataTypeTrait_FOR_S(short); 95 | SPECIFIED_DataTypeTrait_FOR_S(char); 96 | template<>struct DataTypeTrait{ 97 | typedef signed char __Signed; 98 | typedef unsigned char __Unsigned; 99 | }; 100 | }//namespace DataTraits 101 | #undef SPECIFIED_DataTypeTrait_FOR_S 102 | }//namespace DoZerg 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /old/InterTests.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 by DoZerg. ALL RIGHTS RESERVED. 3 | * Consult your license regarding permissions and restrictions. 4 | */ 5 | #pragma once 6 | 7 | #include "Tests.h" 8 | 9 | #ifdef TEST 10 | 11 | #ifdef INTER_TEST 12 | 13 | typedef __TestSigned1 __I_TestType1; 14 | typedef __TestUnsigned1 __I_TestType2; 15 | 16 | void I_Test001(){ //==,!=,<,>,<=,>= 17 | cout<<"\tI_Test001"< b ? "Yes" : "No")<<' '<<(al > bl ? "Yes" : "No")< c ? "Yes" : "No")<<' '<<(al > cl ? "Yes" : "No")< d ? "Yes" : "No")<<' '<<(al > dl ? "Yes" : "No")< a ? "Yes" : "No")<<' '<<(bl > al ? "Yes" : "No")< a ? "Yes" : "No")<<' '<<(cl > al ? "Yes" : "No")< a ? "Yes" : "No")<<' '<<(dl > al ? "Yes" : "No")<= b ? "Yes" : "No")<<' '<<(al >= bl ? "Yes" : "No")<= c ? "Yes" : "No")<<' '<<(al >= cl ? "Yes" : "No")<= d ? "Yes" : "No")<<' '<<(al >= dl ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(bl >= al ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(cl >= al ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(dl >= al ? "Yes" : "No")< 9 | #include "HugeNumberBase.h" 10 | 11 | namespace DoZerg{ 12 | template< 13 | int N, 14 | typename DataType = DataTraits::__DefaultDataType 15 | >class UnsignedHugeLong:public HugeNumberBase 16 | { 17 | typedef HugeNumberBase __MyBase; 18 | typedef UnsignedHugeLong __Myt; 19 | typedef typename __MyBase::__Signed __Signed; 20 | typedef typename __MyBase::__Unsigned __Unsigned; 21 | public: 22 | UnsignedHugeLong(){} 23 | UnsignedHugeLong(const __Unsigned & value):__MyBase(__Signed(value),false){} 24 | UnsignedHugeLong(const std::string & value):__MyBase(value){} 25 | UnsignedHugeLong(const __Myt & value):__MyBase(value){} 26 | explicit UnsignedHugeLong(const __MyBase & value):__MyBase(value){} 27 | __Myt & operator =(const __Unsigned & value){ 28 | __MyBase::FromValue(__Signed(value),false); 29 | return *this; 30 | } 31 | __Myt & operator =(const std::string & value){ 32 | __MyBase::FromString(value); 33 | return *this; 34 | } 35 | __Myt & operator =(const __Myt & value){ 36 | if(this != &value) 37 | __MyBase::FromSelf(value); 38 | return *this; 39 | } 40 | __Myt & operator =(const __MyBase & value){ 41 | if(this != &value) 42 | __MyBase::FromSelf(value); 43 | return *this; 44 | } 45 | __Myt operator +() const{return __Myt(*this);} 46 | __Myt operator -() const{return __Myt(*this).minus();} 47 | __Myt operator ~() const{return __Myt(*this).complement();} 48 | __Myt operator >>(int value) const{return __Myt(*this).rightShift(value);} 49 | __Myt operator <<(int value) const{return __Myt(*this).leftShift(value);} 50 | __Myt & operator ++(){__MyBase::Increase();return *this;} 51 | __Myt & operator --(){__MyBase::Decrease();return *this;} 52 | __Myt operator ++(int){__Myt tmp(*this);operator ++();return tmp;} 53 | __Myt operator --(int){__Myt tmp(*this);operator --();return tmp;} 54 | __Myt & operator >>=(int value){return rightShift(value,false);} 55 | __Myt & operator <<=(int value){return leftShift(value);} 56 | __Myt & operator +=(const __Myt & value){__MyBase::OperatorAdd(value);return *this;} 57 | __Myt & operator -=(const __Myt & value){__MyBase::OperatorSub(value);return *this;} 58 | __Myt & operator *=(const __Myt & value){__MyBase::OperatorMult(value);return *this;} 59 | __Myt & operator /=(const __Myt & value){__MyBase::OperatorDiv(value);return *this;} 60 | __Myt & operator %=(const __Myt & value){__MyBase::OperatorDiv(value,false);return *this;} 61 | __Myt & operator &=(const __Myt & value){__MyBase::OperatorAnd(value);return *this;} 62 | __Myt & operator |=(const __Myt & value){__MyBase::OperatorOr(value);return *this;} 63 | __Myt & operator ^=(const __Myt & value){__MyBase::OperatorXor(value);return *this;} 64 | std::string ToString(int BaseValue = 10,bool uppercase = false,bool showbase = false) const{ 65 | return __MyBase::ToString(BaseValue,false,uppercase,showbase); 66 | } 67 | bool operator ==(const __Myt & value) const{return __MyBase::OperatorEqual(value);} 68 | bool operator !=(const __Myt & value) const{return !operator ==(value);} 69 | bool operator <(const __Myt & value) const{return __MyBase::OperatorSmaller(value);} 70 | bool operator >(const __Myt & value) const{return value.operator <(*this);} 71 | bool operator <=(const __Myt & value) const{return !value.operator <(*this);} 72 | bool operator >=(const __Myt & value) const{return !operator <(value);} 73 | __Myt operator +(const __Myt & value) const{return __Myt(*this).operator +=(value);} 74 | __Myt operator -(const __Myt & value) const{return __Myt(*this).operator -=(value);} 75 | __Myt operator *(const __Myt & value) const{return __Myt(*this).operator *=(value);} 76 | __Myt operator /(const __Myt & value) const{return __Myt(*this).operator /=(value);} 77 | __Myt operator %(const __Myt & value) const{return __Myt(*this).operator %=(value);} 78 | __Myt operator &(const __Myt & value) const{return __Myt(*this).operator &=(value);} 79 | __Myt operator |(const __Myt & value) const{return __Myt(*this).operator |=(value);} 80 | __Myt operator ^(const __Myt & value) const{return __Myt(*this).operator ^=(value);} 81 | //friend functions 82 | inline friend bool operator ==(const __Unsigned & a,const __Myt & b){return __Myt(a) == b;} 83 | inline friend bool operator !=(const __Unsigned & a,const __Myt & b){return __Myt(a) != b;} 84 | inline friend bool operator <(const __Unsigned & a,const __Myt & b){return __Myt(a) < b;} 85 | inline friend bool operator >(const __Unsigned & a,const __Myt & b){return __Myt(a) > b;} 86 | inline friend bool operator <=(const __Unsigned & a,const __Myt & b){return __Myt(a) <= b;} 87 | inline friend bool operator >=(const __Unsigned & a,const __Myt & b){return __Myt(a) >= b;} 88 | inline friend __Myt operator +(const __Unsigned & a,const __Myt & b){return __Myt(a) += b;} 89 | inline friend __Myt operator -(const __Unsigned & a,const __Myt & b){return __Myt(a) -= b;} 90 | inline friend __Myt operator *(const __Unsigned & a,const __Myt & b){return __Myt(a) *= b;} 91 | inline friend __Myt operator /(const __Unsigned & a,const __Myt & b){return __Myt(a) /= b;} 92 | inline friend __Myt operator %(const __Unsigned & a,const __Myt & b){return __Myt(a) %= b;} 93 | inline friend __Myt operator &(const __Unsigned & a,const __Myt & b){return __Myt(a) &= b;} 94 | inline friend __Myt operator |(const __Unsigned & a,const __Myt & b){return __Myt(a) |= b;} 95 | inline friend __Myt operator ^(const __Unsigned & a,const __Myt & b){return __Myt(a) ^= b;} 96 | inline friend __Myt abs(const __Myt & a){return a;} 97 | inline friend std::ostream & operator <<(std::ostream & os,const __Myt & value){ 98 | const std::ios::fmtflags fmt = os.flags(); 99 | const int base = (fmt & os.hex ? 16 : (fmt & os.oct ? 8 : 10)); 100 | return os<class SignedHugeLong:public HugeNumberBase 15 | { 16 | typedef HugeNumberBase __MyBase; 17 | typedef SignedHugeLong __Myt; 18 | typedef typename __MyBase::__Signed __Signed; 19 | typedef typename __MyBase::__Unsigned __Unsigned; 20 | public: 21 | SignedHugeLong(){} 22 | SignedHugeLong(const __Signed & value):__MyBase(value,true){} 23 | SignedHugeLong(const std::string & value):__MyBase(value){} 24 | SignedHugeLong(const __Myt & value):__MyBase(value){} 25 | explicit SignedHugeLong(const __MyBase & value):__MyBase(value){} 26 | __Myt & operator =(const __Signed & value){ 27 | __MyBase::FromValue(value,false); 28 | return *this; 29 | } 30 | __Myt & operator =(const std::string & value){ 31 | __MyBase::FromString(value); 32 | return *this; 33 | } 34 | __Myt & operator =(const __Myt & value){ 35 | if(this != &value) 36 | __MyBase::FromSelf(value); 37 | return *this; 38 | } 39 | __Myt & operator =(const __MyBase & value){ 40 | if(this != &value) 41 | __MyBase::FromSelf(value); 42 | return *this; 43 | } 44 | __Myt operator +() const{return __Myt(*this);} 45 | __Myt operator -() const{return __Myt(*this).minus();} 46 | __Myt operator ~() const{return __Myt(*this).complement();} 47 | __Myt operator >>(int value) const{return __Myt(*this).rightShift(value);} 48 | __Myt operator <<(int value) const{return __Myt(*this).leftShift(value);} 49 | __Myt & operator ++(){__MyBase::Increase();return *this;} 50 | __Myt & operator --(){__MyBase::Decrease();return *this;} 51 | __Myt operator ++(int){__Myt tmp(*this);operator ++();return tmp;} 52 | __Myt operator --(int){__Myt tmp(*this);operator --();return tmp;} 53 | __Myt & operator >>=(int value){return rightShift(value,false);} 54 | __Myt & operator <<=(int value){return leftShift(value);} 55 | __Myt & operator +=(const __Myt & value){__MyBase::OperatorAdd(value);return *this;} 56 | __Myt & operator -=(const __Myt & value){__MyBase::OperatorSub(value);return *this;} 57 | __Myt & operator *=(const __Myt & value){__MyBase::OperatorMult(value);return *this;} 58 | __Myt & operator /=(const __Myt & value){ 59 | const bool sign(__MyBase::GetSignBit()); 60 | if(sign) 61 | __MyBase::Minus(); 62 | OperatorDiv(abs(value)); 63 | if(sign ^ value.GetSignBit()) 64 | __MyBase::Minus(); 65 | return *this; 66 | } 67 | __Myt & operator %=(const __Myt & value){ 68 | const bool sign(__MyBase::GetSignBit()); 69 | if(sign) 70 | __MyBase::Minus(); 71 | OperatorDiv(abs(value),false); 72 | if(sign) 73 | __MyBase::Minus(); 74 | return *this; 75 | } 76 | __Myt & operator &=(const __Myt & value){__MyBase::OperatorAnd(value);return *this;} 77 | __Myt & operator |=(const __Myt & value){__MyBase::OperatorOr(value);return *this;} 78 | __Myt & operator ^=(const __Myt & value){__MyBase::OperatorXor(value);return *this;} 79 | std::string ToString(int BaseValue = 10,bool uppercase = false,bool showbase = false) const{ 80 | return __MyBase::ToString(BaseValue,true,uppercase,showbase); 81 | } 82 | bool operator ==(const __Myt & value) const{return __MyBase::OperatorEqual(value);} 83 | bool operator !=(const __Myt & value) const{return !operator ==(value);} 84 | bool operator <(const __Myt & value) const{return __MyBase::OperatorSmaller(value);} 85 | bool operator >(const __Myt & value) const{return value.operator <(*this);} 86 | bool operator <=(const __Myt & value) const{return !value.operator <(*this);} 87 | bool operator >=(const __Myt & value) const{return !operator <(value);} 88 | __Myt operator +(const __Myt & value) const{return __Myt(*this).operator +=(value);} 89 | __Myt operator -(const __Myt & value) const{return __Myt(*this).operator -=(value);} 90 | __Myt operator *(const __Myt & value) const{return __Myt(*this).operator *=(value);} 91 | __Myt operator /(const __Myt & value) const{return __Myt(*this).operator /=(value);} 92 | __Myt operator %(const __Myt & value) const{return __Myt(*this).operator %=(value);} 93 | __Myt operator &(const __Myt & value) const{return __Myt(*this).operator &=(value);} 94 | __Myt operator |(const __Myt & value) const{return __Myt(*this).operator |=(value);} 95 | __Myt operator ^(const __Myt & value) const{return __Myt(*this).operator ^=(value);} 96 | //friend functions 97 | inline friend bool operator ==(const __Signed & a,const __Myt & b){return __Myt(a) == b;} 98 | inline friend bool operator !=(const __Signed & a,const __Myt & b){return __Myt(a) != b;} 99 | inline friend bool operator <(const __Signed & a,const __Myt & b){return __Myt(a) < b;} 100 | inline friend bool operator >(const __Signed & a,const __Myt & b){return __Myt(a) > b;} 101 | inline friend bool operator <=(const __Signed & a,const __Myt & b){return __Myt(a) <= b;} 102 | inline friend bool operator >=(const __Signed & a,const __Myt & b){return __Myt(a) >= b;} 103 | inline friend __Myt operator +(const __Signed & a,const __Myt & b){return __Myt(a) += b;} 104 | inline friend __Myt operator -(const __Signed & a,const __Myt & b){return __Myt(a) -= b;} 105 | inline friend __Myt operator *(const __Signed & a,const __Myt & b){return __Myt(a) *= b;} 106 | inline friend __Myt operator /(const __Signed & a,const __Myt & b){return __Myt(a) /= b;} 107 | inline friend __Myt operator %(const __Signed & a,const __Myt & b){return __Myt(a) %= b;} 108 | inline friend __Myt operator &(const __Signed & a,const __Myt & b){return __Myt(a) &= b;} 109 | inline friend __Myt operator |(const __Signed & a,const __Myt & b){return __Myt(a) |= b;} 110 | inline friend __Myt operator ^(const __Signed & a,const __Myt & b){return __Myt(a) ^= b;} 111 | inline friend __Myt abs(const __Myt & a){return (a.GetSignBit() ? -value : value);} 112 | inline friend std::ostream & operator <<(std::ostream & os,const __Myt & value){ 113 | const std::ios::fmtflags fmt = os.flags(); 114 | const int base = (fmt & os.hex ? 16 : (fmt & os.oct ? 8 : 10)); 115 | return os< 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {3F2165BF-AD3F-41C5-9131-E931328127AA} 23 | Win32Proj 24 | HugeNumber 25 | 8.1 26 | 27 | 28 | 29 | Application 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | Application 36 | false 37 | v140 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | Application 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | ..\;$(IncludePath) 75 | 76 | 77 | true 78 | ..\;$(IncludePath) 79 | 80 | 81 | false 82 | ..\;$(IncludePath) 83 | 84 | 85 | false 86 | ..\;$(IncludePath) 87 | 88 | 89 | 90 | 91 | 92 | Level3 93 | Disabled 94 | WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 95 | true 96 | 97 | 98 | Console 99 | true 100 | 101 | 102 | 103 | 104 | 105 | 106 | Level3 107 | Disabled 108 | _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 109 | true 110 | 111 | 112 | Console 113 | true 114 | 115 | 116 | 117 | 118 | Level3 119 | 120 | 121 | MaxSpeed 122 | true 123 | true 124 | WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 125 | true 126 | 127 | 128 | Console 129 | true 130 | true 131 | true 132 | 133 | 134 | 135 | 136 | Level3 137 | 138 | 139 | MaxSpeed 140 | true 141 | true 142 | NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 143 | true 144 | 145 | 146 | Console 147 | true 148 | true 149 | true 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /xcode/HugeNumber.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B9A561D01C0DC745007C2F7E /* unit_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B9A561CF1C0DC745007C2F7E /* unit_test.cpp */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | C7AD87791B63AD4D00E1D838 /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = /usr/share/man/man1/; 18 | dstSubfolderSpec = 0; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 1; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | B9A561CF1C0DC745007C2F7E /* unit_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = unit_test.cpp; path = ../test/unit_test.cpp; sourceTree = ""; }; 27 | C7AD877B1B63AD4D00E1D838 /* HugeNumber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = HugeNumber; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | C7DF7CD61B63ADC000B3B8E0 /* huge_number.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = huge_number.h; path = ../huge_number.h; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | C7AD87781B63AD4D00E1D838 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | C7AD87721B63AD4D00E1D838 = { 43 | isa = PBXGroup; 44 | children = ( 45 | C7DF7CD31B63AD9B00B3B8E0 /* HugeNumber */, 46 | C7AD877C1B63AD4D00E1D838 /* Products */, 47 | ); 48 | sourceTree = ""; 49 | }; 50 | C7AD877C1B63AD4D00E1D838 /* Products */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | C7AD877B1B63AD4D00E1D838 /* HugeNumber */, 54 | ); 55 | name = Products; 56 | sourceTree = ""; 57 | }; 58 | C7DF7CD31B63AD9B00B3B8E0 /* HugeNumber */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | B9A561CF1C0DC745007C2F7E /* unit_test.cpp */, 62 | C7DF7CD61B63ADC000B3B8E0 /* huge_number.h */, 63 | ); 64 | name = HugeNumber; 65 | sourceTree = ""; 66 | }; 67 | /* End PBXGroup section */ 68 | 69 | /* Begin PBXNativeTarget section */ 70 | C7AD877A1B63AD4D00E1D838 /* HugeNumber */ = { 71 | isa = PBXNativeTarget; 72 | buildConfigurationList = C7AD87821B63AD4D00E1D838 /* Build configuration list for PBXNativeTarget "HugeNumber" */; 73 | buildPhases = ( 74 | C7AD87771B63AD4D00E1D838 /* Sources */, 75 | C7AD87781B63AD4D00E1D838 /* Frameworks */, 76 | C7AD87791B63AD4D00E1D838 /* CopyFiles */, 77 | ); 78 | buildRules = ( 79 | ); 80 | dependencies = ( 81 | ); 82 | name = HugeNumber; 83 | productName = HugeNumber; 84 | productReference = C7AD877B1B63AD4D00E1D838 /* HugeNumber */; 85 | productType = "com.apple.product-type.tool"; 86 | }; 87 | /* End PBXNativeTarget section */ 88 | 89 | /* Begin PBXProject section */ 90 | C7AD87731B63AD4D00E1D838 /* Project object */ = { 91 | isa = PBXProject; 92 | attributes = { 93 | LastUpgradeCheck = 0710; 94 | ORGANIZATIONNAME = DoZerg; 95 | TargetAttributes = { 96 | C7AD877A1B63AD4D00E1D838 = { 97 | CreatedOnToolsVersion = 6.4; 98 | }; 99 | }; 100 | }; 101 | buildConfigurationList = C7AD87761B63AD4D00E1D838 /* Build configuration list for PBXProject "HugeNumber" */; 102 | compatibilityVersion = "Xcode 3.2"; 103 | developmentRegion = English; 104 | hasScannedForEncodings = 0; 105 | knownRegions = ( 106 | en, 107 | ); 108 | mainGroup = C7AD87721B63AD4D00E1D838; 109 | productRefGroup = C7AD877C1B63AD4D00E1D838 /* Products */; 110 | projectDirPath = ""; 111 | projectRoot = ""; 112 | targets = ( 113 | C7AD877A1B63AD4D00E1D838 /* HugeNumber */, 114 | ); 115 | }; 116 | /* End PBXProject section */ 117 | 118 | /* Begin PBXSourcesBuildPhase section */ 119 | C7AD87771B63AD4D00E1D838 /* Sources */ = { 120 | isa = PBXSourcesBuildPhase; 121 | buildActionMask = 2147483647; 122 | files = ( 123 | B9A561D01C0DC745007C2F7E /* unit_test.cpp in Sources */, 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXSourcesBuildPhase section */ 128 | 129 | /* Begin XCBuildConfiguration section */ 130 | C7AD87801B63AD4D00E1D838 /* Debug */ = { 131 | isa = XCBuildConfiguration; 132 | buildSettings = { 133 | ALWAYS_SEARCH_USER_PATHS = NO; 134 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 135 | CLANG_CXX_LIBRARY = "libc++"; 136 | CLANG_ENABLE_MODULES = YES; 137 | CLANG_ENABLE_OBJC_ARC = YES; 138 | CLANG_WARN_BOOL_CONVERSION = YES; 139 | CLANG_WARN_CONSTANT_CONVERSION = YES; 140 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 141 | CLANG_WARN_EMPTY_BODY = YES; 142 | CLANG_WARN_ENUM_CONVERSION = YES; 143 | CLANG_WARN_INT_CONVERSION = YES; 144 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 145 | CLANG_WARN_UNREACHABLE_CODE = YES; 146 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 147 | COPY_PHASE_STRIP = NO; 148 | DEBUG_INFORMATION_FORMAT = dwarf; 149 | ENABLE_STRICT_OBJC_MSGSEND = YES; 150 | ENABLE_TESTABILITY = YES; 151 | GCC_C_LANGUAGE_STANDARD = gnu99; 152 | GCC_DYNAMIC_NO_PIC = NO; 153 | GCC_NO_COMMON_BLOCKS = YES; 154 | GCC_OPTIMIZATION_LEVEL = 0; 155 | GCC_PREPROCESSOR_DEFINITIONS = ( 156 | "DEBUG=1", 157 | "$(inherited)", 158 | ); 159 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 160 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 161 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 162 | GCC_WARN_UNDECLARED_SELECTOR = YES; 163 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 164 | GCC_WARN_UNUSED_FUNCTION = YES; 165 | GCC_WARN_UNUSED_VARIABLE = YES; 166 | MACOSX_DEPLOYMENT_TARGET = 10.10; 167 | MTL_ENABLE_DEBUG_INFO = YES; 168 | ONLY_ACTIVE_ARCH = YES; 169 | SDKROOT = macosx; 170 | }; 171 | name = Debug; 172 | }; 173 | C7AD87811B63AD4D00E1D838 /* Release */ = { 174 | isa = XCBuildConfiguration; 175 | buildSettings = { 176 | ALWAYS_SEARCH_USER_PATHS = NO; 177 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 178 | CLANG_CXX_LIBRARY = "libc++"; 179 | CLANG_ENABLE_MODULES = YES; 180 | CLANG_ENABLE_OBJC_ARC = YES; 181 | CLANG_WARN_BOOL_CONVERSION = YES; 182 | CLANG_WARN_CONSTANT_CONVERSION = YES; 183 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 184 | CLANG_WARN_EMPTY_BODY = YES; 185 | CLANG_WARN_ENUM_CONVERSION = YES; 186 | CLANG_WARN_INT_CONVERSION = YES; 187 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 188 | CLANG_WARN_UNREACHABLE_CODE = YES; 189 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 190 | COPY_PHASE_STRIP = NO; 191 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 192 | ENABLE_NS_ASSERTIONS = NO; 193 | ENABLE_STRICT_OBJC_MSGSEND = YES; 194 | GCC_C_LANGUAGE_STANDARD = gnu99; 195 | GCC_NO_COMMON_BLOCKS = YES; 196 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 197 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 198 | GCC_WARN_UNDECLARED_SELECTOR = YES; 199 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 200 | GCC_WARN_UNUSED_FUNCTION = YES; 201 | GCC_WARN_UNUSED_VARIABLE = YES; 202 | MACOSX_DEPLOYMENT_TARGET = 10.10; 203 | MTL_ENABLE_DEBUG_INFO = NO; 204 | SDKROOT = macosx; 205 | }; 206 | name = Release; 207 | }; 208 | C7AD87831B63AD4D00E1D838 /* Debug */ = { 209 | isa = XCBuildConfiguration; 210 | buildSettings = { 211 | CLANG_CXX_LANGUAGE_STANDARD = "c++14"; 212 | PRODUCT_NAME = "$(TARGET_NAME)"; 213 | }; 214 | name = Debug; 215 | }; 216 | C7AD87841B63AD4D00E1D838 /* Release */ = { 217 | isa = XCBuildConfiguration; 218 | buildSettings = { 219 | CLANG_CXX_LANGUAGE_STANDARD = "c++14"; 220 | PRODUCT_NAME = "$(TARGET_NAME)"; 221 | }; 222 | name = Release; 223 | }; 224 | /* End XCBuildConfiguration section */ 225 | 226 | /* Begin XCConfigurationList section */ 227 | C7AD87761B63AD4D00E1D838 /* Build configuration list for PBXProject "HugeNumber" */ = { 228 | isa = XCConfigurationList; 229 | buildConfigurations = ( 230 | C7AD87801B63AD4D00E1D838 /* Debug */, 231 | C7AD87811B63AD4D00E1D838 /* Release */, 232 | ); 233 | defaultConfigurationIsVisible = 0; 234 | defaultConfigurationName = Release; 235 | }; 236 | C7AD87821B63AD4D00E1D838 /* Build configuration list for PBXNativeTarget "HugeNumber" */ = { 237 | isa = XCConfigurationList; 238 | buildConfigurations = ( 239 | C7AD87831B63AD4D00E1D838 /* Debug */, 240 | C7AD87841B63AD4D00E1D838 /* Release */, 241 | ); 242 | defaultConfigurationIsVisible = 0; 243 | defaultConfigurationName = Release; 244 | }; 245 | /* End XCConfigurationList section */ 246 | }; 247 | rootObject = C7AD87731B63AD4D00E1D838 /* Project object */; 248 | } 249 | -------------------------------------------------------------------------------- /old/Tests.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 by DoZerg. ALL RIGHTS RESERVED. 3 | * Consult your license regarding permissions and restrictions. 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "HugeLongNumber.h" 10 | #include "PerformanceProfile.h" 11 | 12 | using namespace std; 13 | using namespace DoZerg; 14 | using namespace DoZerg::AllocationStrategy; 15 | 16 | #ifdef TEST 17 | 18 | typedef __int64 DataType; 19 | 20 | typedef SignedHugeLong<4,DataType,DataAutoSelect> __TestSigned1; 21 | typedef SignedHugeLong<4,DataType,DataInStack> __TestSigned2; 22 | typedef SignedHugeLong<4,DataType,DataInHeap> __TestSigned3; 23 | typedef UnsignedHugeLong<4,DataType,DataAutoSelect> __TestUnsigned1; 24 | typedef UnsignedHugeLong<4,DataType,DataInStack> __TestUnsigned2; 25 | typedef UnsignedHugeLong<4,DataType,DataInHeap> __TestUnsigned3; 26 | 27 | #define SIGNED 28 | 29 | #ifdef SIGNED 30 | typedef __TestSigned1 __TestType1; 31 | typedef __TestSigned2 __TestType2; 32 | #else 33 | typedef __TestUnsigned1 __TestType1; 34 | typedef __TestUnsigned2 __TestType2; 35 | #endif 36 | 37 | typedef __TestType1::__Signed __Signed; 38 | typedef __TestType1::__Unsigned __Unsigned; 39 | 40 | #ifdef SIGNED 41 | typedef __Signed __Test; 42 | #else 43 | typedef __Unsigned __Test; 44 | #endif 45 | 46 | void Test001(){ //constructor,assignment,ToString,ostream <<,istream >>,ToSigned 47 | #define TEST001 48 | cout<<"\tTest001"<>a; 63 | cout<>,++,--,>>=,<<=,abs 85 | #define TEST002 86 | cout<<"\tTest002"<>2)<<' '<<(al>>2)<>=3)<<' '<<(al>>=3)<,>=,<= 120 | #define TEST003 121 | cout<<"\tTest003"<= av ? "Yes" : "No")<<' '<<(a < av ? "Yes" : "No")<= bv ? "Yes" : "No")<<' '<<(a < bv ? "Yes" : "No")<= cv ? "Yes" : "No")<= as ? "Yes" : "No")<<' '<<(a < as ? "Yes" : "No")<= bs ? "Yes" : "No")<<' '<<(a < bs ? "Yes" : "No")<= cs ? "Yes" : "No")<= a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(bv < a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(cv < a ? "Yes" : "No")<= a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(bs < a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(cs < a ? "Yes" : "No")<= b ? "Yes" : "No")<<' '<<(a < b ? "Yes" : "No")<= c ? "Yes" : "No")<<' '<<(a < c ? "Yes" : "No")<= d ? "Yes" : "No")< av ? "Yes" : "No")<<' '<<(a <= av ? "Yes" : "No")< bv ? "Yes" : "No")< cv ? "Yes" : "No")< as ? "Yes" : "No")<<' '<<(a <= as ? "Yes" : "No")< bs ? "Yes" : "No")< cs ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")<<' '<<(cv <= a ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")<<' '<<(cs <= a ? "Yes" : "No")< b ? "Yes" : "No")<<' '<<(a <= b ? "Yes" : "No")< c ? "Yes" : "No")< d ? "Yes" : "No")< 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /old/test/tests.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 by DoZerg. ALL RIGHTS RESERVED. 3 | * Consult your license regarding permissions and restrictions. 4 | */ 5 | #ifndef DOZERT_TEST_H_20080926 6 | #define DOZERT_TEST_H_20080926 7 | 8 | //#include "compare_file.h" 9 | #ifdef __DZ_COMPILE_IN_VC8 10 | # ifdef TEST_SIGNED 11 | const char * DZ_OUT_FILE = "result\\test_dz_signed_vc8.txt"; 12 | const char * SYS_OUT_FILE = "result\\test_sys_signed_vc8.txt"; 13 | # else 14 | const char * DZ_OUT_FILE = "result\\test_dz_unsigned_vc8.txt"; 15 | const char * SYS_OUT_FILE = "result\\test_sys_unsigned_vc8.txt"; 16 | # endif 17 | #else 18 | # ifdef TEST_SIGNED 19 | const char * DZ_OUT_FILE = "result/test_dz_signed_gcc.txt"; 20 | const char * SYS_OUT_FILE = "result/test_sys_signed_gcc.txt"; 21 | # else 22 | const char * DZ_OUT_FILE = "result/test_dz_unsigned_gcc.txt"; 23 | const char * SYS_OUT_FILE = "result/test_sys_unsigned_gcc.txt"; 24 | # endif 25 | #endif 26 | 27 | #ifdef TEST_HUGE 28 | ofstream outf(DZ_OUT_FILE); 29 | #else 30 | ofstream outf(SYS_OUT_FILE); 31 | #endif 32 | 33 | #ifdef TEST_FILE 34 | # define cout outf 35 | #endif 36 | 37 | void Test001(){ //constructor,assignment,ToString,ostream <<,istream >>,ToSigned,hex,oct,dec,uppercase,showbase 38 | cout<<"\tTest001\n"; 39 | const ios::fmtflags oldfmt = cout.flags(); 40 | __TestType a0,a1(__Signed(-431)),a2(__Unsigned(-252)); 41 | unsigned int ui = -3; 42 | __TestType b0(100),b1(int(-3)),b2 = ui; 43 | __TestType d(b0); 44 | a0 = -3; 45 | #ifdef FOR_DZ 46 | __TestType c0("-200"),c1("200"); 47 | cout<<"ToString: "<>a0; 64 | cout<>,++,--,>>=,<<=,abs 96 | cout<<"\tTest002\n"; 97 | __TestType a(100),b(-100); 98 | cout<<(a = -100)<>2)<>=3)<,>=,<= 126 | #define TEST003 127 | cout<<"\tTest003"<= av ? "Yes" : "No")<<' '<<(a < av ? "Yes" : "No")<= bv ? "Yes" : "No")<<' '<<(a < bv ? "Yes" : "No")<= cv ? "Yes" : "No")<= as ? "Yes" : "No")<<' '<<(a < as ? "Yes" : "No")<= bs ? "Yes" : "No")<<' '<<(a < bs ? "Yes" : "No")<= cs ? "Yes" : "No")<= a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(bv < a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(cv < a ? "Yes" : "No")<= a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(bs < a ? "Yes" : "No")<= a ? "Yes" : "No")<<' '<<(cs < a ? "Yes" : "No")<= b ? "Yes" : "No")<<' '<<(a < b ? "Yes" : "No")<= c ? "Yes" : "No")<<' '<<(a < c ? "Yes" : "No")<= d ? "Yes" : "No")< av ? "Yes" : "No")<<' '<<(a <= av ? "Yes" : "No")< bv ? "Yes" : "No")< cv ? "Yes" : "No")< as ? "Yes" : "No")<<' '<<(a <= as ? "Yes" : "No")< bs ? "Yes" : "No")< cs ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")<<' '<<(cv <= a ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")<<' '<<(cs <= a ? "Yes" : "No")< b ? "Yes" : "No")<<' '<<(a <= b ? "Yes" : "No")< c ? "Yes" : "No")< d ? "Yes" : "No")< b ? "Yes" : "No")< c ? "Yes" : "No")< d ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")< a ? "Yes" : "No")<= b ? "Yes" : "No")<= c ? "Yes" : "No")<= d ? "Yes" : "No")<= a ? "Yes" : "No")<= a ? "Yes" : "No")<= a ? "Yes" : "No")< //for std::overflow_error,std::runtime_error 9 | #include "Helper.h" 10 | 11 | namespace DoZerg{ 12 | template 13 | class HugeNumberBase 14 | { 15 | typedef HugeNumberBase __Myt; 16 | typedef DataTraits::DataTypeTrait __DTT; 17 | typedef void (__Myt::*__safe_bool_type)(int); 18 | protected: 19 | typedef typename __DTT::__Signed __Signed; 20 | typedef typename __DTT::__Unsigned __Unsigned; 21 | private: 22 | static const size_t EACH_BYTES = sizeof(__Signed); //bytes per data_ 23 | static const size_t EACH_BITS = 8 * EACH_BYTES; //bits per data_ 24 | static const size_t TOTAL_BITS = N * EACH_BITS; //total bits of data_[N] 25 | static const __Unsigned SignBit = __Unsigned(1) << (EACH_BITS - 1); 26 | __Unsigned data_[N]; //the highest data is data_[0],and the lowest is data_[N-1] 27 | public: 28 | static const size_t TOTAL_BYTES = N * EACH_BYTES; //total bytes of data_[N] 29 | __Signed ToSigned() const {return data_[N - 1];} 30 | const __Unsigned & ToUnsigned() const {return data_[N - 1];} 31 | bool GetSignBit() const {return (data_[0] & SignBit) != 0;} 32 | operator __safe_bool_type() const {return operator !() ? 0 : &__Myt::addOne;} 33 | bool operator !() const{ 34 | for(int i = 0;i < N;++i) 35 | if(data_[i] != 0) 36 | return false; 37 | return true; 38 | 39 | } 40 | //friend functions 41 | friend std::istream & operator >>(std::istream & is,__Myt & value){ 42 | std::string tmp; 43 | is>>tmp; 44 | value.FromString(tmp); 45 | return is; 46 | } 47 | protected: 48 | HugeNumberBase(){} 49 | HugeNumberBase(const __Myt & value){FromSelf(value);} 50 | HugeNumberBase(const __Signed & value,bool sign){FromValue(value,sign);} 51 | explicit HugeNumberBase(const std::string & value){FromString(value);} 52 | void FromSelf(const __Myt & value){ 53 | memcpy(data_,value.data_,TOTAL_BYTES); 54 | } 55 | void FromValue(__Signed value,bool sign){ 56 | reset(); 57 | if(sign){ 58 | if(value < 0) 59 | value = -value; 60 | else 61 | sign = false; 62 | } 63 | data_[N - 1] = __Unsigned(value); 64 | if(sign) 65 | Minus(); 66 | } 67 | void FromString(const std::string & value){ 68 | const int ASCII_0 = '0'; 69 | switch(StringHelper::CheckBaseFromString(value)){ //this function ensures the data format 70 | case 2:{ //0 71 | reset(); 72 | break;} 73 | case 8:{ 74 | reset(); 75 | int at(N - 1),bits(0); 76 | for(std::string::const_reverse_iterator v = value.rbegin();at >= 0 && *v != '+' && *v != '-' && v != value.rend();++v){ 77 | __Unsigned t((*v - ASCII_0) & 7); 78 | data_[at] += t << bits; 79 | if((bits += 3) >= EACH_BITS){ 80 | --at; 81 | if(bits -= EACH_BITS) 82 | data_[at] += (t >> (3 - bits)); 83 | } //if at < 0 then the passed value is too large 84 | }break;} 85 | case 10:{ 86 | reset(); 87 | std::string tmp(value); 88 | if(tmp[0] == '+' || tmp[0] == '-') 89 | tmp[0] = ASCII_0; 90 | StringHelper::ReverseString(tmp,-ASCII_0); 91 | bool zero; 92 | int at(N - 1),bits(0); 93 | do{ 94 | data_[at] += __Unsigned(StringHelper::DivideStringByTwo(tmp,zero)) << bits; 95 | if(++bits >= EACH_BITS){ 96 | --at; 97 | bits = 0; 98 | } 99 | }while(!zero && at >= 0); //if !zero then the passed value is too large 100 | break;} 101 | case 16:{ 102 | reset(); 103 | int at(N - 1),bits(0); 104 | for(std::string::const_reverse_iterator v = value.rbegin();*v != 'x' && *v != 'X' && at >= 0;++v){ 105 | __Unsigned t(((*v >= '0' && *v <= '9') ? *v - '0' : (*v >= 'a' && *v <= 'f') ? *v - 'a' + 10 : *v - 'A' + 10) & 0xF); 106 | data_[at] += (t << bits); 107 | if((bits += 4) >= EACH_BITS){ 108 | --at; 109 | if(bits -= EACH_BITS) 110 | data_[at] += (t >> (4 - bits)); 111 | } 112 | }break;} 113 | default:{ 114 | throw std::runtime_error("The passed data format is unknown"); 115 | } 116 | } 117 | if(value[0] == '-') 118 | Minus(); 119 | } 120 | void Increase(){ //operator ++() 121 | for(int i = N - 1;i >= 0 && !++data_[i];--i); 122 | } 123 | void Decrease(){ //operator --() 124 | int i = N - 1; 125 | for(;i >= 0 && !data_[i];--i); 126 | if(i < 0) 127 | reset(-1); 128 | else 129 | --data_[i]; 130 | } 131 | __Myt & Complement(){ //self ~() 132 | for(int i = 0;i < N;++i) 133 | data_[i] = ~data_[i]; 134 | return *this; 135 | } 136 | __Myt & Minus(){ //self -() 137 | __Unsigned carry(1); 138 | for(int i = N - 1;i >= 0;--i){ 139 | data_[i] = ~data_[i] + carry; 140 | carry = (data_[i] < carry ? __Unsigned(1) : __Unsigned(0)); 141 | } 142 | return *this; 143 | } 144 | __Myt & RightShift(int value,bool bsigned){ //the bool means whether to treat *this as a signed value //O(N) 145 | int rshift = value % TOTAL_BITS; 146 | if(!rshift) 147 | return *this; 148 | if(rshift < 0) 149 | rshift += TOTAL_BITS; 150 | int at = N - 1,start = rshift / EACH_BITS; 151 | rshift %= EACH_BITS; 152 | for(int i = N - start - 1;i > 0;--i) 153 | data_[at--] = (rshift != 0 ? (data_[i] >> rshift) + (data_[i - 1] << (EACH_BITS - rshift)) : data_[i]); 154 | if(bsigned){ 155 | data_[at--] = __Signed(data_[0]) >> rshift; 156 | __Signed t(GetSignBit() ? -1 : 0); 157 | for(int i = at;i >= 0;--i) 158 | data_[i] = t; 159 | }else{ 160 | data_[at--] = data_[0] >> rshift; 161 | for(int i = at;i >= 0;--i) 162 | data_[i] = 0; 163 | } 164 | return *this; 165 | } 166 | __Myt & LeftShift(int value){ 167 | int lshift = value % TOTAL_BITS; 168 | if(!lshift) 169 | return *this; 170 | if(lshift < 0) 171 | lshift += TOTAL_BITS; 172 | int at = 0,start = lshift / EACH_BITS; 173 | lshift %= EACH_BITS; 174 | for(int i = start;i < N - 1;++i) 175 | data_[at++] = lshift ? (data_[i] << lshift) + (data_[i + 1] >> (EACH_BITS - lshift)):data_[i]; 176 | data_[at++] = data_[N - 1] << lshift; 177 | for(int i = at;i < N;++i) 178 | data_[i] = 0; 179 | return *this; 180 | } 181 | __Myt & OperatorAdd(const __Myt & value){ 182 | __Unsigned carry(0); 183 | for(int i = N - 1;i >= 0;--i){ 184 | __Unsigned tmp(value.data_[i] + carry); 185 | data_[i] += tmp; 186 | carry = (tmp < carry || tmp > data_[i] ? 1 : 0); 187 | } 188 | return *this; //if carry then overflow 189 | } 190 | __Myt & OperatorSub(const __Myt & value){ 191 | __Unsigned carry(0); 192 | for(int i = N - 1;i >= 0;--i){ 193 | __Unsigned tmp(value.data_[i] + carry); 194 | carry = (tmp > data_[i] || tmp < value.data_[i] ? 1 : 0); 195 | data_[i] -= tmp; 196 | } 197 | return *this; //if carry then overflow 198 | } 199 | __Myt & OperatorMult(const __Myt & value){ 200 | __Myt tmp(*this),tmpvalue(value); //be aware of self mult like x.OperatorMult(x) 201 | reset(); 202 | __Signed carry(0); 203 | for(int i = N - 1,at = 0;i >= 0;--i) 204 | for(int j = 0;j < EACH_BITS;j += 2,at += 2){ 205 | __Signed t(((tmpvalue.data_[i] >> j) & 3) + carry - 1); //------------------------------- 206 | if(!t || t == 1){ 207 | OperatorAdd(tmp); 208 | if(t == 1) 209 | OperatorAdd(tmp); 210 | }else if(t == 2) 211 | OperatorSub(tmp); 212 | tmp.LeftShift(2); 213 | carry = (t > 1 ? 1 : 0); 214 | } 215 | return *this; 216 | } 217 | __Myt & OperatorAnd(const __Myt & value){ 218 | for(int i = 0;i < N;++i) 219 | data_[i] &= value.data_[i]; 220 | return *this; 221 | } 222 | __Myt & OperatorOr(const __Myt & value){ 223 | for(int i = 0;i < N;++i) 224 | data_[i] |= value.data_[i]; 225 | return *this; 226 | } 227 | __Myt & OperatorXor(const __Myt & value){ 228 | for(int i = 0;i < N;++i) 229 | data_[i] ^= value.data_[i]; 230 | return *this; 231 | } 232 | __Myt & OperatorDiv(const __Myt & value,bool result = true){ //return divided result if bool==true by default,otherwise return the modulus 233 | if(!value) 234 | throw std::overflow_error("Divided by Zero"); 235 | int xshift = value.highestBit(); 236 | if(xshift == value.lowestBit()) 237 | return (result ? RightShift(xshift) : resetHigherBits(xshift)); 238 | xshift = highestBit() - xshift; 239 | __Myt tmp(0); 240 | if(xshift >= 0){ 241 | __Myt tmpvalue(value); 242 | tmpvalue.LeftShift(xshift); 243 | bool bsign = GetSignBit() ^ tmpvalue.GetSignBit(); 244 | OperatorSub(tmpvalue); 245 | for(bsign ^= GetSignBit();xshift > 0 && NonZero();--xshift,bsign = GetSignBit()){ 246 | tmpvalue.rightShift1(); 247 | if(bsign) 248 | OperatorAdd(tmpvalue); 249 | else{ 250 | OperatorSub(tmpvalue); 251 | tmp.addOne(xshift); 252 | } 253 | } 254 | if(bsign) 255 | OperatorAdd(tmpvalue); 256 | else 257 | tmp.addOne(xshift); 258 | } 259 | if(result) 260 | operator =(tmp); 261 | return *this; 262 | } 263 | __Myt & OperatorPower(const __Myt & value){ 264 | if(!value) 265 | return FromInteger(1); 266 | __Myt tmp(*this),tmpvalue(value); //be aware of self power like x.OperatorPower(x) 267 | for(int at = tmpvalue.highestBit() - 1;at >= 0;--at){ 268 | OperatorMult(*this); 269 | if(((tmpvalue.data_[N - 1 - at / EACH_BITS] >> at) & 1) != 0) 270 | OperatorMult(tmp); 271 | } 272 | return *this; 273 | } 274 | bool OperatorEqual(const __Myt & value) const{ 275 | return !memcmp(data_,value.data_,TOTAL_BYTES); 276 | } 277 | bool OperatorSmaller(const __Myt & value,bool sign = false) const{ 278 | if(sign){ 279 | const bool mys = GetSignBit(); 280 | const bool notsame = mys ^ value.GetSignBit(); 281 | if(notsame) 282 | return mys; 283 | } 284 | for(int i = 0;i < N;++i) 285 | if(data_[i] != value.data_[i]) 286 | return data_[i] < value.data_[i]; 287 | return false; 288 | } 289 | std::string ToString(int BaseValue,bool bsigned,bool uppercase,bool showbase) const{ //the bool means whether to treat *this as a signed value 290 | const int ASCII_0 = '0'; 291 | std::string tmp,prefix; 292 | switch(BaseValue){ 293 | case 8:{ 294 | if(showbase) 295 | prefix.push_back(ASCII_0); 296 | for(int i = N - 1,shift = 0;i >= 0;){ 297 | __Unsigned t((data_[i] >> shift) & 7); 298 | tmp.push_back(int(t) + ASCII_0); //--------------------------------------- 299 | shift += 3; 300 | if(shift + 3 >= EACH_BITS){ 301 | __Unsigned tt(data_[i] >> shift); 302 | shift += 3 - EACH_BITS; 303 | if(--i >= 0) 304 | tt += (((__Unsigned(1) << shift) - 1) & data_[i]) << (3 - shift); 305 | tmp.push_back(int(tt) + ASCII_0); 306 | } 307 | } 308 | std::string::size_type pos(tmp.find_last_not_of(ASCII_0) + 1); //pos==0 if all '0' 309 | tmp.erase(pos ? pos : 1); 310 | StringHelper::ReverseString(tmp); 311 | break;} 312 | case 16:{ 313 | if(showbase) 314 | prefix = uppercase ? "0X" : "0x"; 315 | bool nonzero(false); 316 | for(int i = 0;i < N;++i){ 317 | if(!data_[i]){ 318 | if(nonzero){ 319 | char t[EACH_BYTES * 2 + 1] = {0}; 320 | memset(t,ASCII_0,EACH_BYTES * 2); 321 | tmp += t; 322 | } 323 | continue; 324 | } 325 | for(int j = EACH_BITS - 4;j >= 0 ;j -= 4){ 326 | __Unsigned t((data_[i] >> j) & 0xF); 327 | if(!t){ 328 | if(nonzero) 329 | tmp.push_back(ASCII_0); 330 | continue; 331 | } 332 | nonzero = true; 333 | tmp.push_back((uppercase ? "0123456789ABCDEF" : "0123456789abcdef")[size_t(t)]); 334 | } 335 | } 336 | if(!nonzero) //just 0 337 | tmp.push_back(ASCII_0); 338 | break;} 339 | default:{ 340 | tmp.push_back(0); 341 | if(bsigned && GetSignBit()){ 342 | for(int i = 0;i < N - 1;++i) 343 | for(int j = EACH_BITS - 1;j >= 0;--j) 344 | StringHelper::MutiStringWithTwo(tmp,(((data_[i] >> j) & 1) != 0 ? 0: 1)); //---------------- 345 | for(int j = EACH_BITS - 1;j > 0;--j) 346 | StringHelper::MutiStringWithTwo(tmp,(((data_[N - 1] >> j) & 1) != 0 ? 0: 1)); //--------------- 347 | StringHelper::MutiStringWithTwo(tmp,(data_[N-1] & 1) != 0 ? 1 : 2); 348 | tmp.push_back(int('-') - ASCII_0); //add '-'(45-48=-3) 349 | StringHelper::ReverseString(tmp,ASCII_0); 350 | }else{ 351 | for(int i = 0;i < N;++i) 352 | for(int j = EACH_BITS - 1;j >= 0;--j){ 353 | StringHelper::MutiStringWithTwo(tmp,(((data_[i] >> j) & 1) != 0 ? 1: 0)); //------------------- 354 | } 355 | StringHelper::ReverseString(tmp,ASCII_0); 356 | } 357 | } 358 | } 359 | return prefix + tmp; 360 | } 361 | private: 362 | void reset(int v = 0){ 363 | memset(data_,v,TOTAL_BYTES); 364 | } 365 | void addOne(int Position){ //add 1 in a particular position 366 | int at(N - 1 - Position / EACH_BITS); 367 | __Unsigned tmp(data_[at]); 368 | if((data_[at--] += (__Unsigned(1) << (Position % EACH_BITS))) < tmp) 369 | while(at >= 0 && !++data_[at]) 370 | --at; //if at<0 then overflow 371 | } 372 | int highestBit() const{ //return the highest bit position based on 0 373 | int at=0; 374 | while(at < N && !data_[at]) 375 | ++at; 376 | if(at >= N) 377 | return 0; 378 | int t(0); 379 | while(!((data_[at] << t) & SignBit)) 380 | ++t; 381 | return (N - at) * EACH_BITS - t - 1; 382 | } 383 | int lowestBit() const{ //return the lowest bit position based on 0 384 | int at(N - 1); 385 | while(at >= 0 && !data_[at]) 386 | --at; 387 | if(at < 0) 388 | return 0; 389 | int t(0); 390 | while(!((data_[at] >> t) & 1)) 391 | ++t; 392 | return (N - 1 - at) * EACH_BITS + t; 393 | } 394 | __Myt & resetHigherBits(int Position){ //reset the higher bits than a value to 0 395 | int at(N - 1 - Position / EACH_BITS); 396 | for(int i = 0;i < at;++i) 397 | data_[i] = 0; 398 | data_[at] &= (__Unsigned(1) << (Position % EACH_BITS)) - 1; 399 | return *this; 400 | } 401 | __Myt & rightShift1(){ //right shift 1 bit as a unsigned value(see data_'s declaration) 402 | for(int i = N - 1;i > 0;--i) 403 | data_[i] = ((data_[i] >> 1) + ((data_[i - 1] & 1) != 0 ? SignBit : 0)); 404 | data_[0] >>= 1; 405 | return *this; 406 | } 407 | }; 408 | } //namespace DoZerg 409 | 410 | #endif 411 | -------------------------------------------------------------------------------- /old/bak.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 by DoZerg. ALL RIGHTS RESERVED. 3 | * Consult your license regarding permissions and restrictions. 4 | */ 5 | #pragma once 6 | 7 | //redundant codes 8 | namespace MAIN_CPP{//main.cpp 9 | union CAF{ 10 | double a; 11 | struct{ 12 | long fl:32; 13 | long fh:20; 14 | long e:11; 15 | long s:1; 16 | }b; 17 | CAF(double x=0):a(x){ 18 | cout<class T> 58 | const TC & TC::fn(const TC & v) const{ 59 | cout<<"fn\n"; 60 | return *this; 61 | } 62 | templateclass T> 63 | void TC::gn(const TC & v){ 64 | cout<<"gn\n"; 65 | } 66 | templateclass T>class DT:public TC{}; 67 | 68 | char d2hex( int d ){ 69 | return "0123456789ABCDEF"[ d ]; 70 | } 71 | } 72 | namespace SIGNEDHUGELONG_H{//SignedHugeLong.h 73 | /*/#define TEMPLATE_HEAD templateclass _Alloc> 74 | //#define TEMPLATE_HEAD1 templateclass _Alloc> \ 75 | // template 76 | //#define MY_TYPE SignedHugeLong 77 | //#define MY_TYPE1 SignedHugeLong 78 | //For operator +,-,*,/ and % implementation 79 | #define SIGNED_MEMBER_DEFINE_OPERATOR(oper) \ 80 | template \ 81 | const SignedHugeLong operator ##oper##(const _ValueType & value) const{ \ 82 | return MY_TYPE(*this).operator ##oper##=(value); \ 83 | } \ 84 | const SignedHugeLong operator ##oper##(const SignedHugeLong & value) const{ \ 85 | return MY_TYPE(*this).operator ##oper##=(value); \ 86 | } 87 | #define SIGNED_GLOBAL_DEFINE_OPERATOR(oper) \ 88 | template \ 89 | inline const SignedHugeLong operator ##oper##(const _ValueType & value1,const SignedHugeLong & value2){ \ 90 | return SignedHugeLong(value1).operator ##oper##=(value2); \ 91 | } 92 | //*/ 93 | /* 94 | template 95 | const __Myt & operator -=(const MY_TYPE1 & value){ 96 | return OperatorSub(value); 97 | return *this; 98 | } 99 | template 100 | const __Myt & operator *=(const MY_TYPE1 & value){ 101 | return OperatorMult(value); 102 | return *this; 103 | } 104 | template 105 | const __Myt & operator /=(const MY_TYPE1 & value){ 106 | bool sign(GetSignBit()); 107 | if(sign) 108 | Minus(); 109 | OperatorDiv(abs(value)); 110 | if(sign^value.GetSignBit()) 111 | Minus(); 112 | return *this; 113 | } 114 | template 115 | const __Myt & operator &=(const MY_TYPE1 & value){ 116 | return OperatorAnd(value); 117 | return *this; 118 | } 119 | template 120 | const __Myt & operator |=(const MY_TYPE1 & value){ 121 | return OperatorOr(value); 122 | return *this; 123 | } 124 | template 125 | const __Myt & operator ^=(const MY_TYPE1 & value){ 126 | return OperatorXor(value); 127 | return *this; 128 | } 129 | template 130 | const __Myt & operator %=(const MY_TYPE1 & value){ 131 | bool sign(GetSignBit()); 132 | if(sign) 133 | Minus(); 134 | OperatorDiv(abs(value),false); 135 | if(sign) 136 | Minus(); 137 | return *this; 138 | } 139 | template 140 | bool operator ==(const MY_TYPE1 & value) const{return OperatorEqual(value);} 141 | template 142 | bool operator !=(const MY_TYPE1 & value) const{return !operator ==(value);} 143 | // SIGNED_MEMBER_DEFINE_OPERATOR(+); 144 | // SIGNED_MEMBER_DEFINE_OPERATOR(-); 145 | // SIGNED_MEMBER_DEFINE_OPERATOR(*); 146 | // SIGNED_MEMBER_DEFINE_OPERATOR(/); 147 | // SIGNED_MEMBER_DEFINE_OPERATOR(%); 148 | template 149 | friend __Myt Power(const __Myt & value1,const MY_TYPE1 & value2){ 150 | return __Myt(value1).OperatorPower(value); 151 | } 152 | friend bool operator >(const SignedHugeLong & value1,const SignedHugeLong & value2){ 153 | bool t(value2.GetSignBit()); 154 | if(t^value1.GetSignBit()) 155 | return t; 156 | return value1.OperatorLarger(value2); 157 | } 158 | friend bool operator <(const SignedHugeLong & value1,const SignedHugeLong & value2){ 159 | bool t(value1.GetSignBit()); 160 | if(t^value2.GetSignBit()) 161 | return t; 162 | return value1.OperatorSmaller(value2); 163 | } 164 | friend bool operator >=(const SignedHugeLong & value1,const SignedHugeLong & value2){ 165 | bool t(value2.GetSignBit()); 166 | if(t^value1.GetSignBit()) 167 | return t; 168 | return value1.OperatorNotSmaller(value2); 169 | } 170 | friend bool operator <=(const SignedHugeLong & value1,const SignedHugeLong & value2){ 171 | bool t(value1.GetSignBit()); 172 | if(t^value2.GetSignBit()) 173 | return t; 174 | return value1.OperatorNotLarger(value2); 175 | } 176 | // template 177 | // inline friend __OutStreamType & operator <<(__OutStreamType & os,const SignedHugeLong & value){ 178 | // return os< 183 | // inline bool operator ==(const __ValueType & value1,const MY_TYPE & value2){ 184 | // return value2.operator ==(value1); 185 | // } 186 | // template 187 | // inline bool operator !=(const __ValueType & value1,const MY_TYPE & value2){ 188 | // return value2.operator !=(value1); 189 | // } 190 | // SIGNED_GLOBAL_DEFINE_OPERATOR(+); 191 | // SIGNED_GLOBAL_DEFINE_OPERATOR(-); 192 | // SIGNED_GLOBAL_DEFINE_OPERATOR(*); 193 | // SIGNED_GLOBAL_DEFINE_OPERATOR(/); 194 | // SIGNED_GLOBAL_DEFINE_OPERATOR(%); 195 | //*/ 196 | //#undef SIGNED_MEMBER_DEFINE_OPERATOR 197 | //#undef SIGNED_GLOBAL_DEFINE_OPERATOR 198 | //#undef TEMPLATE_HEAD 199 | //#undef TEMPLATE_HEAD1 200 | //#undef MY_TYPE 201 | //#undef MY_TYPE1} 202 | namespace UNSIGNEDHUGELONG_H{//UnsignedHugeLong.h 203 | /*/#define TEMPLATE_HEAD templateclass _Alloc> 204 | //#define MY_TYPE1 UnsignedHugeLong 205 | //For operator +,-,*,/ and % implementation 206 | #define UNSIGNED_MEMBER_DEFINE_OPERATOR(oper) \ 207 | template \ 208 | const UnsignedHugeLong operator ##oper##(const __ValueType & value) const{ \ 209 | return __Myt(*this).operator ##oper##=(value); \ 210 | } \ 211 | const UnsignedHugeLong operator ##oper##(const UnsignedHugeLong & value) const{ \ 212 | return __Myt(*this).operator ##oper##=(value); \ 213 | } 214 | #define UNSIGNED_GLOBAL_DEFINE_OPERATOR(oper) \ 215 | template \ 216 | inline const UnsignedHugeLong operator ##oper##(const __ValueType & value1,const UnsignedHugeLong & value2){ \ 217 | return UnsignedHugeLong(value1).operator ##oper##=(value2); \ 218 | } 219 | //*/ 220 | /* 221 | const __Myt & operator +=(const __Myt &); 222 | const __Myt & operator -=(const __Myt &); 223 | const __Myt & operator *=(const __Myt &); 224 | const __Myt & operator /=(const __Myt &); 225 | const __Myt & operator &=(const __Myt &); 226 | const __Myt & operator |=(const __Myt &); 227 | const __Myt & operator ^=(const __Myt &); 228 | const __Myt & operator %=(const __Myt &); 229 | bool operator ==(const __Myt &) const; 230 | bool operator !=(const __Myt &) const; 231 | const __Myt Power(const __Myt &); 232 | const std::string ToString(int = 10) const; 233 | UNSIGNED_MEMBER_DEFINE_OPERATOR(+); 234 | UNSIGNED_MEMBER_DEFINE_OPERATOR(-); 235 | UNSIGNED_MEMBER_DEFINE_OPERATOR(*); 236 | UNSIGNED_MEMBER_DEFINE_OPERATOR(/); 237 | UNSIGNED_MEMBER_DEFINE_OPERATOR(%); 238 | //friend functions. for several reasons they can't be implemented outside 239 | inline friend bool operator >(const __Myt & value1,const __Myt & value2){ 240 | return value1.OperatorLarger(value2); 241 | } 242 | inline friend bool operator <(const __Myt & value1,const __Myt & value2){ 243 | return value1.OperatorSmaller(value2); 244 | } 245 | inline friend bool operator >=(const __Myt & value1,const __Myt & value2){ 246 | return value1.OperatorNotSmaller(value2); 247 | } 248 | inline friend bool operator <=(const __Myt & value1,const __Myt & value2){ 249 | return value1.OperatorNotLarger(value2); 250 | } 251 | template 252 | inline friend __OutStreamType & operator <<(__OutStreamType & os,const __Myt & value){ 253 | return os<>7); //is there a better way to deal with the base(8,10 or 16)? 257 | } 258 | //*/ 259 | /*/definition 260 | //public: 261 | TEMPLATE_HEAD inline __Myt & __Myt::operator =(const std::string & value){ 262 | FromString(value); 263 | return *this; 264 | } 265 | TEMPLATE_HEAD inline const __Myt __Myt::operator +() const{ 266 | return __Myt(*this); 267 | } 268 | TEMPLATE_HEAD inline const __Myt __Myt::operator -() const{ 269 | return __Myt(*this).Minus(); 270 | } 271 | TEMPLATE_HEAD inline const __Myt __Myt::operator ~() const{ 272 | return __Myt(*this).Complement(); 273 | } 274 | TEMPLATE_HEAD inline const __Myt __Myt::operator >>(long value) const{ 275 | return __Myt(*this).RightShift(value); 276 | } 277 | TEMPLATE_HEAD inline const __Myt __Myt::operator <<(long value) const{ 278 | return __Myt(*this).LeftShift(value); 279 | } 280 | TEMPLATE_HEAD inline const __Myt & __Myt::operator ++(){ //you could throw "overflow" if you want 281 | Increase(); 282 | return *this; 283 | } 284 | TEMPLATE_HEAD inline const __Myt __Myt::operator ++(int){ 285 | __Myt tmp(*this); 286 | operator ++(); 287 | return tmp; 288 | } 289 | TEMPLATE_HEAD inline const __Myt & __Myt::operator --(){ 290 | Decrease(); 291 | return *this; 292 | } 293 | TEMPLATE_HEAD inline const __Myt __Myt::operator --(int){ 294 | __Myt tmp(*this); 295 | operator --(); 296 | return tmp; 297 | } 298 | TEMPLATE_HEAD inline const __Myt & __Myt::operator >>=(long value){ 299 | RightShift(value); 300 | return *this; 301 | } 302 | TEMPLATE_HEAD inline const __Myt & __Myt::operator <<=(long value){ 303 | LeftShift(value); 304 | return *this; 305 | } 306 | TEMPLATE_HEAD inline const __Myt & __Myt::operator +=(const UnsignedHugeLong & value){ 307 | OperatorAdd(value); 308 | return *this; 309 | } 310 | TEMPLATE_HEAD inline const __Myt & __Myt::operator -=(const UnsignedHugeLong & value){ 311 | OperatorSub(value); 312 | return *this; 313 | } 314 | TEMPLATE_HEAD inline const __Myt & __Myt::operator *=(const UnsignedHugeLong & value){ 315 | OperatorMult(value); 316 | return *this; 317 | } 318 | TEMPLATE_HEAD inline const __Myt & __Myt::operator /=(const UnsignedHugeLong & value){ 319 | OperatorDiv(value); 320 | return *this; 321 | } 322 | TEMPLATE_HEAD inline const __Myt & __Myt::operator &=(const UnsignedHugeLong & value){ 323 | OperatorAnd(value); 324 | return *this; 325 | } 326 | TEMPLATE_HEAD inline const __Myt & __Myt::operator |=(const UnsignedHugeLong & value){ 327 | OperatorOr(value); 328 | return *this; 329 | } 330 | TEMPLATE_HEAD inline const __Myt & __Myt::operator ^=(const UnsignedHugeLong & value){ 331 | OperatorXor(value); 332 | return *this; 333 | } 334 | TEMPLATE_HEAD inline const __Myt & __Myt::operator %=(const UnsignedHugeLong & value){ 335 | OperatorDiv(value,false); 336 | return *this; 337 | } 338 | TEMPLATE_HEAD inline bool __Myt::operator ==(const UnsignedHugeLong & value) const{ 339 | return OperatorEqual(value); 340 | } 341 | TEMPLATE_HEAD inline bool __Myt::operator !=(const UnsignedHugeLong & value) const{ 342 | return !operator ==(value); 343 | } 344 | TEMPLATE_HEAD inline const __Myt __Myt::Power(const UnsignedHugeLong & value){ 345 | return __Myt(*this).OperatorPower(value); 346 | } 347 | TEMPLATE_HEAD inline const std::string __Myt::ToString(int BaseValue) const{ 348 | return HugeNumberBase::ToString(BaseValue); 349 | } 350 | //others: 351 | template 352 | inline bool operator ==(const __ValueType & value1,const __Myt & value2){ 353 | return value2.operator ==(value1); 354 | } 355 | template 356 | inline bool operator !=(const __ValueType & value1,const __Myt & value2){ 357 | return value2.operator !=(value1); 358 | } 359 | UNSIGNED_GLOBAL_DEFINE_OPERATOR(+); 360 | UNSIGNED_GLOBAL_DEFINE_OPERATOR(-); 361 | UNSIGNED_GLOBAL_DEFINE_OPERATOR(*); 362 | UNSIGNED_GLOBAL_DEFINE_OPERATOR(/); 363 | UNSIGNED_GLOBAL_DEFINE_OPERATOR(%); 364 | //*/ 365 | //#undef UNSIGNED_MEMBER_DEFINE_OPERATOR 366 | //#undef UNSIGNED_GLOBAL_DEFINE_OPERATOR 367 | //#undef TEMPLATE_HEAD 368 | //#undef MY_TYPE1 369 | } 370 | namespace HUGELONGNUMBER_H{//HugeLongNumber.h 371 | //#define TEMPLATE_HEAD templateclass _Alloc> 372 | //#define UNSIGNED_TYPE UnsignedHugeLong 373 | //#define SIGNED_TYPE SignedHugeLong 374 | //others: 375 | /* 376 | #define GLOBAL_DEFINE_OPERATOR(oper) \ 377 | template \ 378 | inline const UnsignedHugeLong operator ##oper##(const SignedHugeLong & value1,const UnsignedHugeLong & value2){ \ 379 | return UnsignedHugeLong(value2).operator ##oper##=(value1); \ 380 | } \ 381 | template \ 382 | inline const UnsignedHugeLong operator ##oper##(const UnsignedHugeLong & value1,const SignedHugeLong & value2){ \ 383 | return UnsignedHugeLong(value1).operator ##oper##=(value2); \ 384 | } 385 | GLOBAL_DEFINE_OPERATOR(+); 386 | GLOBAL_DEFINE_OPERATOR(-); 387 | GLOBAL_DEFINE_OPERATOR(*); 388 | GLOBAL_DEFINE_OPERATOR(/); 389 | GLOBAL_DEFINE_OPERATOR(%); 390 | #undef GLOBAL_DEFINE_OPERATOR 391 | //*/ 392 | //#undef TEMPLATE_HEAD 393 | //#undef UNSIGNED_TYPE 394 | //#undef SIGNED_TYPE 395 | } 396 | namespace HUGENUMBERBASE_H{//HugeNumberBase.h 397 | //forward declaration 398 | // TEMPLATE_HEAD class UnsignedHugeLong; 399 | // TEMPLATE_HEAD class SignedHugeLong; 400 | } 401 | namespace TESTS_H{//Tests.h 402 | /* 403 | SignedHugeLong<4,__Signed,DataInHeap> x(3); 404 | SignedHugeLong<4,__Signed,DataInStack> y(40); 405 | x += y; 406 | cout< x=-1; 517 | DoZerg::UnsignedHugeLong<40,__Signed,DataInHeap> y=-1; 518 | DoZerg::UnsignedHugeLong<50,__Signed,DataInHeap> z=-1; 519 | DoZerg::PerformanceProfile<3> pp; 520 | pp.Reset(); 521 | for(int i=0;i<3;++i) 522 | { 523 | DoZerg::Calculagraph cal(0); 524 | DoZerg::PerformanceProfile<3>::Start(); 525 | x.ToString(); 526 | cal(); 527 | DoZerg::PerformanceProfile<3>::PutMark(); 528 | y.ToString(); 529 | cal(); 530 | DoZerg::PerformanceProfile<3>::PutMark(); 531 | z.ToString(); 532 | cal(); 533 | DoZerg::PerformanceProfile<3>::End(); 534 | } 535 | pp.Result(); 536 | } 537 | void Test07() 538 | { //Test for operator == and != 539 | cout<<" Test 07"<=1000) 556 | cout<<"x="< x(5); 572 | SignedHugeLong<4,__Signed,DataInStack> y("3"); 573 | cout<<"x= "< 35 | explicit HugeNumber(const T & a) { from(__SupportTypeT(a)); } 36 | __Myt & operator =(const __Myt & a) = default; 37 | __Myt && operator =(__Myt && a) { 38 | if (&a != this) { 39 | data_ = std::move(a.data_); 40 | sign_ = a.sign_; 41 | } 42 | return std::move(*this); 43 | } 44 | template 45 | __Myt & operator =(const T & a) { from(__SupportTypeT(a)); return *this; } 46 | //a.swap(b); 47 | void swap(__Myt & a) noexcept { 48 | std::swap(sign_, a.sign_); 49 | data_.swap(a.data_); 50 | } 51 | //+a; 52 | __Myt operator +() { return *this; } 53 | //-a; 54 | __Myt operator -() { return std::move(__Myt(*this).negate()); } 55 | //++a; 56 | __Myt & operator ++() { *this += 1; return *this; } 57 | //--a; 58 | __Myt & operator --() { *this -= 1; return *this; } 59 | //a++; 60 | __Myt operator ++(int) { 61 | auto t(*this); 62 | ++*this; 63 | return std::move(t); 64 | } 65 | //a--; 66 | __Myt operator --(int) { 67 | auto t(*this); 68 | --*this; 69 | return std::move(t); 70 | } 71 | //a += b; 72 | __Myt & operator +=(const __Myt & a) { add(a.sign_, a.data_); return *this; } 73 | template 74 | __Myt & operator +=(const T & a) { add(__SupportTypeT(a)); return *this; } 75 | //a -= b; 76 | __Myt & operator -=(const __Myt & a) { add(!a.sign_, a.data_); return *this; } 77 | template 78 | __Myt & operator -=(const T & a) { sub(__SupportTypeT(a)); return *this; } 79 | //a *= b; 80 | __Myt & operator *=(const __Myt & a) { mul(a.sign_, a.data_); return *this; } 81 | template 82 | __Myt & operator *=(const T & a) { mul(__SupportTypeT(a)); return *this; } 83 | //a /= b; 84 | __Myt & operator /=(const __Myt & a) { div(a); return *this; } 85 | template 86 | __Myt & operator /=(const T & a) { return (*this /= __Myt(a)); } 87 | //a %= b; 88 | __Myt & operator %=(const __Myt & a) { mod(a); return *this; } 89 | template 90 | __Myt & operator %=(const T & a) { return (*this %= __Myt(a)); } 91 | //a <<= n; 92 | __Myt & operator <<=(int a) { (a < 0 ? shiftRight(-a) : shiftLeft(a)); return *this; } 93 | //a >>= n; 94 | __Myt & operator >>=(int a) { (a < 0 ? shiftLeft(-a) : shiftRight(a)); return *this; } 95 | //a + b; 96 | __Myt operator +(const __Myt & a) const { return std::move(__Myt(*this) += a); } 97 | template 98 | __Myt operator +(const T & a) const { return std::move(__Myt(*this) += a); } 99 | template 100 | friend __Myt operator +(const T & a, const __Myt & b) { return (b + a); } 101 | //a - b; 102 | __Myt operator -(const __Myt & a) const { return std::move(__Myt(*this) -= a); } 103 | template 104 | __Myt operator -(const T & a) const { return std::move(__Myt(*this) -= a); } 105 | template 106 | friend __Myt operator -(const T & a, const __Myt & b) { return std::move(__Myt(b - a).negate()); } 107 | //a * b; 108 | __Myt operator *(const __Myt & a) const { return std::move(__Myt(*this) *= a); } 109 | template 110 | __Myt operator *(const T & a) const { return std::move(__Myt(*this) *= a); } 111 | template 112 | friend __Myt operator *(const T & a, const __Myt & b) { return (b * a); } 113 | //a / b; 114 | __Myt operator /(const __Myt & a) const { return std::move(__Myt(*this) /= a); } 115 | template 116 | __Myt operator /(const T & a) const { return std::move(__Myt(*this) /= a); } 117 | template 118 | friend __Myt operator /(const T & a, const __Myt & b) { return std::move(__Myt(a) /= b); } 119 | //a % b; 120 | __Myt operator %(const __Myt & a) const { return std::move(__Myt(*this) %= a); } 121 | template 122 | __Myt operator %(const T & a) const { return std::move(__Myt(*this) %= a); } 123 | template 124 | friend __Myt operator %(const T & a, const __Myt & b) { return std::move(__Myt(a) %= b); } 125 | //a << n; 126 | __Myt operator <<(int a) const { return std::move(__Myt(*this) <<= a); } 127 | //a >> n; 128 | __Myt operator >>(int a) const { return std::move(__Myt(*this) >>= a); } 129 | //if(a){} 130 | explicit operator bool() const { return !operator !(); } 131 | //if(!a){} 132 | bool operator !() const { return data_.empty(); } 133 | //a == b; 134 | bool operator ==(const __Myt & a) const { return (sign_ == a.sign_ && data_ == a.data_); } 135 | template 136 | bool operator ==(const T & a) const { return equal(__SupportTypeT(a)); } 137 | template 138 | friend bool operator ==(const T & a, const __Myt & b) { return (b == a); } 139 | //a != b; 140 | bool operator !=(const __Myt & a) const { return !(*this == a); } 141 | template 142 | bool operator !=(const T & a) const { return !(*this == a); } 143 | template 144 | friend bool operator !=(const T & a, const __Myt & b) { return (b != a); } 145 | //a < b; 146 | bool operator <(const __Myt & a) const { return less(a.sign_, a.data_); } 147 | template 148 | bool operator <(const T & a) const { return less(__SupportTypeT(a)); } 149 | template 150 | friend bool operator <(const T & a, const __Myt & b) { return (b > a); } 151 | //a > b; 152 | bool operator >(const __Myt & a) const { return (a < *this); } 153 | template 154 | bool operator >(const T & a) const { return greater(__SupportTypeT(a)); } 155 | template 156 | friend bool operator >(const T & a, const __Myt & b) { return (b < a); } 157 | //a <= b; 158 | bool operator <=(const __Myt & a) const { return !(a < *this); } 159 | template 160 | bool operator <=(const T & a) const { return !(a < *this); } 161 | template 162 | friend bool operator <=(const T & a, const __Myt & b) { return !(b < a); } 163 | //a >= b; 164 | bool operator >=(const __Myt & a) const { return !(*this < a); } 165 | template 166 | bool operator >=(const T & a) const { return !(*this < a); } 167 | template 168 | friend bool operator >=(const T & a, const __Myt & b) { return !(a < b); } 169 | //a.toString(); 170 | std::string toString(int base = 10, bool uppercase = false, bool showbase = false) const { 171 | const char * const kDigits = (uppercase ? "0123456789ABCDEF" : "0123456789abcdef"); 172 | switch (base) { 173 | case 16:return toStringX<4>(kDigits, (showbase ? (uppercase ? "X0" : "x0") : nullptr)); 174 | case 10:return toString10(); 175 | case 8:return toStringX<3>(kDigits, (showbase ? "0" : nullptr)); 176 | case 2:return toStringX<1>(kDigits, (showbase ? (uppercase ? "B0" : "b0") : nullptr)); 177 | default:; 178 | } 179 | throw std::invalid_argument("Unsupported base"); 180 | return std::string(); 181 | } 182 | //cout<(data_, p, *it++ - '0')); 209 | break; } 210 | case 8: { 211 | reset('-' == a[0]); 212 | int p = 0; 213 | for (auto it = a.rbegin(); it != a.rend() && '+' != *it && '-' != *it; toBits<3>(data_, p, *it++ - '0')); 214 | break; } 215 | case 10: { 216 | reset('-' == a[0]); 217 | std::string t(a); 218 | if ('+' == t[0] || '-' == t[0]) 219 | t[0] = '0'; 220 | reverseAdd(t, -'0'); 221 | int p = 0; 222 | for (bool end = false; !end; toBitsF<1>(data_, p, [&t, &end] { 223 | int c = 0; 224 | for (auto it = t.rbegin(); it != t.rend(); ++it) { 225 | *it += c * 10; 226 | c = (*it & 1); 227 | *it /= 2; 228 | } 229 | const auto p = t.find_last_not_of(char(0)) + 1; 230 | end = !p; 231 | t.erase(p); 232 | return c; 233 | })); 234 | break; } 235 | case 16: { 236 | reset('-' == a[0]); 237 | int p = 0; 238 | for (auto it = a.rbegin(); it != a.rend() && 'x' != *it && 'X' != *it; toBitsF<4>(data_, p, [&it] { 239 | const char c = *it++; 240 | if ('0' <= c && c <= '9') 241 | return (c - '0'); 242 | if ('a' <= c && c <= 'f') 243 | return (c - 'a' + 10); 244 | return (c - 'A' + 10); 245 | })); 246 | break; } 247 | default:throw std::invalid_argument("Input is not an integer number"); 248 | } 249 | shrink(); 250 | } 251 | __Myt & negate() { 252 | if (*this) 253 | sign_ = !sign_; 254 | return *this; 255 | } 256 | void add(const __Int & a) { add(false, a); } 257 | void add(const __SInt & a) { add((a < 0), abs(a)); } 258 | void add(const std::string & a) { *this += __Myt(a); } 259 | template 260 | void add(bool s, const T & a) { 261 | if (sign_ == s) { 262 | addAbs(a); 263 | return; 264 | } 265 | switch (compare(a)) { 266 | case 0:reset(); break; 267 | case 1:subAbs(a); break; 268 | default:sign_ = s; subByAbs(a); 269 | } 270 | } 271 | void sub(const __Int & a) { add(true, a); } 272 | void sub(const __SInt & a) { add((a > 0), abs(a)); } 273 | void sub(const std::string & a) { *this -= __Myt(a); } 274 | void mul(const __SInt & a) { mul(abs(a), (a < 0)); } 275 | void mul(const __Int & a, bool s = false) { 276 | if (mulSign(s, !a, (1 == a))) 277 | return; 278 | __Myt t(*this), r; 279 | for (__Int i = a; i; i >>= 1, t <<= 1) 280 | if (0 != (i & 1)) 281 | r += t; 282 | data_.swap(r.data_); 283 | shrink(); 284 | } 285 | void mul(const std::string & a) { *this *= __Myt(a); } 286 | void mul(bool s, const __Data & a) { 287 | if (mulSign(s, a.empty(), false)) 288 | return; 289 | __Myt t(*this), r; 290 | forBits<1>(a, 0, [&r, &t](const auto & i) { 291 | if (i) 292 | r += t; 293 | t <<= 1; 294 | }); 295 | data_.swap(r.data_); 296 | shrink(); 297 | } 298 | void div(const __Myt & a) { 299 | if (!a) 300 | throw std::runtime_error("Divided by 0"); 301 | if (!*this) 302 | return; 303 | const int p = topBit(data_) - topBit(a.data_) + 1; 304 | if (p > 0) { 305 | __Myt d, r; 306 | divModAbs(a, d, r, p); 307 | data_.swap(d.data_); 308 | sign_ = (sign_ != a.sign_); 309 | shrink(); 310 | } else 311 | reset(); 312 | } 313 | void mod(const __Myt & a) { 314 | if (!a) 315 | throw std::runtime_error("Divided by 0"); 316 | if (!*this) 317 | return; 318 | const int p = topBit(data_) - topBit(a.data_) + 1; 319 | if (p > 0) { 320 | __Myt q, r; 321 | divModAbs(a, q, r, p); 322 | data_.swap(r.data_); 323 | shrink(); 324 | } 325 | } 326 | void divModAbs(const __Myt & a, __Myt & q, __Myt & r, int p) const { 327 | r.data_ = data_; 328 | q.data_.clear(); 329 | assert(0 < p); 330 | __Myt t(a << (p - 1)); 331 | t.sign_ = false; 332 | for (;; t >>= 1) { 333 | if (t <= r) { 334 | r -= t; 335 | toBitsReverse<1>(q.data_, p, 1); 336 | } else 337 | --p; 338 | if (p < 1) 339 | break; 340 | } 341 | } 342 | void shiftLeft(int a) { 343 | if (a < 0) 344 | throw std::invalid_argument("Invalid shift bits"); 345 | if (!a || !*this) 346 | return; 347 | __Data r; 348 | for (const auto & v : data_) 349 | toBits(r, a, v); 350 | data_.swap(r); 351 | shrink(); 352 | } 353 | void shiftRight(int a) { 354 | if (a < 0) 355 | throw std::invalid_argument("Invalid shift bits"); 356 | if (!a) 357 | return; 358 | __Data r; 359 | forBits(data_, a, [&r](const auto & v) {r.push_back(v); }); 360 | data_.swap(r); 361 | shrink(); 362 | } 363 | bool equal(const __SInt & a) const { return (sign_ == (a < 0) && 0 == compare(abs(a))); } 364 | bool equal(const __Int & a) const { return (!sign_ && 0 == compare(a)); } 365 | bool equal(const std::string & a) const { return (*this == __Myt(a)); } 366 | bool less(const __Int & a) const { return less(false, a); } 367 | bool less(const __SInt & a) const { return less((a < 0), abs(a)); } 368 | bool less(const std::string & a) const { return (*this < __Myt(a)); } 369 | template 370 | bool less(bool s, const T & a) const { 371 | if (sign_ != s) 372 | return sign_; 373 | const int r = compare(a); 374 | return (sign_ ? (1 == r) : (-1 == r)); 375 | } 376 | bool greater(const __Int & a) const { return greater(false, a); } 377 | bool greater(const __SInt & a) const { return greater((a < 0), abs(a)); } 378 | bool greater(const std::string & a) const { return (*this > __Myt(a)); } 379 | bool greater(bool s, const __Int & a) const { 380 | if (sign_ != s) 381 | return !sign_; 382 | const int r = compare(a); 383 | return (sign_ ? (-1 == r) : (1 == r)); 384 | } 385 | 386 | void reset(bool s = false) { sign_ = s; data_.clear(); } 387 | void shrink() { 388 | eraseTailIf(data_, [](auto v) {return (0 == v); }); 389 | if (data_.empty() && sign_) 390 | sign_ = false; 391 | } 392 | template 393 | std::string toStringX(const char * digits, const char * base) const { 394 | static_assert(N > 0, "N is less than 1"); 395 | std::string ret; 396 | if (data_.empty()) 397 | ret.push_back('0'); 398 | else { 399 | forBits(data_, 0, [&ret, &digits](const auto & i) {ret.push_back(digits[i]); }); 400 | eraseTailIf(ret, [](auto c) {return ('0' == c); }); 401 | } 402 | if (base) 403 | ret += base; 404 | if (sign_) 405 | ret.push_back('-'); 406 | std::reverse(ret.begin(), ret.end()); 407 | return std::move(ret); 408 | } 409 | std::string toString10() const { 410 | std::string ret; 411 | forBitsReverse<1>(data_, 0, [&ret](const auto & v) { 412 | int add = static_cast(v); 413 | assert(0 <= add && add < 10); 414 | if (!ret.empty()) 415 | for (char & c : ret) { 416 | c = (c << 1) + add; 417 | if ((add = (c > 9 ? 1 : 0))) 418 | c -= 10; 419 | } 420 | if (add) 421 | ret.push_back(add); 422 | }); 423 | if (ret.empty()) 424 | ret.push_back(0); 425 | if (sign_) 426 | ret.push_back('-' - '0'); 427 | reverseAdd(ret, '0'); 428 | return std::move(ret); 429 | } 430 | int compare(const __Int & a) const { 431 | if (!a) 432 | return (data_.empty() ? 0 : 1); 433 | if (data_.size() < 1) 434 | return -1; 435 | else if (data_.size() > 1) 436 | return 1; 437 | return (data_[0] < a ? -1 : (data_[0] > a ? 1 : 0)); 438 | } 439 | int compare(const __Data & a) const { 440 | if (data_.size() < a.size()) 441 | return -1; 442 | else if (data_.size() > a.size()) 443 | return 1; 444 | for (int i = int(a.size() - 1); i >= 0; --i) 445 | if (data_[i] < a[i]) 446 | return -1; 447 | else if (data_[i] > a[i]) 448 | return 1; 449 | return 0; 450 | } 451 | void addAbs(const __Int & a) { (a ? addAbs({}, a) : (void)0); } 452 | void addAbs(const __Data & a, const __Int & b = 0) { 453 | if (!b) { 454 | if (a.empty()) 455 | return; 456 | if (data_.empty()) { 457 | data_ = a; 458 | return; 459 | } 460 | } 461 | __Int c = b; 462 | for (size_t i = 0; i < a.size() || c; ++i) { 463 | __Int t = c; 464 | c = 0; 465 | if (i < a.size()) 466 | c += plus(t, a[i]); 467 | if (i < data_.size()) 468 | c += plus(data_[i], t); 469 | else 470 | data_.push_back(t); 471 | } 472 | } 473 | void subAbs(const __Int & a) { (a ? subAbs({}, a) : (void)0); } 474 | void subAbs(const __Data & a, const __Int & b = 0) { 475 | if (a.empty() && !b) 476 | return; 477 | __Int c = b; 478 | for (size_t i = 0; i < a.size() || c; ++i) { 479 | c = minus(data_[i], c); 480 | if (i < a.size()) 481 | c += minus(data_[i], a[i]); 482 | } 483 | shrink(); 484 | } 485 | void subByAbs(const __Int & a) { (a ? subByAbs({}, a) : (void)0); } 486 | void subByAbs(const __Data & a, const __Int & b = 0) { 487 | if (data_.empty() && !b) { 488 | data_ = a; 489 | return; 490 | } 491 | __Data r; 492 | __Int c = b, d = 0; 493 | for (size_t i = 0; i < a.size() || c || d; ++i) { 494 | __Int t = c; 495 | c = 0; 496 | d = minus(t, d); 497 | if (i < a.size()) 498 | c += plus(t, a[i]); 499 | if (i < data_.size()) 500 | d += minus(t, data_[i]); 501 | if (c == d) 502 | c = d = 0; 503 | r.push_back(t); 504 | } 505 | r.swap(data_); 506 | shrink(); 507 | } 508 | bool mulSign(bool s, bool zero, bool one) { 509 | if (!*this) 510 | return true; 511 | if (zero) { 512 | reset(); 513 | return true; 514 | } 515 | sign_ = (sign_ != s); 516 | return one; 517 | } 518 | static __Int abs(const __SInt & a) { return (a < 0 ? -a : a); } 519 | static int plus(__Int & a, const __Int & b) { 520 | const auto t(a); 521 | a += b; 522 | return (a < t || a < b ? 1 : 0); 523 | } 524 | static int minus(__Int & a, const __Int & b) { 525 | const int r = (a < b ? 1 : 0); 526 | a -= b; 527 | return r; 528 | } 529 | static int topBit(const __Data & a) { 530 | if (a.empty()) 531 | return 0; 532 | int i = kEachBits - 1; 533 | for (; i >= 0 && !(a.back() & (__Int(1) << i)); --i); 534 | return int(i + kEachBits * (a.size() - 1)); 535 | } 536 | template 537 | static void eraseTailIf(T & c, F && f) { 538 | auto it = c.rbegin(); 539 | if (it != c.rend() && f(*it)) { 540 | for (++it; it != c.rend() && f(*it); ++it); 541 | c.erase(it.base(), c.end()); 542 | } 543 | } 544 | static constexpr __Int mask(int bits) { return (bits < 1 ? 0 : (bits >= kEachBits ? __Int(-1) : ((__Int(1) << bits) - 1))); } 545 | static constexpr __Int getBits(const __Int & val, int from, int bits) { return ((val >> from) & mask(bits)); } 546 | template 547 | static __Int getBits(const __Data & data, int from) { 548 | static_assert(0 < N && N <= kEachBits, "read invlaid bits"); 549 | const int fi = from / kEachBits, ri = from % kEachBits; 550 | assert(size_t(fi) < data.size()); 551 | __Int val = getBits(data[fi], ri, N); 552 | if (kEachBits - N < ri && size_t(fi + 1) < data.size()) { 553 | const int s1 = kEachBits - ri, s2 = N - s1; 554 | setBits(val, s1, s2, getBits(data[fi + 1], 0, s2)); 555 | } 556 | return val; 557 | } 558 | static void setBits(__Int & ret, int from, int bits, const __Int & val) { 559 | assert(0 <= from && from < kEachBits); 560 | const __Int m = mask(bits); 561 | ret &= ~(m << from); 562 | ret += (val & m) << from; 563 | } 564 | template 565 | static void setBits(__Int & ret, int from, const __Int & val) { 566 | assert(0 <= from && from < kEachBits); 567 | constexpr __Int m = mask(N); 568 | ret &= ~(m << from); 569 | ret += (val & m) << from; 570 | } 571 | template 572 | static void setBits(__Data & data, int from, const __Int & val) { 573 | static_assert(0 < N && N <= kEachBits, "write invalid bits"); 574 | const int fi = from / kEachBits, ri = from % kEachBits; 575 | assert(size_t(fi) < data.size()); 576 | setBits(data[fi], ri, val); 577 | if (kEachBits - N < ri && size_t(fi + 1) < data.size()) { 578 | const int s1 = kEachBits - ri, s2 = N - s1; 579 | setBits(data[fi + 1], 0, s2, getBits(val, s1, s2)); 580 | } 581 | } 582 | template 583 | static void forBits(const __Data & data, int from, F && func) { 584 | for (const int kTotalBits = int(kEachBits * data.size()); from < kTotalBits; from += N) 585 | func(getBits(data, from)); 586 | } 587 | template 588 | static void forBitsReverse(const __Data & data, int from, F && func) { 589 | for (const int kTotalBits = int(kEachBits * data.size()); from < kTotalBits; from += N) 590 | func(getBits(data, kTotalBits - N - from)); 591 | } 592 | template 593 | static void toBits(__Data & data, int & from, const __Int & val) { 594 | const int kTotalBits = int(kEachBits * data.size()); 595 | if (kTotalBits < from + N) 596 | data.resize((from + N + kEachBits - 1) / kEachBits); 597 | setBits(data, from, val); 598 | from += N; 599 | } 600 | template 601 | static void toBitsF(__Data & data, int & from, F && func) { toBits(data, from, func()); } 602 | template 603 | static void toBitsReverse(__Data & data, int & from, const __Int & val) { 604 | assert(from >= N); 605 | const int kTotalBits = int(kEachBits * data.size()); 606 | if (kTotalBits < from) 607 | data.resize((from + kEachBits - 1) / kEachBits); 608 | setBits(data, from - N, val); 609 | from -= N; 610 | } 611 | static void reverseAdd(std::string & s, int v) { 612 | for (int i = 0, j = int(s.size() - 1); i <= j; ++i, --j) { 613 | const auto t = s[i]; 614 | s[i] = s[j] + v; 615 | if (i < j) 616 | s[j] = t + v; 617 | } 618 | } 619 | //return: 620 | // 0 empty string 621 | // 2 base is 2 622 | // 3 for "0", "-0", "+0", base is 10 623 | // 8 base is 8 624 | // 10 base is 10 625 | // 16 base is 16 626 | // others error 627 | static int checkBase(const std::string & a) { 628 | int r = 0; 629 | for (auto c : a) { 630 | switch (r) { 631 | case 0: 632 | if ('+' == c || '-' == c) 633 | break; 634 | case 1: 635 | if ('0' == c) { 636 | r = 3; 637 | break; 638 | } 639 | case 10:r = ('0' <= c && c <= '9' ? 10 : -1); break; 640 | case 3: 641 | if ('b' == c || 'B' == c) { 642 | r = 5; 643 | break; 644 | } else if ('x' == c || 'X' == c) { 645 | r = 7; 646 | break; 647 | } 648 | case 8:r = ('0' <= c && c < '8' ? 8 : -1); break; 649 | case 2: 650 | case 5:r = ('0' == c || '1' == c ? 2 : -1); break; 651 | case 7: 652 | case 16:r = (('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') ? 16 : -1); break; 653 | } 654 | if (r < 0) 655 | break; 656 | } 657 | return r; 658 | } 659 | //fields 660 | __Data data_; 661 | bool sign_ = false; 662 | }; 663 | 664 | //explicit specializations for member class template 665 | template<>struct HugeNumber::__SupportType { typedef const std::string & type; }; 666 | template<>struct HugeNumber::__SupportType { typedef const std::string & type; }; 667 | template<>struct HugeNumber::__SupportType { typedef const std::string & type; }; 668 | //templatestruct HugeNumber::__SupportType{typedef const std::string & type;}; 669 | templatestruct HugeNumber::__SupportType { typedef const std::string & type; }; 670 | #define __SUPPORT_INTEGER(tp) \ 671 | template<>struct HugeNumber::__SupportType{ \ 672 | typedef const __TypeSelect::is_signed, __SInt, __Int>::type & type; \ 673 | } 674 | __SUPPORT_INTEGER(char); 675 | __SUPPORT_INTEGER(wchar_t); 676 | __SUPPORT_INTEGER(char16_t); 677 | __SUPPORT_INTEGER(char32_t); 678 | __SUPPORT_INTEGER(signed char); 679 | __SUPPORT_INTEGER(unsigned char); 680 | __SUPPORT_INTEGER(short); 681 | __SUPPORT_INTEGER(unsigned short); 682 | __SUPPORT_INTEGER(int); 683 | __SUPPORT_INTEGER(unsigned int); 684 | __SUPPORT_INTEGER(long); 685 | __SUPPORT_INTEGER(unsigned long); 686 | __SUPPORT_INTEGER(long long); 687 | __SUPPORT_INTEGER(unsigned long long); 688 | #undef __SUPPORT_INTEGER 689 | 690 | //swap(a, b); 691 | inline void swap(HugeNumber & a, HugeNumber & b) noexcept { 692 | a.swap(b); 693 | } 694 | } // namespace dozerg 695 | 696 | #endif 697 | -------------------------------------------------------------------------------- /test/unit_test.cpp: -------------------------------------------------------------------------------- 1 | #include "huge_number.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | typedef dozerg::HugeNumber Int; 11 | 12 | #ifdef _WIN32 13 | # define __PRETTY_FUNCTION__ __FUNCSIG__ 14 | #endif 15 | 16 | #define ASSERT_EQ(aa, bb) assert_eq(aa, bb, __LINE__, __PRETTY_FUNCTION__) 17 | 18 | void assert_eq(string a, string b, int line, const char * func) 19 | { 20 | if(a == b) 21 | return; 22 | cerr << "not equal at line " << line << ":\na=" << a << "\nb=" << b << endl 23 | << "in " << func << endl; 24 | throw 1; 25 | } 26 | 27 | void assert_eq(bool a, bool b, int line, const char * func) 28 | { 29 | if(a == b) 30 | return; 31 | cerr << "not equal at line " << line << ":\na=" << boolalpha<< a << "\nb=" << b << endl 32 | << "in " << func << endl; 33 | throw 1; 34 | } 35 | 36 | void assert_eq(string a, const Int & b, int line, const char * func) 37 | { 38 | if(a == b.toString()) 39 | return; 40 | cerr << "not equal at line " << line << ":\na=" << a << "\nb=" << b << endl 41 | << "in " << func << endl; 42 | throw 1; 43 | } 44 | 45 | void assert_eq(const Int & a, const Int & b, int line, const char * func) 46 | { 47 | if(a == b) 48 | return; 49 | cerr << "not equal at line " << line << ":\na=" << a << "\nb=" << b << endl 50 | << "in " << func << endl; 51 | throw 1; 52 | } 53 | 54 | void assert_eq(const char * a, const Int & b, int line, const char * func) 55 | { 56 | assert_eq(string(a), b, line, func); 57 | } 58 | 59 | template 60 | void assert_eq(const T & a, const Int & b, int line, const char * func) 61 | { 62 | ostringstream oss; 63 | if(sizeof(T) < sizeof(int)) 64 | oss<(a); 65 | else 66 | oss< u(from, to); 75 | return u(gen); 76 | } 77 | 78 | char genChar(string s) 79 | { 80 | assert(!s.empty()); 81 | return s[genRand(0, int(s.size() - 1))]; 82 | } 83 | 84 | template 85 | void genArray(T & a, size_t len, typename T::value_type from, typename T::value_type to) 86 | { 87 | uniform_int_distribution u(from, to); 88 | for(size_t i = 0;i < len;++i, a.push_back(u(gen))); 89 | } 90 | 91 | template 92 | void genArray(T & a, size_t len, const T & b) 93 | { 94 | assert(!b.empty()); 95 | uniform_int_distribution u(0, b.size() - 1); 96 | for(size_t i = 0;i < len;++i, a.push_back(b[u(gen)])); 97 | } 98 | 99 | template 100 | void test_ctor_type() 101 | { 102 | for(int i = -100;i <= 100;++i){ 103 | const T ma = numeric_limits::max() + i; 104 | const T mi = numeric_limits::min() + i; 105 | const T z = i; 106 | Int a(ma), b(mi), c(z), aa, bb, cc; 107 | ASSERT_EQ(ma, a); 108 | ASSERT_EQ(mi, b); 109 | ASSERT_EQ(z, c); 110 | aa = ma; 111 | bb = mi; 112 | cc = z; 113 | ASSERT_EQ(ma, aa); 114 | ASSERT_EQ(mi, bb); 115 | ASSERT_EQ(z, cc); 116 | aa = aa; 117 | bb = bb; 118 | cc = cc; 119 | ASSERT_EQ(ma, aa); 120 | ASSERT_EQ(mi, bb); 121 | ASSERT_EQ(z, cc); 122 | } 123 | } 124 | 125 | void test_ctor_str_base_case(int base, bool upper, string bstr, string head, string body) 126 | { 127 | constexpr int kSize = 200; 128 | string s(bstr); 129 | s.push_back(genChar(head)); 130 | genArray(s, kSize, body); 131 | { 132 | char ss[kSize + 16]; 133 | const char (&css)[sizeof ss] = ss; 134 | { 135 | strcpy(ss, s.c_str()); 136 | Int a(s), b(s.c_str()), c(ss), d(css), aa, bb, cc, dd; 137 | ASSERT_EQ(s, a.toString(base, upper, true)); 138 | ASSERT_EQ(s, b.toString(base, upper, true)); 139 | ASSERT_EQ(s, c.toString(base, upper, true)); 140 | ASSERT_EQ(s, d.toString(base, upper, true)); 141 | aa = s; 142 | bb = s.c_str(); 143 | cc = ss; 144 | dd = css; 145 | ASSERT_EQ(s, aa.toString(base, upper, true)); 146 | ASSERT_EQ(s, bb.toString(base, upper, true)); 147 | ASSERT_EQ(s, cc.toString(base, upper, true)); 148 | ASSERT_EQ(s, dd.toString(base, upper, true)); 149 | }{ 150 | string t('+' + s); 151 | strcpy(ss, t.c_str()); 152 | Int a(s), b(s.c_str()), c(ss), d(css), aa, bb, cc, dd; 153 | ASSERT_EQ(s, a.toString(base, upper, true)); 154 | ASSERT_EQ(s, b.toString(base, upper, true)); 155 | ASSERT_EQ(s, c.toString(base, upper, true)); 156 | ASSERT_EQ(s, d.toString(base, upper, true)); 157 | aa = s; 158 | bb = s.c_str(); 159 | cc = ss; 160 | dd = css; 161 | ASSERT_EQ(s, aa.toString(base, upper, true)); 162 | ASSERT_EQ(s, bb.toString(base, upper, true)); 163 | ASSERT_EQ(s, cc.toString(base, upper, true)); 164 | ASSERT_EQ(s, dd.toString(base, upper, true)); 165 | } 166 | s.insert(s.begin(), '-'); 167 | { 168 | strcpy(ss, s.c_str()); 169 | Int a(s), b(s.c_str()), c(ss), d(css), aa, bb, cc, dd; 170 | ASSERT_EQ(s, a.toString(base, upper, true)); 171 | ASSERT_EQ(s, b.toString(base, upper, true)); 172 | ASSERT_EQ(s, c.toString(base, upper, true)); 173 | ASSERT_EQ(s, d.toString(base, upper, true)); 174 | aa = s; 175 | bb = s.c_str(); 176 | cc = ss; 177 | dd = css; 178 | ASSERT_EQ(s, aa.toString(base, upper, true)); 179 | ASSERT_EQ(s, bb.toString(base, upper, true)); 180 | ASSERT_EQ(s, cc.toString(base, upper, true)); 181 | ASSERT_EQ(s, dd.toString(base, upper, true)); 182 | } 183 | } 184 | } 185 | 186 | template 187 | void test_ctor_others(T s) 188 | { 189 | const Int a(s); 190 | } 191 | 192 | void test_ctor_str() 193 | { 194 | test_ctor_str_base_case(2, false, "0b", "1", "01"); 195 | test_ctor_str_base_case(2, true, "0B", "1", "01"); 196 | test_ctor_str_base_case(8, false, "0", "1234567", "01234567"); 197 | test_ctor_str_base_case(8, true, "0", "1234567", "01234567"); 198 | test_ctor_str_base_case(10, false, "", "123456789", "0123456789"); 199 | test_ctor_str_base_case(10, true, "", "123456789", "0123456789"); 200 | test_ctor_str_base_case(16, false, "0x", "123456789abcdef", "0123456789abcdef"); 201 | test_ctor_str_base_case(16, true, "0X", "123456789ABCDEF", "0123456789ABCDEF"); 202 | { 203 | string s; 204 | const char ss[12] = { 0 }; 205 | Int a(s), b(s.c_str()), c(ss); 206 | ASSERT_EQ("0", a); 207 | ASSERT_EQ("0", b); 208 | ASSERT_EQ("0", c); 209 | } { 210 | char s[124]; 211 | strcpy(s, "124"); 212 | const char ss[123] = "123"; 213 | const Int a(s), b(ss), c("123"); 214 | test_ctor_others(s); //Strange!! 215 | test_ctor_others(ss); 216 | } 217 | } 218 | 219 | void test_ctor() 220 | { 221 | { 222 | Int a, b(a), c(move(a)), d(static_cast(a)); 223 | const Int e, f(e); 224 | a = b; 225 | b = move(c); 226 | //Int aa(true); 227 | //Int bb(1.0); 228 | //a = true; 229 | //a = 1.; 230 | } 231 | test_ctor_type(); 232 | test_ctor_type(); 233 | test_ctor_type(); 234 | #ifndef _WIN32 // char32_t in Visual Studio 2015 RC acts strangely 235 | test_ctor_type(); 236 | #endif 237 | test_ctor_type(); 238 | test_ctor_type(); 239 | test_ctor_type(); 240 | test_ctor_type(); 241 | test_ctor_type(); 242 | test_ctor_type(); 243 | test_ctor_type(); 244 | test_ctor_type(); 245 | test_ctor_type(); 246 | test_ctor_type(); 247 | test_ctor_str(); 248 | cout<<__FUNCTION__<<"() SUCC\n"; 249 | } 250 | 251 | void test_sign() 252 | { 253 | { //positive 254 | Int a; 255 | a = 123; 256 | ASSERT_EQ("123", +a); 257 | a = 0; 258 | ASSERT_EQ("0", +a); 259 | a = -0; 260 | ASSERT_EQ("0", +a); 261 | a = -123; 262 | ASSERT_EQ("-123", +a); 263 | }{ //negate 264 | Int a; 265 | a = 123; 266 | ASSERT_EQ("-123", -a); 267 | a = 0; 268 | ASSERT_EQ("0", -a); 269 | a = -0; 270 | ASSERT_EQ("0", -a); 271 | a = -123; 272 | ASSERT_EQ("123", -a); 273 | } 274 | cout<<__FUNCTION__<<"() SUCC\n"; 275 | } 276 | 277 | template 278 | static int comp(const T & a, const S & b) 279 | { 280 | return (a == b ? 0 : (a < b ? -1 : 1)); 281 | } 282 | 283 | #define __TEST_COMP(cp, a, b) do{ \ 284 | ASSERT_EQ(0 == cp, a == b); \ 285 | ASSERT_EQ(0 == cp, b == a); \ 286 | ASSERT_EQ(0 != cp, a != b); \ 287 | ASSERT_EQ(0 != cp, b != a); \ 288 | ASSERT_EQ(-1 == cp, a < b); \ 289 | ASSERT_EQ(1 == cp, b < a); \ 290 | ASSERT_EQ(1 == cp, a > b); \ 291 | ASSERT_EQ(-1 == cp, b > a); \ 292 | ASSERT_EQ(1 != cp, a <= b); \ 293 | ASSERT_EQ(-1 != cp, b <= a); \ 294 | ASSERT_EQ(-1 != cp, a >= b); \ 295 | ASSERT_EQ(1 != cp, b >= a); \ 296 | }while(0) 297 | 298 | template 299 | void test_compare_type() 300 | { 301 | for(int i = -100;i <= 100;++i){ 302 | const T ma = numeric_limits::max() + i; 303 | const T mi = numeric_limits::min() + i; 304 | const T z = i; 305 | const Int a(ma), b(mi), c(z); 306 | for(int j = -10;j <= 10;++j){ 307 | const T maj(ma + j), mij(mi + j), zj(z + j); 308 | __TEST_COMP(comp(ma, maj), a, maj); 309 | __TEST_COMP(comp(mi, mij), b, mij); 310 | __TEST_COMP(comp(z, zj), c, zj); 311 | } 312 | __TEST_COMP(0, a, a); 313 | __TEST_COMP(0, b, b); 314 | __TEST_COMP(0, c, c); 315 | } 316 | } 317 | 318 | void test_compare_str_type(int cp, const Int & a, string s) 319 | { 320 | constexpr int kSize = 200; 321 | char ss[kSize]; 322 | const char (&css)[sizeof ss] = ss; 323 | strcpy(ss, s.c_str()); 324 | const Int b(s); 325 | __TEST_COMP(cp, a, s); 326 | __TEST_COMP(cp, a, s.c_str()); 327 | __TEST_COMP(cp, a, ss); 328 | __TEST_COMP(cp, a, css); 329 | __TEST_COMP(cp, a, b); 330 | __TEST_COMP(0, a, a); 331 | } 332 | 333 | void test_compare_str() 334 | { 335 | test_compare_str_type(1, Int("2415134134141341302394292428"), "0"); 336 | test_compare_str_type(0, Int(), "0"); 337 | test_compare_str_type(-1, Int("-2415134134141341302394292428"), "0"); 338 | 339 | test_compare_str_type(1, Int("2415134134141341302394292428"), "123"); 340 | test_compare_str_type(-1, Int(), "123"); 341 | test_compare_str_type(-1, Int("-2415134134141341302394292428"), "123"); 342 | 343 | test_compare_str_type(1, Int("2415134134141341302394292429"), "2415134134141341302394292428"); 344 | test_compare_str_type(0, Int("2415134134141341302394292428"), "2415134134141341302394292428"); 345 | test_compare_str_type(-1, Int("2415134134141341302394292427"), "2415134134141341302394292428"); 346 | test_compare_str_type(-1, Int(), "2415134134141341302394292428"); 347 | test_compare_str_type(-1, Int("-2415134134141341302394292427"), "2415134134141341302394292428"); 348 | test_compare_str_type(-1, Int("-2415134134141341302394292428"), "2415134134141341302394292428"); 349 | test_compare_str_type(-1, Int("-2415134134141341302394292429"), "2415134134141341302394292428"); 350 | 351 | test_compare_str_type(1, Int("2415134134141341302394292428"), "-123"); 352 | test_compare_str_type(1, Int(), "-123"); 353 | test_compare_str_type(-1, Int("-2415134134141341302394292428"), "-123"); 354 | 355 | test_compare_str_type(1, Int("2415134134141341302394292429"), "-2415134134141341302394292428"); 356 | test_compare_str_type(1, Int("2415134134141341302394292428"), "-2415134134141341302394292428"); 357 | test_compare_str_type(1, Int("2415134134141341302394292427"), "-2415134134141341302394292428"); 358 | test_compare_str_type(1, Int(), "-2415134134141341302394292428"); 359 | test_compare_str_type(1, Int("-2415134134141341302394292427"), "-2415134134141341302394292428"); 360 | test_compare_str_type(0, Int("-2415134134141341302394292428"), "-2415134134141341302394292428"); 361 | test_compare_str_type(-1, Int("-2415134134141341302394292429"), "-2415134134141341302394292428"); 362 | } 363 | 364 | void test_compare() 365 | { 366 | //__TEST_COMP(-1, Int(), true); 367 | //__TEST_COMP(-1, Int(), 1.); 368 | test_compare_type(); 369 | test_compare_type(); 370 | test_compare_type(); 371 | test_compare_type(); 372 | test_compare_type(); 373 | test_compare_type(); 374 | test_compare_type(); 375 | test_compare_type(); 376 | test_compare_type(); 377 | test_compare_type(); 378 | test_compare_type(); 379 | test_compare_type(); 380 | test_compare_type(); 381 | test_compare_type(); 382 | test_compare_str(); 383 | cout<<__FUNCTION__<<"() SUCC\n"; 384 | } 385 | 386 | #undef __TEST_COMP 387 | 388 | void test_bool() 389 | { 390 | const Int a; 391 | const Int b("12345"), c("-12345"); 392 | const Int d("1304165134617364173013561034"), e("-1304165134617364173013561034"); 393 | ASSERT_EQ(false, (a ? true : false)); 394 | ASSERT_EQ(true, !a); 395 | ASSERT_EQ(true, (b ? true : false)); 396 | ASSERT_EQ(false, !b); 397 | ASSERT_EQ(true, (c ? true : false)); 398 | ASSERT_EQ(false, !c); 399 | ASSERT_EQ(true, (d ? true : false)); 400 | ASSERT_EQ(false, !d); 401 | ASSERT_EQ(true, (e ? true : false)); 402 | ASSERT_EQ(false, !e); 403 | cout<<__FUNCTION__<<"() SUCC\n"; 404 | } 405 | 406 | void test_incr_decr_exp(string s, string ss) 407 | { 408 | Int a(s), b(s); 409 | ASSERT_EQ(ss, ++a); 410 | ASSERT_EQ(s, b++); 411 | ASSERT_EQ(ss, b); 412 | ASSERT_EQ(s, --a); 413 | ASSERT_EQ(ss, b--); 414 | ASSERT_EQ(s, b); 415 | } 416 | 417 | void test_incr_decr() 418 | { 419 | test_incr_decr_exp("-14910398570183471326419783246138", "-14910398570183471326419783246137"); 420 | test_incr_decr_exp("-18446744073709551616", "-18446744073709551615"); 421 | test_incr_decr_exp("-18446744073709551615", "-18446744073709551614"); 422 | test_incr_decr_exp("-9223372036854775809", "-9223372036854775808"); 423 | test_incr_decr_exp("-9223372036854775808", "-9223372036854775807"); 424 | test_incr_decr_exp("-123", "-122"); 425 | test_incr_decr_exp("-1", "0"); 426 | test_incr_decr_exp("0", "1"); 427 | test_incr_decr_exp("123", "124"); 428 | test_incr_decr_exp("9223372036854775806", "9223372036854775807"); 429 | test_incr_decr_exp("9223372036854775807", "9223372036854775808"); 430 | test_incr_decr_exp("18446744073709551614", "18446744073709551615"); 431 | test_incr_decr_exp("18446744073709551615", "18446744073709551616"); 432 | test_incr_decr_exp("14910398570183471326419783246138", "14910398570183471326419783246139"); 433 | cout<<__FUNCTION__<<"() SUCC\n"; 434 | } 435 | 436 | #define __TEST_ADD_SUB(s1, s2, ss) do{ \ 437 | const Int a(s1), b(s2), c(ss); \ 438 | ASSERT_EQ(c, Int(s1) += b); \ 439 | ASSERT_EQ(c, Int(s1) += s2); \ 440 | ASSERT_EQ(c, Int(s2) += a); \ 441 | ASSERT_EQ(c, Int(s2) += s1); \ 442 | ASSERT_EQ(a, Int(ss) -= b); \ 443 | ASSERT_EQ(a, Int(ss) -= s2); \ 444 | ASSERT_EQ(b, Int(ss) -= a); \ 445 | ASSERT_EQ(b, Int(ss) -= s1); \ 446 | ASSERT_EQ(c, a + b); \ 447 | ASSERT_EQ(c, a + (s2)); \ 448 | ASSERT_EQ(c, (s1) + b); \ 449 | ASSERT_EQ(a, c - b); \ 450 | ASSERT_EQ(a, c - (s2)); \ 451 | ASSERT_EQ(a, (ss) - b); \ 452 | ASSERT_EQ(b, c - a); \ 453 | ASSERT_EQ(b, c - (s1)); \ 454 | ASSERT_EQ(b, (ss) - a); \ 455 | }while(0) 456 | 457 | #define __TEST_ADD_SUB2(s, ss) do{ \ 458 | const Int a(s), b(ss); \ 459 | Int v(s); \ 460 | ASSERT_EQ(b, v += v); \ 461 | ASSERT_EQ("0", v -= v); \ 462 | ASSERT_EQ(b, a + a); \ 463 | ASSERT_EQ("0", a - a); \ 464 | }while(0) 465 | 466 | template 467 | void test_add_sub_type() 468 | { 469 | const T ma = numeric_limits::max(); 470 | const T mi = numeric_limits::min(); 471 | const T z = 0; 472 | for(T i = 0;i <= 10;++i){ 473 | __TEST_ADD_SUB(ma - i, i, ma); 474 | __TEST_ADD_SUB(mi, i, mi + i); 475 | __TEST_ADD_SUB(z, i, i); 476 | __TEST_ADD_SUB2(z, z); 477 | __TEST_ADD_SUB2(i, 2 * i); 478 | if(mi < 0){ 479 | __TEST_ADD_SUB(0 - i, i, z); 480 | __TEST_ADD_SUB2(0 - i, -2 * i); 481 | } 482 | } 483 | } 484 | 485 | void test_add_sub_str_exp(string s, string ss) 486 | { 487 | constexpr int kSize = 200; 488 | char cs[kSize], css[kSize]; 489 | const char (&ccs)[kSize] = cs; 490 | const char (&ccss)[kSize] = css; 491 | strcpy(cs, s.c_str()); 492 | strcpy(css, ss.c_str()); 493 | __TEST_ADD_SUB2(s, ss); 494 | __TEST_ADD_SUB2(cs, css); 495 | __TEST_ADD_SUB2(ccs, ccss); 496 | } 497 | 498 | void test_add_sub_str_exp(string s1, string s2, string ss) 499 | { 500 | constexpr int kSize = 200; 501 | char cs1[kSize], cs2[kSize], css[kSize]; 502 | const char (&ccs1)[kSize] = cs1; 503 | const char (&ccs2)[kSize] = cs2; 504 | const char (&ccss)[kSize] = css; 505 | strcpy(cs1, s1.c_str()); 506 | strcpy(cs2, s2.c_str()); 507 | strcpy(css, ss.c_str()); 508 | __TEST_ADD_SUB(s1, s2, ss); 509 | __TEST_ADD_SUB(cs1, cs2, css); 510 | __TEST_ADD_SUB(ccs1, ccs2, ccss); 511 | } 512 | 513 | #undef __TEST_ADD_SUB 514 | #undef __TEST_ADD_SUB2 515 | 516 | void test_add_sub_str() 517 | { 518 | { 519 | test_add_sub_str_exp("-4444444444444444444444444444444444444", 520 | "-8888888888888888888888888888888888888"); 521 | test_add_sub_str_exp("-15000000000000000000", 522 | "-30000000000000000000"); 523 | test_add_sub_str_exp("-123", "-246"); 524 | test_add_sub_str_exp("0", "0"); 525 | test_add_sub_str_exp("123", "246"); 526 | test_add_sub_str_exp("15000000000000000000", 527 | "30000000000000000000"); 528 | test_add_sub_str_exp("4444444444444444444444444444444444444", 529 | "8888888888888888888888888888888888888"); 530 | }{ 531 | test_add_sub_str_exp( 532 | "-4444444444444444444444444444444444444", 533 | "-6666666666666666666666666666666666666", 534 | "-11111111111111111111111111111111111110"); 535 | test_add_sub_str_exp( 536 | "-4444444444444444444444444444444444444", 537 | "-15000000000000000000", 538 | "-4444444444444444459444444444444444444"); 539 | test_add_sub_str_exp( 540 | "-4444444444444444444444444444444444444", 541 | "-123", 542 | "-4444444444444444444444444444444444567"); 543 | test_add_sub_str_exp( 544 | "-4444444444444444444444444444444444444", 545 | "0", 546 | "-4444444444444444444444444444444444444"); 547 | test_add_sub_str_exp( 548 | "-4444444444444444444444444444444444444", 549 | "123", 550 | "-4444444444444444444444444444444444321"); 551 | test_add_sub_str_exp( 552 | "-4444444444444444444444444444444444444", 553 | "14000000000000000000", 554 | "-4444444444444444430444444444444444444"); 555 | test_add_sub_str_exp( 556 | "-4444444444444444444444444444444444444", 557 | "4444444444444444444444444444444444440", 558 | "-4"); 559 | test_add_sub_str_exp( 560 | "-4444444444444444444444444444444444444", 561 | "4444444444444444444444444444444444444", 562 | "0"); 563 | test_add_sub_str_exp( 564 | "-4444444444444444444444444444444444444", 565 | "4444444444444444444444444444444444448", 566 | "4"); 567 | test_add_sub_str_exp( 568 | "-4444444444444444444444444444444444444", 569 | "6666666666666666666666666666666666666", 570 | "2222222222222222222222222222222222222"); 571 | }{ 572 | test_add_sub_str_exp( 573 | "-15000000000000000000", 574 | "-16000000000000000000", 575 | "-31000000000000000000"); 576 | test_add_sub_str_exp( 577 | "-15000000000000000000", 578 | "-123", 579 | "-15000000000000000123"); 580 | test_add_sub_str_exp( 581 | "-15000000000000000000", 582 | "0", 583 | "-15000000000000000000"); 584 | test_add_sub_str_exp( 585 | "-15000000000000000000", 586 | "123", 587 | "-14999999999999999877"); 588 | test_add_sub_str_exp( 589 | "-15000000000000000000", 590 | "14999999999999990000", 591 | "-10000"); 592 | test_add_sub_str_exp( 593 | "-15000000000000000000", 594 | "15000000000000000000", 595 | "0"); 596 | test_add_sub_str_exp( 597 | "-15000000000000000000", 598 | "15000000000000100000", 599 | "100000"); 600 | test_add_sub_str_exp( 601 | "-15000000000000000000", 602 | "6666666666666666666666666666666666666", 603 | "6666666666666666651666666666666666666"); 604 | }{ 605 | test_add_sub_str_exp( 606 | "-123", 607 | "-234", 608 | "-357"); 609 | test_add_sub_str_exp( 610 | "-123", 611 | "0", 612 | "-123"); 613 | test_add_sub_str_exp( 614 | "-123", 615 | "122", 616 | "-1"); 617 | test_add_sub_str_exp( 618 | "-123", 619 | "123", 620 | "0"); 621 | test_add_sub_str_exp( 622 | "-123", 623 | "124", 624 | "1"); 625 | test_add_sub_str_exp( 626 | "-123", 627 | "15000000000000000000", 628 | "14999999999999999877"); 629 | test_add_sub_str_exp( 630 | "-123", 631 | "6666666666666666666666666666666666666", 632 | "6666666666666666666666666666666666543"); 633 | }{ 634 | test_add_sub_str_exp( 635 | "0", 636 | "0", 637 | "0"); 638 | test_add_sub_str_exp( 639 | "0", 640 | "123", 641 | "123"); 642 | test_add_sub_str_exp( 643 | "0", 644 | "15000000000000000000", 645 | "15000000000000000000"); 646 | test_add_sub_str_exp( 647 | "0", 648 | "6666666666666666666666666666666666666", 649 | "6666666666666666666666666666666666666"); 650 | }{ 651 | test_add_sub_str_exp( 652 | "123", 653 | "234", 654 | "357"); 655 | test_add_sub_str_exp( 656 | "123", 657 | "15000000000000000000", 658 | "15000000000000000123"); 659 | test_add_sub_str_exp( 660 | "123", 661 | "6666666666666666666666666666666666666", 662 | "6666666666666666666666666666666666789"); 663 | }{ 664 | test_add_sub_str_exp( 665 | "15000000000000000000", 666 | "16000000000000000000", 667 | "31000000000000000000"); 668 | test_add_sub_str_exp( 669 | "15000000000000000000", 670 | "6666666666666666666666666666666666666", 671 | "6666666666666666681666666666666666666"); 672 | }{ 673 | test_add_sub_str_exp( 674 | "3333333333333333333333333333333333333", 675 | "6666666666666666666666666666666666666", 676 | "9999999999999999999999999999999999999"); 677 | } 678 | } 679 | 680 | void test_add_sub() 681 | { 682 | test_add_sub_type(); 683 | test_add_sub_type(); 684 | test_add_sub_type(); 685 | test_add_sub_type(); 686 | test_add_sub_type(); 687 | test_add_sub_type(); 688 | test_add_sub_type(); 689 | test_add_sub_type(); 690 | test_add_sub_type(); 691 | test_add_sub_type(); 692 | test_add_sub_type(); 693 | test_add_sub_type(); 694 | test_add_sub_type(); 695 | test_add_sub_type(); 696 | test_add_sub_str(); 697 | cout<<__FUNCTION__<<"() SUCC\n"; 698 | } 699 | 700 | void shiftLeft(Int & a) { a += a; } 701 | void shiftLeft(Int & a, int v) { for (; v-- > 0; shiftLeft(a)); } 702 | 703 | #define __TEST_SHIFT(a, b, i) do{ \ 704 | Int aa(a), bb(b); \ 705 | ASSERT_EQ(b, aa <<= i); \ 706 | ASSERT_EQ(a, aa <<= (-i)); \ 707 | ASSERT_EQ(a, bb >>= i); \ 708 | ASSERT_EQ(b, bb >>= (-i)); \ 709 | ASSERT_EQ(b, a << i); \ 710 | ASSERT_EQ(a, b >> i); \ 711 | ASSERT_EQ(a, b << (-i)); \ 712 | ASSERT_EQ(b, a >> (-i)); \ 713 | }while(0) 714 | 715 | 716 | void test_shift_exp(const Int & a) 717 | { 718 | Int b(a); 719 | for (int i = 0; i <= 1000; ++i, shiftLeft(b)) 720 | __TEST_SHIFT(a, b, i); 721 | } 722 | 723 | #undef __TEST_SHIFT 724 | 725 | void test_shift() 726 | { 727 | test_shift_exp(Int("-6666666666666666666666666666666666666")); 728 | test_shift_exp(Int("-15000000000000000000")); 729 | test_shift_exp(Int(-123456)); 730 | test_shift_exp(Int(-1)); 731 | test_shift_exp(Int(0)); 732 | test_shift_exp(Int(1)); 733 | test_shift_exp(Int(12345)); 734 | test_shift_exp(Int("14000000000000000000")); 735 | test_shift_exp(Int("6666666666666676666666666666666666666")); 736 | cout<<__FUNCTION__<<"() SUCC\n"; 737 | } 738 | 739 | #define __TEST_MUL_DIV(aa, bb, qq, rr) do{ \ 740 | const Int a(aa), b(bb), q(qq), r(rr), p(a - r); \ 741 | ASSERT_EQ(p, Int(b) *= q); \ 742 | ASSERT_EQ(p, Int(b) *= qq); \ 743 | ASSERT_EQ(p, Int(q) *= b); \ 744 | ASSERT_EQ(p, Int(q) *= bb); \ 745 | ASSERT_EQ(q, Int(a) /= b); \ 746 | ASSERT_EQ(q, Int(a) /= bb); \ 747 | ASSERT_EQ(r, Int(a) %= b); \ 748 | ASSERT_EQ(r, Int(a) %= bb); \ 749 | ASSERT_EQ(p, b * q); \ 750 | ASSERT_EQ(p, b * qq); \ 751 | ASSERT_EQ(p, bb * q); \ 752 | ASSERT_EQ(p, q * b); \ 753 | ASSERT_EQ(p, q * bb); \ 754 | ASSERT_EQ(p, qq * b); \ 755 | ASSERT_EQ(q, a / b); \ 756 | ASSERT_EQ(q, a / bb); \ 757 | ASSERT_EQ(q, aa / b); \ 758 | ASSERT_EQ(r, a % b); \ 759 | ASSERT_EQ(r, a % bb); \ 760 | ASSERT_EQ(r, aa % b); \ 761 | }while(0) 762 | 763 | template 764 | void test_mul_div_type(T aa, T bb) 765 | { 766 | assert(bb); 767 | const T qq(aa / bb), rr(aa % bb); 768 | __TEST_MUL_DIV(aa, bb, qq, rr); 769 | } 770 | 771 | template 772 | void test_mul_div_type() 773 | { 774 | const T ma = numeric_limits::max(); 775 | const T mi = numeric_limits::min(); 776 | const T z = 0; 777 | for(T i = 0;i <= 10;++i){ 778 | if (i) { 779 | test_mul_div_type(ma - i, i); 780 | test_mul_div_type(ma - i, i); 781 | test_mul_div_type(mi + i, i); 782 | test_mul_div_type(mi + i, i); 783 | } 784 | test_mul_div_type(z + i, 1 + i); 785 | test_mul_div_type(z + i, -1 - i); 786 | test_mul_div_type(z - i, 1 + i); 787 | test_mul_div_type(z - i, -1 - i); 788 | } 789 | } 790 | 791 | void test_mul_div_str_exp(string aa, string bb, string qq, string rr) 792 | { 793 | constexpr int kSize = 200; 794 | char ca[kSize], cb[kSize], cq[kSize], cr[kSize]; 795 | const char(&cca)[kSize] = ca; 796 | const char(&ccb)[kSize] = cb; 797 | const char(&ccq)[kSize] = cq; 798 | const char(&ccr)[kSize] = cr; 799 | strcpy(ca, aa.c_str()); 800 | strcpy(cb, bb.c_str()); 801 | strcpy(cq, qq.c_str()); 802 | strcpy(cr, rr.c_str()); 803 | __TEST_MUL_DIV(aa, bb, qq, rr); 804 | __TEST_MUL_DIV(ca, cb, cq, cr); 805 | __TEST_MUL_DIV(cca, ccb, ccq, ccr); 806 | } 807 | 808 | #undef __TEST_MUL_DIV 809 | 810 | void test_mul_div_str_sign(string a, string b, string q, string r) 811 | { 812 | test_mul_div_str_exp(a, b, q, r); 813 | test_mul_div_str_exp('-' + a, b, '-' + q, '-' + r); 814 | test_mul_div_str_exp(a, '-' + b, '-' + q, r); 815 | test_mul_div_str_exp('-' + a, '-' + b, q, '-' + r); 816 | } 817 | 818 | void test_mul_div_str() 819 | { 820 | { 821 | test_mul_div_str_sign("0", "1", "0", "0"); 822 | test_mul_div_str_sign("1", "1", "1", "0"); 823 | test_mul_div_str_sign("2", "1", "2", "0"); 824 | test_mul_div_str_sign("15000000000000000000", "1", "15000000000000000000", "0"); 825 | test_mul_div_str_sign("6666666666666666666666666666666666666", "1", "6666666666666666666666666666666666666", "0"); 826 | } { 827 | test_mul_div_str_sign("0", "1234", "0", "0"); 828 | test_mul_div_str_sign("1", "1234", "0", "1"); 829 | test_mul_div_str_sign("1233", "1234", "0", "1233"); 830 | test_mul_div_str_sign("1234", "1234", "1", "0"); 831 | test_mul_div_str_sign("1235", "1234", "1", "1"); 832 | test_mul_div_str_sign("2468", "1234", "2", "0"); 833 | test_mul_div_str_sign("12340000000000000678", "1234", "10000000000000000", "678"); 834 | test_mul_div_str_sign("1234000000000000000000000000000000000000000789", "1234", "1000000000000000000000000000000000000000000", "789"); 835 | } { 836 | test_mul_div_str_sign("0", "10000000000000000000", "0", "0"); 837 | test_mul_div_str_sign("1", "10000000000000000000", "0", "1"); 838 | test_mul_div_str_sign("9999999999999999999", "10000000000000000000", "0", "9999999999999999999"); 839 | test_mul_div_str_sign("10000000000000000000", "10000000000000000000", "1", "0"); 840 | test_mul_div_str_sign("10000000000000000001", "10000000000000000000", "1", "1"); 841 | test_mul_div_str_sign( 842 | "2345746587695950431310000000006666666666", 843 | "10000000000000000000", 844 | "234574658769595043131", "6666666666"); 845 | test_mul_div_str_sign( 846 | "64569874673221432524624352345746587695950431310000000006666666666", 847 | "10000000000000000000", 848 | "6456987467322143252462435234574658769595043131", "6666666666"); 849 | } { 850 | test_mul_div_str_sign("0", "1000000000000000000000000000000000000000000", "0", "0"); 851 | test_mul_div_str_sign("1", "1000000000000000000000000000000000000000000", "0", "1"); 852 | test_mul_div_str_sign("10000000000000000000", "1000000000000000000000000000000000000000000", "0", "10000000000000000000"); 853 | test_mul_div_str_sign( 854 | "999999999999999999999999999999999999999999", 855 | "1000000000000000000000000000000000000000000", "0", "999999999999999999999999999999999999999999"); 856 | test_mul_div_str_sign( 857 | "1000000000000000000000000000000000000000000", 858 | "1000000000000000000000000000000000000000000", "1", "0"); 859 | test_mul_div_str_sign( 860 | "1000000000000000000000000000000000000000001", 861 | "1000000000000000000000000000000000000000000", "1", "1"); 862 | test_mul_div_str_sign( 863 | "1000000000000000000000000000000066666666666", 864 | "1000000000000000000000000000000000000000000", "1", "66666666666"); 865 | test_mul_div_str_sign( 866 | "357354623245241000000000000000000000000000000066666666666", 867 | "1000000000000000000000000000000000000000000", 868 | "357354623245241", "66666666666"); 869 | test_mul_div_str_sign( 870 | "357354623245241000066666666666666666666666666666666666666", 871 | "1000000000000000000000000000000000000000000", 872 | "357354623245241", "66666666666666666666666666666666666666"); 873 | test_mul_div_str_sign( 874 | "45343658567967896058944673546252134132412344562346356357354623245241000066666666666666666666666666666666666666", 875 | "1000000000000000000000000000000000000000000", 876 | "45343658567967896058944673546252134132412344562346356357354623245241", "66666666666666666666666666666666666666"); 877 | } 878 | } 879 | 880 | void test_mul_div() 881 | { 882 | test_mul_div_type(); 883 | test_mul_div_type(); 884 | test_mul_div_type(); 885 | test_mul_div_type(); 886 | test_mul_div_type(); 887 | test_mul_div_type(); 888 | test_mul_div_type(); 889 | test_mul_div_type(); 890 | test_mul_div_type(); 891 | test_mul_div_type(); 892 | test_mul_div_type(); 893 | test_mul_div_type(); 894 | test_mul_div_type(); 895 | test_mul_div_type(); 896 | test_mul_div_str(); 897 | cout << __FUNCTION__ << "() SUCC\n"; 898 | } 899 | 900 | #define __TEST_SWAP(s1, s2) do{ \ 901 | Int a(s1), b(s2); \ 902 | a.swap(b); \ 903 | ASSERT_EQ(s1, b); \ 904 | ASSERT_EQ(s2, a); \ 905 | b.swap(a); \ 906 | ASSERT_EQ(s1, a); \ 907 | ASSERT_EQ(s2, b); \ 908 | swap(a, b); \ 909 | ASSERT_EQ(s1, b); \ 910 | ASSERT_EQ(s2, a); \ 911 | swap(b, a); \ 912 | ASSERT_EQ(s1, a); \ 913 | ASSERT_EQ(s2, b); \ 914 | }while(0) 915 | 916 | void test_swap() 917 | { 918 | { 919 | __TEST_SWAP("0", "0"); 920 | __TEST_SWAP("0", "12345"); 921 | __TEST_SWAP("0", "-12345"); 922 | __TEST_SWAP("0", "514151445243624352623452446245243512345"); 923 | __TEST_SWAP("0", "-514151445243624352623452446245243512345"); 924 | } { 925 | __TEST_SWAP("12345", "23456"); 926 | __TEST_SWAP("12345", "-23456"); 927 | __TEST_SWAP("12345", "514151445243624352623452446245243512345"); 928 | __TEST_SWAP("12345", "-514151445243624352623452446245243512345"); 929 | __TEST_SWAP("-12345", "23456"); 930 | __TEST_SWAP("-12345", "-23456"); 931 | __TEST_SWAP("-12345", "514151445243624352623452446245243512345"); 932 | __TEST_SWAP("-12345", "-514151445243624352623452446245243512345"); 933 | } { 934 | __TEST_SWAP("1232142346563457435684567456745", "514151445243624352623452446245243512345"); 935 | __TEST_SWAP("1232142346563457435684567456745", "-514151445243624352623452446245243512345"); 936 | __TEST_SWAP("-1232142346563457435684567456745", "514151445243624352623452446245243512345"); 937 | __TEST_SWAP("-1232142346563457435684567456745", "-514151445243624352623452446245243512345"); 938 | } 939 | cout << __FUNCTION__ << "() SUCC\n"; 940 | } 941 | 942 | int main() 943 | { 944 | test_ctor(); 945 | test_sign(); 946 | test_compare(); 947 | test_bool(); 948 | test_incr_decr(); 949 | test_add_sub(); 950 | test_shift(); 951 | test_mul_div(); 952 | test_swap(); 953 | return 0; 954 | } 955 | 956 | --------------------------------------------------------------------------------