├── .gitignore ├── tests ├── brat.cpp ├── brat-base.cpp ├── subtract.cpp ├── brat-pows.cpp ├── brat-division.cpp ├── addition.cpp ├── base.cpp ├── brat-addition.cpp ├── brat-subtract.cpp ├── brat-gcd.cpp ├── brat-lcm.cpp ├── brat-product.cpp ├── shifts.cpp ├── gcd.cpp ├── lcm.cpp ├── brat-point.cpp ├── pows.cpp ├── product.cpp ├── comparison.cpp ├── bits.cpp ├── brat-comparison.cpp ├── fibonnaci.cpp ├── division.cpp ├── factorial.cpp └── main.cpp ├── LICENSE ├── CMakeLists.txt ├── include └── BeeNum │ ├── Math.h │ ├── Brat.h │ └── Bint.h ├── .github └── workflows │ └── release.yml ├── src ├── Brat.cpp ├── Brat │ ├── io.cpp │ ├── comparison.cpp │ └── arithmetics.cpp ├── Bint │ ├── bitoperations.cpp │ ├── io.cpp │ ├── shifts.cpp │ ├── comparison.cpp │ └── arithmetics.cpp ├── Math.cpp └── Bint.cpp └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.o 3 | *.swp 4 | *.log 5 | main 6 | main-fast 7 | test-* 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/brat.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Brat a(1, "34534534"); 13 | Brat b("-SomeNumbersAreHere::62", "-SomeNumbersAreHere::62"); // base 62 14 | Brat c = "-9:10:79:100:16:3:35:72:76:15:11::101 / 2"; // base 101 15 | 16 | a += b; 17 | a *= c; 18 | 19 | std::cout << "a = " << a << std::endl; 20 | std::cout << "a b62 = " << a.base(62) << std::endl; 21 | std::cout << "a point = " << a.point(50) << std::endl; 22 | std::cout << "a point b62 = " << a.point(50, 62) << std::endl; 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Max Vetrov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/brat-base.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Brat a; 12 | Brat c; 13 | 14 | std::vector> data = { 15 | {"453453a::32/43453b::32", "4466021482/137499755", "453453a::32/43453b::32"}, 16 | {"-453453a::32/-45afA3a::62", "171770057/8920503206", "53q069::32/89r84t6::32"}, 17 | {"1:12:20:111::150/1:12:20:112::150", "3648111/3648112", "3fajf::32/3fajg::32"}, 18 | }; 19 | 20 | /////////////////////////////////////////////////////////// 21 | 22 | std::cout << "Different Bases:" << std::endl; 23 | std::cout << "Decimal:" << std::endl; 24 | for (auto& s : data) { 25 | a = s[0]; 26 | std::cout << "a = " << a << std::endl; 27 | std::cout << "s = " << s[1] << std::endl; 28 | assert(a.toString() == s[1]); 29 | std::cout << std::endl; 30 | } 31 | 32 | std::cout << "Base32:" << std::endl; 33 | for (auto& s : data) { 34 | a = s[0]; 35 | std::cout << "a = " << a.base(32) << std::endl; 36 | std::cout << "s = " << s[2] << std::endl; 37 | assert(a.base(32) == s[2]); 38 | std::cout << std::endl; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /tests/subtract.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | 12 | std::string data[][3] = { 13 | {"-500000000000000000000", "500000000000000000000", "-1000000000000000000000"}, 14 | {"500000000000000000000", "-500000000000000000000", "1000000000000000000000"}, 15 | {"18446744073709551616", "1", "18446744073709551615"}, // (1 << 64) - 1 16 | {"115792089237316195423570985008687907853269984665640564039457584007913129639936", "1", "115792089237316195423570985008687907853269984665640564039457584007913129639935"}, // (1 << 256) - 1 17 | }; 18 | 19 | /////////////////////////////////////////////////////////// 20 | 21 | Bint a; 22 | Bint b; 23 | Bint c; 24 | std::string s; 25 | 26 | for (auto& item: data) { 27 | a = item[0]; 28 | std::cout << "a = " << a << std::endl; 29 | std::cout << "a = " << a.hex() << std::endl; 30 | 31 | b = item[1]; 32 | std::cout << "b = " << b << std::endl; 33 | std::cout << "b = " << b.hex() << std::endl; 34 | 35 | s = item[2]; 36 | std::cout << "s = " << s << std::endl; 37 | 38 | c = a - b; 39 | std::cout << "c = " << c << std::endl; 40 | std::cout << "c = " << c.hex() << std::endl; 41 | std::cout << std::endl; 42 | 43 | assert(c.toString() == s); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /tests/brat-pows.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Brat a; 13 | int b; 14 | Brat c; 15 | 16 | std::vector> data = { 17 | {"-5/23", "334" , "285746847820568745553945887076335239862977498705699665303781460806908158976684548918862005465043007412295763588343507058055135340570979687781510573352510310491378504344021315252113959925738006541406921456882628262974321842193603515625/65629218059151821783361066374230705132484876048854031364279109080760000432549452817323157819336406081525296568668713099971626516034722654896387618155178603081327877047438815730857894400750808295634321357126661155038480159766714286970178265202351119940657886462335013967533238982725161694721534974960914781713905854639939552518927584726107453798646114783787779979965748010815548352462018323575289721202724893333330184001516901514121741731791414098158218609"}, 18 | }; 19 | 20 | /////////////////////////////////////////////////////////// 21 | std::cout << "pows:" << std::endl; 22 | 23 | for (auto& s : data) { 24 | a = s[0]; 25 | std::cout << "a = " << a << std::endl; 26 | b = std::stoi(s[1]); 27 | std::cout << "b = " << b << std::endl; 28 | 29 | Brat t = s[2]; 30 | std::cout << "t = " << t << std::endl; 31 | c = Math::pow(a, b); 32 | std::cout << "c = " << c << std::endl; 33 | assert(t.toString() == c.toString()); 34 | std::cout << std::endl; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tests/brat-division.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Brat a; 13 | Brat b; 14 | Brat c; 15 | 16 | std::vector> data = { 17 | {"-500000000000000000000/200000000000000000000000000", "-50000000004000000000000/400000000000000000000", "250/12500000001"}, 18 | {"543563/24994884934885", "-537483929/484588458292993", "-263404356155114154059/13434348959704898963165"}, 19 | }; 20 | 21 | /////////////////////////////////////////////////////////// 22 | std::cout << "division:" << std::endl; 23 | 24 | std::cout << "positives:" << std::endl; 25 | for (auto& s : data) { 26 | a = s[0]; 27 | std::cout << "a = " << a << std::endl; 28 | b = s[1]; 29 | std::cout << "b = " << b << std::endl; 30 | 31 | Brat t = s[2]; 32 | std::cout << "t = " << t << std::endl; 33 | c = a / b; 34 | std::cout << "c = " << c << std::endl; 35 | assert(t.toString() == c.toString()); 36 | std::cout << std::endl; 37 | } 38 | 39 | std::cout << "negatives:" << std::endl; 40 | for (auto& s : data) { 41 | a = s[0]; 42 | std::cout << "a = " << a << std::endl; 43 | b = s[1]; 44 | b = -b; 45 | std::cout << "b = " << b << std::endl; 46 | 47 | Brat t = s[2]; 48 | t = -t; 49 | std::cout << "t = " << t << std::endl; 50 | c = a / b; 51 | std::cout << "c = " << c << std::endl; 52 | assert(t.toString() == c.toString()); 53 | std::cout << std::endl; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /tests/addition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Bint a; 13 | Bint c; 14 | 15 | std::map data; 16 | data = { 17 | {"2305843009213693952", "4611686018427387904"}, {"4611686018427387904", "9223372036854775808"}, 18 | {"9223372036854775808", "18446744073709551616"}, {"18446744073709551616", "36893488147419103232"}, 19 | {"36893488147419103232", "73786976294838206464"} 20 | }; 21 | 22 | /////////////////////////////////////////////////////////// 23 | 24 | std::cout << "addition:" << std::endl; 25 | 26 | std::cout << "positives:" << std::endl; 27 | for (auto& s : data) { 28 | a = s.first; 29 | std::cout << "a = " << a << std::endl; 30 | std::cout << "a = " << a.bin() << std::endl; 31 | 32 | c = a+a; 33 | std::cout << "c = a + a" << std::endl; 34 | std::cout << "c = " << c << std::endl; 35 | std::cout << "c = " << c.bin() << std::endl; 36 | assert(c.toString()==s.second); 37 | 38 | std::cout << std::endl; 39 | } 40 | 41 | std::cout << "negatives:" << std::endl; 42 | for (auto& s : data) { 43 | a = "-" + s.first; 44 | std::cout << "a = " << a << std::endl; 45 | std::cout << "a = " << a.bin() << std::endl; 46 | 47 | c = a+a; 48 | std::cout << "c = a + a" << std::endl; 49 | std::cout << "c = " << c << std::endl; 50 | std::cout << "c = " << c.bin() << std::endl; 51 | assert(c.toString()=="-"+s.second); 52 | 53 | std::cout << std::endl; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /tests/base.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Bint a; 12 | Bint c; 13 | 14 | std::vector> data = { 15 | {"453453a::32", "4466021482", "21uyc8a::36"}, 16 | {"-453453a::32", "-4466021482", "-21uyc8a::36"}, 17 | {"cc453453a::32", "13610922415210", "4torrs60a::36"}, 18 | {"cc45A3453a::50", "23909464394262660", "6jf74b49m6c::36"}, 19 | {"0::150", "0", "0::36"}, 20 | {"1::150", "1", "1::36"}, 21 | {"1:12::150", "162", "4i::36"}, 22 | {"1:12:20::150", "24320", "irk::36"}, 23 | {"1:12:20:111::150", "3648111", "266wf::36"}, 24 | {"1:1::150", "151", "47::36"}, 25 | {"1:1:1::150", "22651", "hh7::36"}, 26 | }; 27 | 28 | /////////////////////////////////////////////////////////// 29 | 30 | std::cout << "Different Bases:" << std::endl; 31 | std::cout << "From base to decimal:" << std::endl; 32 | for (auto& s : data) { 33 | a = s[0]; 34 | std::cout << "a = " << a << std::endl; 35 | std::cout << "a = " << a.bin() << std::endl; 36 | std::cout << "s = " << s[1] << std::endl; 37 | assert(a.toString()==s[1]); 38 | std::cout << std::endl; 39 | } 40 | 41 | std::cout << "From decimal to base62:" << std::endl; 42 | int base = 36; 43 | for (auto& s : data) { 44 | a = s[1]; 45 | std::cout << "a = " << a << std::endl; 46 | std::cout << "a = " << a.base(base) << std::endl; 47 | std::cout << "s = " << s[2] << std::endl; 48 | assert(a.base(base)==s[2]); 49 | std::cout << std::endl; 50 | } 51 | 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.10) 2 | 3 | project (Bint 4 | VERSION "0.1.0" 5 | DESCRIPTION "Bint is an arbitrary-precision arithmetic library." 6 | LANGUAGES CXX 7 | ) 8 | 9 | enable_testing() 10 | 11 | set(CMAKE_CXX_STANDARD 17) 12 | set(CMAKE_CXX_EXTENSIONS OFF) 13 | if(MSVC) 14 | #add_compile_options(/Wall) 15 | else() 16 | add_compile_options(-Wall -Wextra -pedantic) 17 | endif() 18 | 19 | # sources 20 | include_directories(include) 21 | aux_source_directory(src/Bint BINT_SRC) 22 | aux_source_directory(src/Brat BRAT_SRC) 23 | set(BINT_SRC ${BINT_SRC} ${BRAT_SRC} src/Bint.cpp src/Brat.cpp) 24 | set(MATH_SRC src/Math.cpp) 25 | add_library(shareobjects OBJECT ${BINT_SRC} ${MATH_SRC}) 26 | 27 | # libraries 28 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 29 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) 30 | 31 | add_library(BeeNum SHARED ${BINT_SRC} ${MATH_SRC}) 32 | add_library(BeeNum_static STATIC $) 33 | set_target_properties(BeeNum_static PROPERTIES OUTPUT_NAME BeeNum) 34 | 35 | # tests 36 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") 37 | 38 | add_executable(test-main-fast tests/main.cpp ${BINT_SRC} ${MATH_SRC}) 39 | set_target_properties(test-main-fast PROPERTIES COMPILE_FLAGS -Ofast) 40 | add_test(NAME tst-main-fast COMMAND ./tests/test-main-fast) 41 | 42 | aux_source_directory(tests TESTS) 43 | foreach(tstfile ${TESTS}) 44 | string(REGEX MATCH "\/(.*)\\.[^.]*$" dummy ${tstfile}) 45 | add_executable(test-${CMAKE_MATCH_1} ${tstfile} $) 46 | add_test(NAME tst-${CMAKE_MATCH_1} COMMAND ./tests/test-${CMAKE_MATCH_1}) 47 | endforeach() 48 | -------------------------------------------------------------------------------- /tests/brat-addition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | 13 | std::vector> data = { 14 | {"1", "3", "1", "8", "11", "24"}, 15 | {"2", "3", "3", "8", "25", "24"}, 16 | {"2444234", "3434634563567456", "34563457727", "457536743223454565677473721", "559163491374441896220487035953613", "785735756188682526849306693345947725411888"}, 17 | }; 18 | 19 | /////////////////////////////////////////////////////////// 20 | 21 | std::cout << "addition:" << std::endl; 22 | 23 | std::cout << "positives:" << std::endl; 24 | for (auto& s : data) { 25 | Brat a(s[0], s[1]); 26 | std::cout << "a = " << a << std::endl; 27 | Brat b(s[2], s[3]); 28 | std::cout << "b = " << b << std::endl; 29 | Brat t(s[4], s[5]); 30 | std::cout << "t = " << t << std::endl; 31 | 32 | Brat c = a + b; 33 | std::cout << "c = a + b" << std::endl; 34 | std::cout << "c = " << c << std::endl; 35 | assert(c.toString() == t.toString()); 36 | 37 | std::cout << std::endl; 38 | } 39 | 40 | std::cout << "negatives:" << std::endl; 41 | for (auto& s : data) { 42 | Brat a("-" + s[0], s[1]); 43 | std::cout << "a = " << a << std::endl; 44 | Brat b(s[2], "-" + s[3]); 45 | std::cout << "b = " << b << std::endl; 46 | Brat t("-" + s[4], s[5]); 47 | std::cout << "t = " << t << std::endl; 48 | 49 | Brat c = a + b; 50 | std::cout << "c = a + b" << std::endl; 51 | std::cout << "c = " << c << std::endl; 52 | assert(c.toString() == t.toString()); 53 | 54 | std::cout << std::endl; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /tests/brat-subtract.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | 12 | std::vector> data = { 13 | {"1", "3", "1", "8", "5", "24"}, 14 | {"2", "3", "3", "8", "7", "24"}, 15 | {"3", "8", "2", "3", "-7", "24"}, 16 | {"2", "3", "0", "8", "2", "3"}, 17 | {"0", "3", "6", "16", "-3", "8"}, 18 | {"2444234", "3434634563567456", "34563457727", "457536743223454565677473721", "559163372661595350663627267021101", "785735756188682526849306693345947725411888"}, 19 | }; 20 | 21 | /////////////////////////////////////////////////////////// 22 | 23 | std::cout << "subtraction:" << std::endl; 24 | 25 | std::cout << "positives:" << std::endl; 26 | for (auto& s : data) { 27 | Brat a(s[0], s[1]); 28 | std::cout << "a = " << a << std::endl; 29 | Brat b(s[2], s[3]); 30 | std::cout << "b = " << b << std::endl; 31 | Brat t(s[4], s[5]); 32 | std::cout << "t = " << t << std::endl; 33 | 34 | Brat c = a - b; 35 | std::cout << "c = a - b" << std::endl; 36 | std::cout << "c = " << c << std::endl; 37 | assert(c.toString() == t.toString()); 38 | 39 | std::cout << std::endl; 40 | } 41 | 42 | std::cout << "negatives:" << std::endl; 43 | for (auto& s : data) { 44 | Brat a(s[0], s[1]); 45 | a = -a; 46 | std::cout << "a = " << a << std::endl; 47 | Brat b(s[2], s[3]); 48 | b = -b; 49 | std::cout << "b = " << b << std::endl; 50 | 51 | Brat t(s[4], s[5]); 52 | t = -t; 53 | std::cout << "t = " << t << std::endl; 54 | 55 | Brat c = a - b; 56 | std::cout << "c = a - b" << std::endl; 57 | std::cout << "c = " << c << std::endl; 58 | assert(c.toString() == t.toString()); 59 | 60 | std::cout << std::endl; 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /tests/brat-gcd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Brat a; 13 | Brat b; 14 | Brat c; 15 | 16 | std::vector> data = { 17 | {"4/5", "8/15", "4/15"}, 18 | {"4434/2345", "3422448/14345345", "6/961138115"}, 19 | {"44123456789034/23123456789045", "34123456789022448/141234567890345345", "6/653166285546368606189972549105"}, 20 | {"441234567890341234567/231234567890451234567", "341234567890224481234567/1412345678903453451234567", "1/108861047591062015671942869376375371818559163"}, 21 | {"4412345678903412345672/2312345678904512345672", "3412345678902244812345672/14123456789034534512345672", "3/510286160583103198462673630487219350369017681"}, 22 | {"4412345678903412345672345/2312345678904512345672", "3412345678902244812345672345/14123456789034534512345672", "15/4082289284664825587701389043897754802952141448"}, 23 | }; 24 | 25 | /////////////////////////////////////////////////////////// 26 | 27 | std::cout << "Greatest Common Divisor:" << std::endl; 28 | 29 | std::cout << "positives:" << std::endl; 30 | for (auto& s : data) { 31 | a = s[0]; 32 | std::cout << "a = " << a << std::endl; 33 | b = s[1]; 34 | std::cout << "b = " << b << std::endl; 35 | c = Math::gcd(a, b); 36 | std::cout << "c = " << c << std::endl; 37 | std::cout << "s = " << s[2] << std::endl; 38 | assert(c.toString()==s[2]); 39 | std::cout << std::endl; 40 | } 41 | 42 | std::cout << "negatives:" << std::endl; 43 | for (auto& s : data) { 44 | a = s[0]; 45 | a = -a; 46 | std::cout << "a = " << a << std::endl; 47 | b = s[1]; 48 | std::cout << "b = " << b << std::endl; 49 | c = Math::gcd(a, b); 50 | std::cout << "c = " << c << std::endl; 51 | std::cout << "s = " << s[2] << std::endl; 52 | assert(c.toString()==s[2]); 53 | std::cout << std::endl; 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /tests/brat-lcm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Brat a; 13 | Brat b; 14 | Brat c; 15 | 16 | std::vector> data = { 17 | {"4/5", "8/15", "8/5"}, 18 | {"4434/2345", "3422448/14345345", "2529189072/35"}, 19 | {"44123456789034/23123456789045", "34123456789022448/141234567890345345", "250940811853816811901637705872/5"}, 20 | {"441234567890341234567/231234567890451234567", "341234567890224481234567/1412345678903453451234567", "150564487112290508962653036830640507095677489/3"}, 21 | {"4412345678903412345672/2312345678904512345672", "3412345678902244812345672/14123456789034534512345672", "78419003704317973418084047912047984406339227/1"}, 22 | {"4412345678903412345672345/2312345678904512345672", "3412345678902244812345672345/14123456789034534512345672", "1003763247415270059751554398708779566810310006519935/8"}, 23 | }; 24 | 25 | /////////////////////////////////////////////////////////// 26 | 27 | std::cout << "Least Common Multiple:" << std::endl; 28 | 29 | std::cout << "positives:" << std::endl; 30 | for (auto& s : data) { 31 | a = s[0]; 32 | std::cout << "a = " << a << std::endl; 33 | b = s[1]; 34 | std::cout << "b = " << b << std::endl; 35 | c = Math::lcm(a, b); 36 | std::cout << "c = " << c << std::endl; 37 | std::cout << "s = " << s[2] << std::endl; 38 | assert(c.toString() == s[2]); 39 | std::cout << std::endl; 40 | } 41 | 42 | std::cout << "negatives:" << std::endl; 43 | for (auto& s : data) { 44 | a = s[0]; 45 | a = -a; 46 | std::cout << "a = " << a << std::endl; 47 | b = s[1]; 48 | std::cout << "b = " << b << std::endl; 49 | c = Math::lcm(a, b); 50 | std::cout << "c = " << c << std::endl; 51 | std::cout << "s = " << s[2] << std::endl; 52 | assert(c.toString()==s[2]); 53 | std::cout << std::endl; 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /include/BeeNum/Math.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | 27 | #ifndef TIGERTV_MATH_H 28 | #define TIGERTV_MATH_H 29 | 30 | #include "Bint.h" 31 | #include "Brat.h" 32 | 33 | 34 | namespace BeeNum { 35 | 36 | class Math { 37 | private: 38 | Math(); 39 | static Bint oddFact(const uint64_t a, const uint64_t begin); 40 | public: 41 | static Bint pow(const Bint& a, uint64_t exp); 42 | static Brat pow(const Brat& a, uint64_t exp); 43 | static Bint modPow(const Bint& base, const uint64_t exp, const uint64_t mod); 44 | static Bint fact(const uint64_t a); 45 | static Bint gcd(const Bint& a, const Bint& b); 46 | static Brat gcd(const Brat& a, const Brat& b); 47 | static Bint lcm(const Bint& a, const Bint& b); 48 | static Brat lcm(const Brat& a, const Brat& b); 49 | static Bint fib(const uint64_t a); 50 | }; 51 | 52 | 53 | } // namespace 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: [push] 4 | 5 | env: 6 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 7 | BUILD_TYPE: Release 8 | 9 | jobs: 10 | build: 11 | # The CMake configure and build commands are platform agnostic and should work equally 12 | # well on Windows or Mac. You can convert this to a matrix build if you need 13 | # cross-platform coverage. 14 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 15 | runs-on: ${{matrix.os}} 16 | strategy: 17 | matrix: 18 | os: [ubuntu-latest, windows-latest] 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: Create Build Environment 23 | # Some projects don't allow in-source building, so create a separate build directory 24 | # We'll use this as our working directory for all subsequent commands 25 | run: cmake -E make_directory ${{runner.workspace}}/build 26 | 27 | - name: Configure CMake 28 | # Use a bash shell so we can use the same syntax for environment variable 29 | # access regardless of the host operating system 30 | shell: bash 31 | working-directory: ${{runner.workspace}}/build 32 | # Note the current convention is to use the -S and -B options here to specify source 33 | # and build directories, but this is only available with CMake 3.13 and higher. 34 | # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 35 | run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE 36 | 37 | - name: Build 38 | working-directory: ${{runner.workspace}}/build 39 | shell: bash 40 | # Execute the build. You can specify a specific target with "--target " 41 | run: cmake --build . --config $BUILD_TYPE 42 | 43 | - name: Test 44 | working-directory: ${{runner.workspace}}/build 45 | shell: bash 46 | # Execute tests defined by the CMake configuration. 47 | # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail 48 | run: ctest -C $BUILD_TYPE 49 | -------------------------------------------------------------------------------- /tests/brat-product.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Brat a; 12 | Brat b; 13 | Brat c; 14 | 15 | std::vector> data = { 16 | {"-500000000000000000000/200000000000000000000000000", "-50000000004000000000000/400000000000000000000" , "12500000001/40000000000000", "1/160000000000"}, 17 | {"543563/24994884934885", "-537483929/484588458292993" , "-292156376899027/12112232755806678879056760805", "295460734969/624744272908141130689963225"}, 18 | }; 19 | 20 | /////////////////////////////////////////////////////////// 21 | std::cout << "product:" << std::endl; 22 | 23 | std::cout << "positives:" << std::endl; 24 | for (auto& s : data) { 25 | a = s[0]; 26 | std::cout << "a = " << a << std::endl; 27 | b = s[1]; 28 | std::cout << "b = " << b << std::endl; 29 | 30 | Brat t = s[2]; 31 | std::cout << "t = " << t << std::endl; 32 | c = a * b; 33 | std::cout << "c = " << c << std::endl; 34 | assert(t.toString() == c.toString()); 35 | std::cout << std::endl; 36 | } 37 | 38 | std::cout << "negatives:" << std::endl; 39 | for (auto& s : data) { 40 | a = s[0]; 41 | std::cout << "a = " << a << std::endl; 42 | b = s[1]; 43 | b = -b; 44 | std::cout << "b = " << b << std::endl; 45 | 46 | Brat t = s[2]; 47 | t = -t; 48 | std::cout << "t = " << t << std::endl; 49 | c = a * b; 50 | std::cout << "c = " << c << std::endl; 51 | assert(t.toString() == c.toString()); 52 | std::cout << std::endl; 53 | } 54 | 55 | /////////////////////////////////////////////////////////// 56 | std::cout << "square:" << std::endl; 57 | 58 | std::cout << "positives:" << std::endl; 59 | for (auto& s : data) { 60 | a = s[0]; 61 | std::cout << "a = " << a << std::endl; 62 | 63 | Brat t = s[3]; 64 | std::cout << "t = " << t << std::endl; 65 | c = a * a; 66 | std::cout << "c = " << c << std::endl; 67 | assert(t.toString() == c.toString()); 68 | std::cout << std::endl; 69 | } 70 | 71 | std::cout << "negatives:" << std::endl; 72 | for (auto& s : data) { 73 | a = s[0]; 74 | a = -a; 75 | std::cout << "a = " << a << std::endl; 76 | 77 | Brat t = s[3]; 78 | std::cout << "t = " << t << std::endl; 79 | c = a * a; 80 | std::cout << "c = " << c << std::endl; 81 | assert(t.toString() == c.toString()); 82 | std::cout << std::endl; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Brat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | 30 | namespace BeeNum { 31 | 32 | Brat::Brat() { 33 | //numerator = 0; 34 | denominator = 1; 35 | } 36 | 37 | Brat::Brat(const Bint& numerator, const Bint& denominator) : numerator(numerator), denominator(denominator) { 38 | simplify(); 39 | } 40 | 41 | Brat::Brat(const int64_t num) { 42 | numerator = num; 43 | denominator = 1; 44 | } 45 | 46 | Brat::Brat(const std::string& s) { 47 | auto end = s.find('/'); 48 | numerator = s.substr(0, end); 49 | if (end != std::string::npos) { 50 | denominator = s.substr(end + 1); 51 | } else { 52 | denominator = 1; 53 | } 54 | simplify(); 55 | } 56 | 57 | Brat::Brat(const char* s) : Brat((std::string)s) { 58 | 59 | } 60 | 61 | void Brat::simplify() { 62 | if (denominator < 0) { 63 | denominator = -denominator; 64 | numerator = -numerator; 65 | } 66 | 67 | Bint c = Math::gcd(numerator, denominator); 68 | if (c != 1) { 69 | numerator /= c; 70 | denominator /= c; 71 | } 72 | } 73 | 74 | Bint Brat::getNumerator() const { 75 | return numerator; 76 | } 77 | 78 | Bint Brat::getDenominator() const { 79 | return denominator; 80 | } 81 | 82 | 83 | } // namespace 84 | -------------------------------------------------------------------------------- /tests/shifts.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Bint a; 12 | Bint b; 13 | Bint c; 14 | 15 | std::map data; 16 | data = { 17 | {61, "2305843009213693952"}, {62, "4611686018427387904"}, {63, "9223372036854775808"}, 18 | {64, "18446744073709551616"}, {65, "36893488147419103232"} 19 | }; 20 | 21 | /////////////////////////////////////////////////////////// 22 | 23 | std::cout << "shift left:" << std::endl; 24 | 25 | std::cout << "positives:" << std::endl; 26 | for (auto& s : data) { 27 | a = "1"; 28 | std::cout << "a = " << a << std::endl; 29 | std::cout << "a <<= " << s.first << std::endl; 30 | a <<= s.first; 31 | assert(a.toString()==s.second); 32 | std::cout << "a = " << a << std::endl; 33 | std::cout << "a = " << a.bin() << std::endl; 34 | std::cout << std::endl; 35 | } 36 | 37 | std::cout << "negatives:" << std::endl; 38 | for (auto& s : data) { 39 | a = "-1"; 40 | std::cout << "a = " << a << std::endl; 41 | std::cout << "a <<= " << s.first << std::endl; 42 | a <<= s.first; 43 | assert(a.toString()==("-"+s.second)); 44 | std::cout << "a = " << a << std::endl; 45 | std::cout << "a = " << a.bin() << std::endl; 46 | std::cout << std::endl; 47 | } 48 | 49 | /////////////////////////////////////////////////////////// 50 | 51 | std::cout << "shift right:" << std::endl; 52 | 53 | std::cout << "positives:" << std::endl; 54 | for (auto& s : data) { 55 | a = "1"; 56 | std::cout << "a = " << a << std::endl; 57 | std::cout << "a <<= " << (s.first + 1) << std::endl; 58 | a <<= s.first + 1; 59 | a >>= 1; 60 | std::cout << "a >>= 1" << std::endl; 61 | std::cout << "a = " << a << std::endl; 62 | assert(a.toString()==s.second); 63 | std::cout << "a = " << a << std::endl; 64 | std::cout << "a = " << a.bin() << std::endl; 65 | std::cout << std::endl; 66 | } 67 | 68 | std::cout << "negatives:" << std::endl; 69 | for (auto& s : data) { 70 | a = "-1"; 71 | std::cout << "a = " << a << std::endl; 72 | std::cout << "a <<= " << (s.first + 1) << std::endl; 73 | a <<= s.first + 1; 74 | a >>= 1; 75 | std::cout << "a >>= 1" << std::endl; 76 | std::cout << "a = " << a << std::endl; 77 | assert(a.toString()==("-"+s.second)); 78 | std::cout << "a = " << a << std::endl; 79 | std::cout << "a = " << a.bin() << std::endl; 80 | std::cout << std::endl; 81 | } 82 | 83 | a = "5000000000000000000"; 84 | std::cout << "a = " << a << std::endl; 85 | std::cout << "a = " << a.bin() << std::endl; 86 | std::cout << std::endl; 87 | a <<= 2; 88 | std::cout << "a = " << a << std::endl; 89 | std::cout << "a = " << a.bin() << std::endl; 90 | assert(a.toString()=="20000000000000000000"); 91 | std::cout << std::endl; 92 | 93 | } 94 | -------------------------------------------------------------------------------- /tests/gcd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Bint a; 13 | Bint b; 14 | Bint c; 15 | 16 | std::vector> data = { 17 | {"54", "24", "6"}, 18 | {"54", "1", "1"}, 19 | {"54", "0", "54"}, 20 | {"0", "0", "0"}, 21 | {"5634563456345624562456435634563456345636574567456763434536745247235423452345234523451234355634563456345664", "245635675674678567856785678545674568", "8"}, 22 | {"8345383455657547867846978956789567854653456345563456345634562456245634563456345634566163675675674674567456", "245345345345345345345345674678678567856785678567856730584300921369395234456456456454456", "8"}, 23 | {"6443534534546425624523462453567245728436724562456234563567456746734563456", "34245698729348249569258298624572785723745823845728452457824356", "4"}, 24 | {"4213518165211821182155201879854514971797088", "9307999046194775203602390818721305202949035", "123"}, 25 | {"54", "-3", "3"}, 26 | {"-54", "3", "3"}, 27 | {"-44", "99", "11"}, 28 | }; 29 | 30 | /////////////////////////////////////////////////////////// 31 | 32 | std::cout << "Greatest Common Divisor:" << std::endl; 33 | 34 | std::cout << "positives:" << std::endl; 35 | for (auto& s : data) { 36 | a = s[0]; 37 | std::cout << "a = " << a << std::endl; 38 | std::cout << "a = " << a.bin() << std::endl; 39 | b = s[1]; 40 | std::cout << "b = " << b << std::endl; 41 | std::cout << "b = " << b.bin() << std::endl; 42 | c = Math::gcd(a, b); 43 | std::cout << "c = " << c << std::endl; 44 | std::cout << "c = " << c.bin() << std::endl; 45 | std::cout << "s = " << s[2] << std::endl; 46 | assert(c.toString()==s[2]); 47 | std::cout << std::endl; 48 | } 49 | 50 | std::cout << "negatives:" << std::endl; 51 | for (auto& s : data) { 52 | a = s[0]; 53 | a = -a; 54 | std::cout << "a = " << a << std::endl; 55 | std::cout << "a = " << a.bin() << std::endl; 56 | b = s[1]; 57 | std::cout << "b = " << b << std::endl; 58 | std::cout << "b = " << b.bin() << std::endl; 59 | c = Math::gcd(a, b); 60 | std::cout << "c = " << c << std::endl; 61 | std::cout << "c = " << c.bin() << std::endl; 62 | std::cout << "s = " << s[2] << std::endl; 63 | assert(c.toString()==s[2]); 64 | std::cout << std::endl; 65 | } 66 | 67 | for (auto& s : data) { 68 | a = s[0]; 69 | std::cout << "a = " << a << std::endl; 70 | std::cout << "a = " << a.bin() << std::endl; 71 | b = s[1]; 72 | b = -b; 73 | std::cout << "b = " << b << std::endl; 74 | std::cout << "b = " << b.bin() << std::endl; 75 | c = Math::gcd(a, b); 76 | std::cout << "c = " << c << std::endl; 77 | std::cout << "c = " << c.bin() << std::endl; 78 | std::cout << "s = " << s[2] << std::endl; 79 | assert(c.toString()==s[2]); 80 | std::cout << std::endl; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/Brat/io.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | Brat::operator std::string() const { 32 | return this->toString(); 33 | } 34 | 35 | std::string Brat::toString() const { 36 | return base(10); 37 | } 38 | 39 | std::string Brat::base(const uint64_t base) const { 40 | return numerator.base(base) + '/' + denominator.base(base); 41 | } 42 | 43 | std::string Brat::point(const uint64_t num) const { 44 | return point(num, 10); 45 | } 46 | 47 | std::string Brat::point(const uint64_t num, const uint64_t base) const { 48 | Bint a = numerator; 49 | Bint t = a / denominator; 50 | a %= denominator; 51 | 52 | if (a < 0) { 53 | a = -a; 54 | } 55 | 56 | std::string s = (t == 0 && numerator < 0) ? "-" : ""; 57 | s += t.base(base); 58 | s = s.substr(0, s.find("::")) + '.'; 59 | 60 | uint64_t i; 61 | // get zeros 62 | for (i = num; i != 0; --i) { 63 | a *= base; 64 | t = a / denominator; 65 | a %= denominator; 66 | if (t != 0) break; 67 | s += '0'; // TODO: replace, it's wrong for alphabet beginning from not '0' 68 | if (base > 62) s += ':'; // TODO: replace, alphabet's size specific 69 | } 70 | 71 | // get rest 72 | Bint b; 73 | for ( ; i != 0; --i) { 74 | b *= base; 75 | b += t; 76 | 77 | a *= base; 78 | t = a / denominator; 79 | a %= denominator; 80 | } 81 | 82 | return s + b.base(base); 83 | } 84 | 85 | //////////////////////////////////////////////////////////////////////// 86 | // INPUT-OUTPUT FUNCTIONS 87 | //////////////////////////////////////////////////////////////////////// 88 | 89 | std::ostream& operator << (std::ostream& strm, const Brat& a) { 90 | return strm << a.toString(); 91 | } 92 | /* 93 | std::istream& operator >> (std::istream& strm, Brat& a) { 94 | std::string s; 95 | strm >> s; 96 | a = s; 97 | return strm; 98 | } 99 | //*/ 100 | 101 | 102 | } // namespace 103 | -------------------------------------------------------------------------------- /tests/lcm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Bint a; 13 | Bint b; 14 | Bint c; 15 | 16 | std::vector> data = { 17 | {"54", "24", "216"}, 18 | {"54", "1", "54"}, 19 | //{"54", "0", "54"}, 20 | //{"0", "0", "0"}, 21 | {"5634563456345624562456435634563456345636574567456763434536745247235423452345234523451234355634563456345664", "245635675674678567856785678545674568", "173006225216413715740126566995238155829519723604703958043497563993382627864804795006579693654556009408777877641656298930034989063774882734144"}, 22 | {"8345383455657547867846978956789567854653456345563456345634562456245634563456345634566163675675674674567456", "245345345345345345345345674678678567856785678567856730584300921369395234456456456454456", "255937623245954076878040201197905480781418879882004205574133926397656696777744624333525375217089291910726114803492949229473178060518037013031244557537874739849369070493450582447838575145472992"}, 23 | {"6443534534546425624523462453567245728436724562456234563567456746734563456", "34245698729348249569258298624572785723745823845728452457824356", "55165835605557023181848233454674621745745707233848930994611262356527852260513761154129799643140381351540577562858660542564182296083584"}, 24 | {"4213518165211821182155201879854514971797088", "9307999046194775203602390818721305202949035", "318857098072487730162070861687937008783824504874318711282673670233575906334237604960"}, 25 | }; 26 | 27 | /////////////////////////////////////////////////////////// 28 | 29 | std::cout << "Least Common Multiple:" << std::endl; 30 | 31 | std::cout << "positives:" << std::endl; 32 | for (auto& s : data) { 33 | a = s[0]; 34 | std::cout << "a = " << a << std::endl; 35 | std::cout << "a = " << a.bin() << std::endl; 36 | b = s[1]; 37 | std::cout << "b = " << b << std::endl; 38 | std::cout << "b = " << b.bin() << std::endl; 39 | c = Math::lcm(a, b); 40 | std::cout << "c = " << c << std::endl; 41 | std::cout << "c = " << c.bin() << std::endl; 42 | std::cout << "s = " << s[2] << std::endl; 43 | assert(c.toString()==s[2]); 44 | std::cout << std::endl; 45 | } 46 | 47 | std::cout << "negatives:" << std::endl; 48 | for (auto& s : data) { 49 | a = "-"+s[0]; 50 | std::cout << "a = " << a << std::endl; 51 | std::cout << "a = " << a.bin() << std::endl; 52 | b = s[1]; 53 | std::cout << "b = " << b << std::endl; 54 | std::cout << "b = " << b.bin() << std::endl; 55 | c = Math::lcm(a, b); 56 | std::cout << "c = " << c << std::endl; 57 | std::cout << "c = " << c.bin() << std::endl; 58 | std::cout << "s = " << s[2] << std::endl; 59 | assert(c.toString()==s[2]); 60 | std::cout << std::endl; 61 | } 62 | 63 | for (auto& s : data) { 64 | a = s[0]; 65 | std::cout << "a = " << a << std::endl; 66 | std::cout << "a = " << a.bin() << std::endl; 67 | b = "-"+s[1]; 68 | std::cout << "b = " << b << std::endl; 69 | std::cout << "b = " << b.bin() << std::endl; 70 | c = Math::lcm(a, b); 71 | std::cout << "c = " << c << std::endl; 72 | std::cout << "c = " << c.bin() << std::endl; 73 | std::cout << "s = " << s[2] << std::endl; 74 | assert(c.toString()==s[2]); 75 | std::cout << std::endl; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /tests/brat-point.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Brat a; 12 | Brat c; 13 | 14 | std::vector> data = { 15 | {"453453/434538", "1.04352898940944175192963561299587147729312511218811", "1.1kevzj90iucwsuh3jpribijw1mmg61qt71c5kztpvp2duatfet::36", "1.4:35:28:98:94:9:44:17:51:92:96:35:61:29:95:87:14:77:29:31:25:11:21:88:11:70:34:64:36:90:54:2:97:97:16:38:84:40:13:64:20:75:3:14:12:67:27:69:70:2::100"}, 16 | {"1/434538", "0.00000230129470840294749826252249515577463881179551", "0.0003v5f1av76ta9ao42vpvdgxl6wtt9gb1hb47vgdangvz7nk9::36", "0.0:0:2:30:12:94:70:84:2:94:74:98:26:25:22:49:51:55:77:46:38:81:17:95:51:61:57:39:1:47:69:70:94:38:53:1:17:4:38:48:86:93:73:90:97:61:63:18:94:10::100"}, 17 | {"-1/434538", "-0.00000230129470840294749826252249515577463881179551", "-0.0003v5f1av76ta9ao42vpvdgxl6wtt9gb1hb47vgdangvz7nk9::36", "-0.0:0:2:30:12:94:70:84:2:94:74:98:26:25:22:49:51:55:77:46:38:81:17:95:51:61:57:39:1:47:69:70:94:38:53:1:17:4:38:48:86:93:73:90:97:61:63:18:94:10::100"}, 18 | {"171770057/8920503206", "0.01925564657433967632610253892890086810647574134171", "0.0oye3bbxc9ql9aq5wf6pcs85eirfkx3mojty0nze25udix3o6q::36", "0.1:92:55:64:65:74:33:96:76:32:61:2:53:89:28:90:8:68:10:64:75:74:13:41:71:55:15:77:37:85:82:24:58:67:98:4:66:3:38:12:66:69:57:74:78:54:20:77:66:31::100"}, 19 | {"3648111/3648112", "0.99999972588560877516918340226396558000412268044402", "0.zzzzjfb96azavcnmk4nog2c7q7zyq5wghfp6i9805vzpdrcw1e::36", "0.99:99:99:72:58:85:60:87:75:16:91:83:40:22:63:96:55:80:0:41:22:68:4:44:2:14:55:48:16:29:94:99:57:67:67:37:99:48:86:12:19:17:30:95:56:28:55:52:63:65::100"}, 20 | {"364811100000/3648112", "99999.97258856087751691834022639655800041226804440214554", "255r.z0h3b3ihxp0vodkay768y1nrfhr9lcttlmjblmude4q62lh9mu::36", "9:99:99.97:25:88:56:8:77:51:69:18:34:2:26:39:65:58:0:4:12:26:80:44:40:21:45:54:81:62:99:49:95:76:76:73:79:94:88:61:21:91:73:9:55:62:85:55:26:36:54:18:60::100"}, 21 | }; 22 | 23 | /////////////////////////////////////////////////////////// 24 | 25 | std::cout << "Point:" << std::endl; 26 | std::cout << "Decimal:" << std::endl; 27 | int p = 50; 28 | 29 | for (auto& s : data) { 30 | a = s[0]; 31 | std::cout << "a = " << a << std::endl; 32 | std::cout << "a.point = " << a.point(p) << std::endl; 33 | std::cout << "s = " << s[1] << std::endl; 34 | assert(a.point(p) == s[1]); 35 | std::cout << std::endl; 36 | } 37 | 38 | std::cout << "Base36:" << std::endl; 39 | int b = 36; 40 | for (auto& s : data) { 41 | a = s[0]; 42 | std::cout << "a = " << a << std::endl; 43 | std::cout << "a.point = " << a.point(p) << std::endl; 44 | std::cout << "a.point = " << a.point(p, b) << std::endl; 45 | std::cout << "s = " << s[1] << std::endl; 46 | std::cout << "s = " << s[2] << std::endl; 47 | assert(a.point(p, b) == s[2]); 48 | std::cout << std::endl; 49 | } 50 | 51 | std::cout << "Base100:" << std::endl; 52 | b = 100; 53 | for (auto& s : data) { 54 | a = s[0]; 55 | std::cout << "a = " << a << std::endl; 56 | std::cout << "a.point = " << a.point(p) << std::endl; 57 | std::cout << "a.point = " << a.point(p, b) << std::endl; 58 | std::cout << "s = " << s[1] << std::endl; 59 | std::cout << "s = " << s[3] << std::endl; 60 | assert(a.point(p, b) == s[3]); 61 | std::cout << std::endl; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /tests/pows.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Bint a; 13 | Bint b; 14 | Bint c; 15 | Bint d; 16 | 17 | std::vector> data = { 18 | {"54", "1000", "24760523525153779042306425129042269170653438632102989289544245144217598697196575585336370332945691516639356072848874341645755486127625134772026649610191898106418756222669348253814776455903046107875082937588780155141525869928519863596975366561706902385571900178496766399051533059979166948946650263969858538012166978770580387290596392969401930284582083127664574596100564834836845736883764033170698790188606728287186224833520012928247649705039562028741362770580247617032117021446662063508230628442076159292266562480926397575844212221244076481075152300762457397378510962422563672091530864296251823324452297940669976141519582053969670065633449517596064824560841429396987086467452540316672467861223805386560597408246976035124640630810815234975296683743350880439812030120104242464216194346217965060628596783121731670534182531712933262289278504575558302053816914901606780865442923829250668836788355341952692755089540425038300445641524422473735862739990663552433013291551496492967051494757169825684396578977386073958461460103421505112691017948083246639724179435791540048976394141209183397099150761658509034123001250516397655195412171623659751971193920443642011422388466334476642785719106425015081569535889715959774643496150478244690158679571595727649427050906746186791288802545662233466465555460786901661811525320391946268888379748388806427656128328034318862979075814243060548498608633009786619957089897230197538201991904051751480925061108356607540115011204530435494291485511821941549634370046574708674513664628847894905309481477991728283983668928353134342859814856284338446898254753315151574922478357491503003401133419295362125784165116496005315702829423003010087199888510946399845971137259733871724301253338863833453089612420126532096229376", "4444", "1112"}, 19 | {"-54", "5", "-459165024", "4344", "-4224"}, 20 | {"-54", "6", "24794911296", "7447", "5644"}, 21 | {"10", "0", "1", "7", "1"}, 22 | }; 23 | 24 | /////////////////////////////////////////////////////////// 25 | 26 | std::cout << "Pow:" << std::endl; 27 | 28 | for (auto& s : data) { 29 | a = s[0]; 30 | std::cout << "a = " << a << std::endl; 31 | std::cout << "a = " << a.bin() << std::endl; 32 | b = s[1]; 33 | std::cout << "b = " << b << std::endl; 34 | std::cout << "b = " << b.bin() << std::endl; 35 | c = Math::pow(a, std::stoi(b)); 36 | std::cout << "c = " << c << std::endl; 37 | std::cout << "s = " << s[2] << std::endl; 38 | assert(c.toString()==s[2]); 39 | std::cout << std::endl; 40 | } 41 | 42 | std::cout << "ModPow:" << std::endl; 43 | 44 | for (auto& s : data) { 45 | a = s[0]; 46 | std::cout << "a = " << a << std::endl; 47 | std::cout << "a = " << a.bin() << std::endl; 48 | b = s[1]; 49 | std::cout << "b = " << b << std::endl; 50 | std::cout << "b = " << b.bin() << std::endl; 51 | d = s[3]; 52 | std::cout << "d = " << d << std::endl; 53 | std::cout << "d = " << d.bin() << std::endl; 54 | c = Math::modPow(a, std::stoi(b), std::stoi(d)); 55 | std::cout << "c = " << c << std::endl; 56 | std::cout << "s = " << s[4] << std::endl; 57 | assert(c.toString()==s[4]); 58 | std::cout << std::endl; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /tests/product.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Bint a; 12 | Bint b; 13 | Bint c; 14 | 15 | std::vector> data = { 16 | {"2305843009213693952", "5316911983139663491615228241121378304"}, 17 | {"4611686018427387904", "21267647932558653966460912964485513216"}, 18 | {"9223372036854775808", "85070591730234615865843651857942052864"}, 19 | {"18446744073709551616", "340282366920938463463374607431768211456"}, 20 | {"36893488147419103232", "1361129467683753853853498429727072845824"} 21 | }; 22 | 23 | /////////////////////////////////////////////////////////// 24 | 25 | a = "-500000000000000000000000000000000000000000000000"; 26 | std::cout << "a = " << a << std::endl; 27 | std::cout << "a = " << a.bin() << std::endl; 28 | 29 | b = "-500000000000000000000000000000000000000000"; 30 | std::cout << "b = " << b << std::endl; 31 | std::cout << "b = " << b.bin() << std::endl; 32 | 33 | c = a * b; 34 | std::cout << "c = " << c << std::endl; 35 | std::cout << "c = " << c.bin() << std::endl; 36 | assert(c.toString()=="250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); 37 | std::cout << std::endl; 38 | 39 | /////////////////////////////////////////////////////////// 40 | 41 | std::cout << "square:" << std::endl; 42 | 43 | std::cout << "positives:" << std::endl; 44 | for (auto& s : data) { 45 | a = s[0]; 46 | std::cout << "a = " << a << std::endl; 47 | std::cout << "a = " << a.bin() << std::endl; 48 | 49 | a *= a; 50 | std::cout << "a = " << a << std::endl; 51 | std::cout << "a = " << a.bin() << std::endl; 52 | assert(a.toString()==s[1]); 53 | std::cout << std::endl; 54 | } 55 | 56 | std::cout << "negatives:" << std::endl; 57 | for (auto& s : data) { 58 | a = "-" + s[0]; 59 | std::cout << "a = " << a << std::endl; 60 | std::cout << "a = " << a.bin() << std::endl; 61 | 62 | a *= a; 63 | std::cout << "a = " << a << std::endl; 64 | std::cout << "a = " << a.bin() << std::endl; 65 | assert(a.toString()==s[1]); 66 | std::cout << std::endl; 67 | } 68 | 69 | /////////////////////////////////////////////////////////// 70 | 71 | std::cout << "product:" << std::endl; 72 | 73 | std::cout << "positives:" << std::endl; 74 | for (auto& s : data) { 75 | a = s[1]; 76 | std::cout << "a = " << a << std::endl; 77 | std::cout << "a = " << a.bin() << std::endl; 78 | 79 | int i = -10; 80 | std::cout << "i = " << i << std::endl; 81 | a *= i; 82 | std::cout << "a = " << a << std::endl; 83 | std::cout << "a = " << a.bin() << std::endl; 84 | assert(a.toString()==("-" + s[1]+ "0")); 85 | std::cout << std::endl; 86 | } 87 | 88 | std::cout << "negatives:" << std::endl; 89 | for (auto& s : data) { 90 | a = "-" + s[1]; 91 | std::cout << "a = " << a << std::endl; 92 | std::cout << "a = " << a.bin() << std::endl; 93 | 94 | std::string t = "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; 95 | std::cout << "t = " << t << std::endl; 96 | a *= t; 97 | std::cout << "a = " << a << std::endl; 98 | std::cout << "a = " << a.bin() << std::endl; 99 | assert(a.toString()==("-" + s[1] + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); 100 | std::cout << std::endl; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /tests/comparison.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Bint a; 12 | Bint b; 13 | Bint c; 14 | 15 | std::map data; 16 | data = { 17 | {61, "2305843009213693952"}, {62, "4611686018427387904"}, {63, "9223372036854775808"}, 18 | {64, "18446744073709551616"}, {65, "36893488147419103232"} 19 | }; 20 | 21 | /////////////////////////////////////////////////////////// 22 | 23 | std::cout << "comparison operators:" << std::endl; 24 | a = "-3235345345345"; 25 | b = "-2935107723423"; 26 | std::cout << "a = " << a << std::endl; 27 | std::cout << "a = " << a.bin() << std::endl; 28 | std::cout << "b = " << b << std::endl; 29 | std::cout << "b = " << b.bin() << std::endl; 30 | if (a > b) { 31 | std::cout << "a > b" << std::endl; 32 | } else { 33 | std::cout << "a !> b" << std::endl; 34 | } 35 | assert((a > b)==false); 36 | std::cout << std::endl; 37 | 38 | a = "-2135107723423"; 39 | std::cout << "a = " << a << std::endl; 40 | std::cout << "a = " << a.bin() << std::endl; 41 | std::cout << "b = " << b << std::endl; 42 | std::cout << "b = " << b.bin() << std::endl; 43 | if (a > b) { 44 | std::cout << "a > b" << std::endl; 45 | } else { 46 | std::cout << "a !> b" << std::endl; 47 | } 48 | assert((a > b)==true); 49 | std::cout << std::endl; 50 | /// 51 | a = "3235345345345"; 52 | b = "2935107723423"; 53 | std::cout << "a = " << a << std::endl; 54 | std::cout << "a = " << a.bin() << std::endl; 55 | std::cout << "b = " << b << std::endl; 56 | std::cout << "b = " << b.bin() << std::endl; 57 | if (a > b) { 58 | std::cout << "a > b" << std::endl; 59 | } else { 60 | std::cout << "a !> b" << std::endl; 61 | } 62 | assert((a > b)==true); 63 | std::cout << std::endl; 64 | 65 | a = "2135107723423"; 66 | std::cout << "a = " << a << std::endl; 67 | std::cout << "a = " << a.bin() << std::endl; 68 | std::cout << "b = " << b << std::endl; 69 | std::cout << "b = " << b.bin() << std::endl; 70 | if (a > b) { 71 | std::cout << "a > b" << std::endl; 72 | } else { 73 | std::cout << "a !> b" << std::endl; 74 | } 75 | assert((a > b)==false); 76 | std::cout << std::endl; 77 | 78 | /////////////////////////////////////////////////////////// 79 | 80 | a = "-3235345345345"; 81 | b = "-2935107723423"; 82 | std::cout << "a = " << a << std::endl; 83 | std::cout << "a = " << a.bin() << std::endl; 84 | std::cout << "b = " << b << std::endl; 85 | std::cout << "b = " << b.bin() << std::endl; 86 | if (a < b) { 87 | std::cout << "a < b" << std::endl; 88 | } else { 89 | std::cout << "a !< b" << std::endl; 90 | } 91 | assert((a < b)==true); 92 | std::cout << std::endl; 93 | 94 | a = "-2135107723423"; 95 | std::cout << "a = " << a << std::endl; 96 | std::cout << "a = " << a.bin() << std::endl; 97 | std::cout << "b = " << b << std::endl; 98 | std::cout << "b = " << b.bin() << std::endl; 99 | if (a < b) { 100 | std::cout << "a < b" << std::endl; 101 | } else { 102 | std::cout << "a !< b" << std::endl; 103 | } 104 | assert((a < b)==false); 105 | std::cout << std::endl; 106 | /// 107 | a = "3235345345345"; 108 | b = "2935107723423"; 109 | std::cout << "a = " << a << std::endl; 110 | std::cout << "a = " << a.bin() << std::endl; 111 | std::cout << "b = " << b << std::endl; 112 | std::cout << "b = " << b.bin() << std::endl; 113 | if (a < b) { 114 | std::cout << "a < b" << std::endl; 115 | } else { 116 | std::cout << "a !< b" << std::endl; 117 | } 118 | assert((a < b)==false); 119 | std::cout << std::endl; 120 | 121 | a = "2135107723423"; 122 | std::cout << "a = " << a << std::endl; 123 | std::cout << "a = " << a.bin() << std::endl; 124 | std::cout << "b = " << b << std::endl; 125 | std::cout << "b = " << b.bin() << std::endl; 126 | if (a < b) { 127 | std::cout << "a < b" << std::endl; 128 | } else { 129 | std::cout << "a !< b" << std::endl; 130 | } 131 | assert((a < b)==true); 132 | std::cout << std::endl; 133 | } 134 | -------------------------------------------------------------------------------- /tests/bits.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Bint a; 12 | Bint b; 13 | Bint c; 14 | 15 | std::vector> data = { 16 | {"54", "24", "16", "62", "46", "-55"}, 17 | {"546345634563456346534563456345634554", "645634563967877275645748456834856475", "540488919652592388619687676516300314", "651491278878741233560624236664190715", "111002359226148844940936560147890401", "-546345634563456346534563456345634555"}, 18 | {"543", "0", "0", "543", "543", "-544"}, 19 | {"0", "34534534", "0", "34534534", "34534534", "-1"}, 20 | {"0", "0", "0", "0", "0", "-1"}, 21 | {"5634563456345624562456435634563456345636574567456763434536745247235423452345234523451234355634563456345664", "245635675674678567856785678545674568", "209274063275951493981402799900074048", "5634563456345624562456435634563456345636574567456763434536745247235423488706846922178308231017442101946184", "5634563456345624562456435634563456345636574567456763434536745247235423279432783646226814249614642201872136", "-5634563456345624562456435634563456345636574567456763434536745247235423452345234523451234355634563456345665"}, 22 | {"8345383455657547867846978956789567854653456345563456345634562456245634563456345634566163675675674674567456", "245345345345345345345345674678678567856785678567856730584300921369395234456456456454456", "74326086151754002906920882714427839311485329518267565116821366681537180868657107173664", "8345383455657547868017998215983159197091881137527707074179862805295223728923825189254021729263474023848248", "8345383455657547867943672129831405194184960254813279234868377475776956163807003822572484548394816916674584", "-8345383455657547867846978956789567854653456345563456345634562456245634563456345634566163675675674674567457"}, 23 | }; 24 | 25 | /////////////////////////////////////////////////////////// 26 | 27 | std::cout << "Bit operations:" << std::endl; 28 | 29 | std::cout << "Bit AND:" << std::endl; 30 | std::cout << "positives:" << std::endl; 31 | for (auto& s : data) { 32 | a = s[0]; 33 | std::cout << "a = " << a << std::endl; 34 | std::cout << "a = " << a.bin() << std::endl; 35 | b = s[1]; 36 | std::cout << "b = " << b << std::endl; 37 | std::cout << "b = " << b.bin() << std::endl; 38 | c = a & b; 39 | std::cout << "c = " << c << std::endl; 40 | std::cout << "c = " << c.bin() << std::endl; 41 | std::cout << "s = " << s[2] << std::endl; 42 | assert(c.toString()==s[2]); 43 | std::cout << std::endl; 44 | } 45 | 46 | std::cout << "Bit OR:" << std::endl; 47 | std::cout << "positives:" << std::endl; 48 | for (auto& s : data) { 49 | a = s[0]; 50 | std::cout << "a = " << a << std::endl; 51 | std::cout << "a = " << a.bin() << std::endl; 52 | b = s[1]; 53 | std::cout << "b = " << b << std::endl; 54 | std::cout << "b = " << b.bin() << std::endl; 55 | c = a | b; 56 | std::cout << "c = " << c << std::endl; 57 | std::cout << "c = " << c.bin() << std::endl; 58 | std::cout << "s = " << s[3] << std::endl; 59 | assert(c.toString()==s[3]); 60 | std::cout << std::endl; 61 | } 62 | 63 | std::cout << "Bit XOR:" << std::endl; 64 | std::cout << "positives:" << std::endl; 65 | for (auto& s : data) { 66 | a = s[0]; 67 | std::cout << "a = " << a << std::endl; 68 | std::cout << "a = " << a.bin() << std::endl; 69 | b = s[1]; 70 | std::cout << "b = " << b << std::endl; 71 | std::cout << "b = " << b.bin() << std::endl; 72 | c = a ^ b; 73 | std::cout << "c = " << c << std::endl; 74 | std::cout << "c = " << c.bin() << std::endl; 75 | std::cout << "s = " << s[4] << std::endl; 76 | assert(c.toString()==s[4]); 77 | std::cout << std::endl; 78 | } 79 | 80 | std::cout << "Bit NOT(COMPLEMENT):" << std::endl; 81 | std::cout << "positives:" << std::endl; 82 | for (auto& s : data) { 83 | a = s[0]; 84 | std::cout << "a = " << a << std::endl; 85 | std::cout << "a = " << a.bin() << std::endl; 86 | c = ~a; 87 | std::cout << "c = " << c << std::endl; 88 | std::cout << "c = " << c.bin() << std::endl; 89 | std::cout << "s = " << s[5] << std::endl; 90 | assert(c.toString()==s[5]); 91 | std::cout << std::endl; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/Bint/bitoperations.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | Bint& Bint::bitOperation(const Bint& a, std::function&& lambda) { 32 | Bint aa(a); 33 | extendNumberBySizeOf(*this, aa); 34 | extendNumberBySizeOf(aa, *this); 35 | 36 | const std::vector& bin = aa.number; 37 | 38 | for(int j = 0; j < (int)bin.size(); j++) { 39 | number[j] = lambda(number[j], bin[j]); 40 | } 41 | 42 | return *this; 43 | } 44 | 45 | Bint& Bint::bitOperation(const int64_t a, std::function&& lambda) { 46 | number[0] = lambda(number[0], a); 47 | uint64_t b; 48 | 49 | if (a < 0) { 50 | b = -1; 51 | } else { 52 | b = 0; 53 | } 54 | 55 | for(int j = 1; j < (int)number.size(); j++) { 56 | number[j] = lambda(number[j], b); 57 | } 58 | 59 | return *this; 60 | } 61 | 62 | Bint Bint::operator | (const Bint& a) const { 63 | Bint b(*this); 64 | b |= a; 65 | return b; 66 | } 67 | 68 | Bint Bint::operator | (const int64_t a) const { 69 | Bint b(*this); 70 | b |= a; 71 | return b; 72 | } 73 | 74 | Bint& Bint::operator |= (const Bint& a) { 75 | return bitOperation(a, [](auto a, auto b) { return a | b; }); 76 | } 77 | 78 | Bint& Bint::operator |= (const int64_t a) { 79 | return bitOperation(a, [](auto a, auto b) { return a | b; }); 80 | } 81 | 82 | Bint Bint::operator & (const Bint& a) const { 83 | Bint b(*this); 84 | b &= a; 85 | return b; 86 | } 87 | 88 | Bint Bint::operator & (const int64_t a) const { 89 | Bint b(*this); 90 | b &= a; 91 | return b; 92 | } 93 | 94 | Bint& Bint::operator &= (const Bint& a) { 95 | return bitOperation(a, [](auto a, auto b) { return a & b; }); 96 | } 97 | 98 | Bint& Bint::operator &= (const int64_t a) { 99 | return bitOperation(a, [](auto a, auto b) { return a & b; }); 100 | } 101 | 102 | Bint Bint::operator ^ (const Bint& a) const { 103 | Bint b(*this); 104 | b ^= a; 105 | return b; 106 | } 107 | 108 | Bint Bint::operator ^ (const int64_t a) const { 109 | Bint b(*this); 110 | b ^= a; 111 | return b; 112 | } 113 | 114 | Bint& Bint::operator ^= (const Bint& a) { 115 | return bitOperation(a, [](auto a, auto b) { return a ^ b; }); 116 | } 117 | 118 | Bint& Bint::operator ^= (const int64_t a) { 119 | return bitOperation(a, [](auto a, auto b) { return a ^ b; }); 120 | } 121 | 122 | Bint Bint::operator ~ () const { 123 | Bint a(*this); 124 | std::vector& number = a.number; 125 | for(auto& item : number) { 126 | item = ~item; 127 | } 128 | return a; 129 | } 130 | 131 | /////////////////////////////////////////////////////////////// 132 | // Left side operators for int 133 | /////////////////////////////////////////////////////////////// 134 | 135 | Bint operator & (const int64_t a, const Bint& b) { 136 | return b & a; 137 | } 138 | 139 | Bint operator | (const int64_t a, const Bint& b) { 140 | return b | a; 141 | } 142 | 143 | Bint operator ^ (const int64_t a, const Bint& b) { 144 | return b ^ a; 145 | } 146 | } // namespace 147 | -------------------------------------------------------------------------------- /src/Brat/comparison.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | bool Brat::operator == (const Brat& b) const { 32 | return (numerator == b.numerator && denominator == b.denominator); 33 | } 34 | 35 | bool Brat::operator != (const Brat& b) const { 36 | return (numerator != b.numerator || denominator != b.denominator); 37 | } 38 | 39 | bool Brat::operator > (const Brat& b) const { 40 | Brat a(*this); 41 | Brat bb(b); 42 | 43 | a.numerator *= bb.denominator; 44 | bb.numerator *= a.denominator; 45 | a.denominator *= bb.denominator; 46 | bb.denominator = a.denominator; 47 | 48 | if (a.denominator > 0) { 49 | return (a.numerator > bb.numerator); 50 | } 51 | 52 | return (a.numerator < bb.numerator); 53 | } 54 | 55 | bool Brat::operator < (const Brat& b) const { 56 | Brat a(*this); 57 | Brat bb(b); 58 | 59 | a.numerator *= bb.denominator; 60 | bb.numerator *= a.denominator; 61 | a.denominator *= bb.denominator; 62 | bb.denominator = a.denominator; 63 | 64 | if (a.denominator > 0) { 65 | return (a.numerator < bb.numerator); 66 | } 67 | 68 | return (a.numerator > bb.numerator); 69 | } 70 | 71 | bool Brat::operator <= (const Brat& b) const { 72 | return !(*this > b); 73 | } 74 | 75 | bool Brat::operator >= (const Brat& b) const { 76 | return !(*this < b); 77 | } 78 | 79 | /* 80 | bool Bint::operator == (const int64_t a) const { 81 | if (number.size() != 1) return false; 82 | return (number[0] == (uint64_t)a); 83 | } 84 | 85 | bool Bint::operator != (const int64_t a) const { 86 | if (number.size() != 1) return true; 87 | return (number[0] != (uint64_t)a); 88 | } 89 | 90 | bool Bint::operator > (const int64_t a) const { 91 | bool neg = isNegative(); 92 | bool negA = (a < 0); 93 | if (neg != negA) return negA; 94 | if (number.size() > 1) return !neg; 95 | return (number[0] > (uint64_t)a); 96 | } 97 | 98 | bool Bint::operator < (const int64_t a) const { 99 | bool neg = isNegative(); 100 | bool negA = (a < 0); 101 | if (neg != negA) return neg; 102 | if (number.size() > 1) return neg; 103 | return (number[0] < (uint64_t)a); 104 | } 105 | 106 | 107 | bool Bint::operator <= (const int64_t a) const { 108 | return !(*this > a); 109 | } 110 | 111 | bool Bint::operator >= (const int64_t a) const { 112 | return !(*this < a); 113 | } 114 | 115 | /////////////////////////////////////////////////////////////// 116 | // Left side operators for int 117 | /////////////////////////////////////////////////////////////// 118 | 119 | bool operator <= (const int64_t a, const Bint &b) { 120 | return b < a; 121 | } 122 | 123 | bool operator >= (const int64_t a, const Bint &b) { 124 | return b > a; 125 | } 126 | 127 | bool operator == (const int64_t a, const Bint &b) { 128 | return b == a; 129 | } 130 | 131 | bool operator != (const int64_t a, const Bint &b) { 132 | return b != a; 133 | } 134 | 135 | bool operator < (const int64_t a, const Bint &b) { 136 | return b > a; 137 | } 138 | 139 | bool operator > (const int64_t a, const Bint &b) { 140 | return b < a; 141 | } 142 | //*/ 143 | 144 | } // namespace 145 | -------------------------------------------------------------------------------- /src/Bint/io.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | 30 | namespace BeeNum { 31 | 32 | Bint::operator std::string() const { 33 | return this->toString(); 34 | } 35 | 36 | std::string Bint::bin() const { 37 | return "0b" + base2(1); 38 | } 39 | 40 | std::string Bint::base2(const uint64_t base) const { 41 | uint64_t mask = (1 << base) - 1; 42 | std::string s = ""; 43 | 44 | Bint a(*this); 45 | uint64_t j = a.number.size() << 6; 46 | const uint64_t limit = j / base; 47 | const uint64_t rmd = j % base; 48 | j = 0; 49 | 50 | for(uint64_t i = 0; i < limit; i++) { 51 | j = a.number[0] & mask; 52 | s.push_back(alphabet[j]); 53 | a.urshift(base); 54 | } 55 | 56 | if (rmd) { 57 | j = a.number[0] & mask; 58 | s.push_back(alphabet[j]); 59 | } 60 | 61 | if (s.size() == 0) return "0"; 62 | std::reverse(s.begin(), s.end()); 63 | return s; 64 | } 65 | 66 | std::string Bint::toString() const { 67 | return base(10); 68 | } 69 | 70 | std::string Bint::hex() const { 71 | return "0x" + base2(4); 72 | } 73 | 74 | std::string Bint::oct() const { 75 | return "0" + base2(3); 76 | } 77 | 78 | std::string Bint::base(const uint64_t base) const { 79 | bool isBaseBig = (base > alphabet.size()); 80 | 81 | Bint temp(*this); 82 | bool neg = isNegative(); 83 | if (neg) { 84 | temp = -temp; 85 | } 86 | 87 | std::vectorcurrent = temp.number; 88 | std::string s = ""; 89 | 90 | while(current[0] || (current.size() > 1)) { 91 | std::vectorres; 92 | bool notFirst = false; 93 | uint64_t rmd = 0; 94 | 95 | for(int j = (int)current.size() - 1; j >= 0; j--) { 96 | uint64_t quot = div(current[j], base, rmd); 97 | if (quot) { 98 | notFirst = true; 99 | } 100 | if (notFirst) { 101 | res.push_back(quot); 102 | } 103 | } 104 | 105 | if (res.size() == 0) res.push_back(0); 106 | 107 | if (isBaseBig) { 108 | uint64_t current = rmd; 109 | do { 110 | rmd = current % 10; 111 | current = current / 10; 112 | s.push_back(alphabet[rmd]); 113 | } while (current); 114 | s.push_back(':'); 115 | } else { 116 | s.push_back(alphabet[rmd]); 117 | } 118 | 119 | std::reverse(res.begin(), res.end()); 120 | current = res; 121 | } 122 | 123 | if (s.size() == 0) { 124 | s = "0"; 125 | if (base == 10) return s; 126 | return s + "::" + std::to_string(base); 127 | } 128 | 129 | if (isBaseBig) s.pop_back(); 130 | if (neg) s += '-'; 131 | 132 | std::reverse(s.begin(), s.end()); 133 | 134 | if (base == 10) return s; 135 | return s + "::" + std::to_string(base); 136 | } 137 | 138 | //////////////////////////////////////////////////////////////////////// 139 | // INPUT-OUTPUT FUNCTIONS 140 | //////////////////////////////////////////////////////////////////////// 141 | 142 | std::ostream& operator << (std::ostream& strm, const Bint& a) { 143 | return strm << a.toString(); 144 | } 145 | 146 | std::istream& operator >> (std::istream& strm, Bint& a) { 147 | std::string s; 148 | strm >> s; 149 | a = s; 150 | return strm; 151 | } 152 | 153 | 154 | } // namespace 155 | -------------------------------------------------------------------------------- /include/BeeNum/Brat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #ifndef TIGERTV_BIG_RATIONAL_H 27 | #define TIGERTV_BIG_RATIONAL_H 28 | 29 | #include 30 | #include "Bint.h" 31 | 32 | 33 | namespace BeeNum { 34 | 35 | class Brat { 36 | private: 37 | Bint numerator; 38 | Bint denominator; 39 | 40 | void simplify(); 41 | 42 | public: 43 | // Constructors 44 | Brat(); 45 | Brat(const int64_t num); 46 | Brat(const char* s); 47 | Brat(const std::string& s); 48 | Brat(const Bint& numerator, const Bint& denominator); 49 | 50 | // getters 51 | Bint getNumerator() const; 52 | Bint getDenominator() const; 53 | 54 | // String representation 55 | std::string toString() const; 56 | std::string base(const uint64_t base) const; 57 | std::string point(const uint64_t num) const; 58 | std::string point(const uint64_t num, const uint64_t base) const; 59 | operator std::string() const; 60 | 61 | // Arithmetics 62 | Brat operator ++ (int); // postfix 63 | Brat& operator ++ (); // prefix 64 | Brat operator -- (int); // postfix 65 | Brat& operator -- (); // prefix 66 | Brat operator - () const; // prefix 67 | Brat operator + (const Brat& a) const; 68 | Brat& operator += (const Brat& a); 69 | Brat operator - (const Brat& a) const; 70 | Brat& operator -= (const Brat& a); 71 | Brat operator * (const Brat& a) const; 72 | Brat& operator *= (const Brat& a); 73 | Brat operator / (const Brat& a) const; 74 | Brat& operator /= (const Brat& a); 75 | 76 | // Comparison 77 | bool operator <= (const Brat &b) const; 78 | bool operator >= (const Brat &b) const; 79 | bool operator == (const Brat &b) const; 80 | bool operator != (const Brat &b) const; 81 | bool operator < (const Brat &b) const; 82 | bool operator > (const Brat &b) const; 83 | /* 84 | Bint operator + (const int64_t a) const; 85 | Bint& operator += (const int64_t a); 86 | Bint operator - (const int64_t a) const; 87 | Bint& operator -= (const int64_t a); 88 | Bint operator * (const int64_t a) const; 89 | Bint& operator *= (const int64_t a); 90 | Bint operator / (const int64_t a) const; 91 | Bint& operator /= (const int64_t a); 92 | 93 | 94 | bool operator <= (const int64_t a) const; 95 | bool operator >= (const int64_t a) const; 96 | bool operator == (const int64_t a) const; 97 | bool operator != (const int64_t a) const; 98 | bool operator < (const int64_t a) const; 99 | bool operator > (const int64_t a) const; 100 | //*/ 101 | }; 102 | 103 | // Input-output 104 | std::ostream& operator << (std::ostream& strm, const Brat& a); 105 | /* 106 | std::istream& operator >> (std::istream& strm, Brat& a); 107 | //*/ 108 | // Left side operators for int 109 | // Arithmetics 110 | Brat operator + (const int64_t a, const Brat& b); 111 | Brat operator - (const int64_t a, const Brat& b); 112 | Brat operator * (const int64_t a, const Brat& b); 113 | Brat operator / (const int64_t a, const Brat& b); 114 | /* 115 | // Comparison 116 | bool operator <= (const int64_t a, const Bint &b); 117 | bool operator >= (const int64_t a, const Bint &b); 118 | bool operator == (const int64_t a, const Bint &b); 119 | bool operator != (const int64_t a, const Bint &b); 120 | bool operator < (const int64_t a, const Bint &b); 121 | bool operator > (const int64_t a, const Bint &b); 122 | //*/ 123 | 124 | } // namespace 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/Bint/shifts.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | Bint Bint::operator >> (const uint64_t shift) const { 32 | Bint b(*this); 33 | b >>= shift; 34 | return b; 35 | } 36 | 37 | Bint& Bint::operator >>= (const uint64_t shift) { 38 | uint64_t sh = shift; 39 | if (sh > 63) { 40 | uint64_t q = sh / 64; // container size specific 41 | sh %= 64; 42 | // check q limits 43 | if (q >= number.size()) { 44 | number.clear(); 45 | number.push_back(0); 46 | return *this; 47 | } else { 48 | number.erase(number.begin(), number.begin() + q); 49 | } 50 | } 51 | 52 | bool neg = isNegative(); 53 | 54 | uint64_t mask = (1 << sh) - 1; 55 | uint64_t maskShift = 64 - sh; 56 | uint64_t carry = 0; 57 | 58 | for (int i = (int)number.size() - 1; i >= 0; --i) { 59 | uint64_t nextCarry = number[i] & mask; 60 | number[i] >>= sh; 61 | if (carry) { 62 | carry <<= maskShift; 63 | number[i] |= carry; 64 | } 65 | carry = nextCarry; 66 | } 67 | 68 | if (neg) { 69 | uint64_t t = -1; 70 | t <<= maskShift; 71 | uint64_t& num = number.back(); 72 | num |= t; 73 | } 74 | 75 | eraseLeadingSign(); 76 | return *this; 77 | } 78 | 79 | // unsigned right shift 80 | Bint& Bint::urshift(const uint64_t shift) { 81 | uint64_t sh = shift; 82 | if (sh > 63) { 83 | uint64_t q = sh / 64; 84 | sh %= 64; 85 | // check q limits 86 | if (q >= number.size()) { 87 | number.clear(); 88 | number.push_back(0); 89 | return *this; 90 | } else { 91 | number.erase(number.begin(), number.begin() + q); 92 | } 93 | } 94 | 95 | uint64_t mask = (1 << sh) - 1; 96 | uint64_t maskShift = 64 - sh; 97 | uint64_t carry = 0; 98 | 99 | for (int i = (int)number.size() - 1; i >= 0; --i) { 100 | uint64_t nextCarry = number[i] & mask; 101 | number[i] >>= sh; 102 | if (carry) { 103 | carry <<= maskShift; 104 | number[i] |= carry; 105 | } 106 | carry = nextCarry; 107 | } 108 | 109 | eraseLeadingSign(); 110 | 111 | return *this; 112 | } 113 | 114 | Bint Bint::operator << (const uint64_t shift) const { 115 | Bint b(*this); 116 | b <<= shift; 117 | return b; 118 | } 119 | 120 | Bint& Bint::operator <<= (const uint64_t shift) { 121 | uint64_t sh = shift; 122 | uint64_t q = 0; 123 | if (sh > 63) { // size specific 124 | q = sh / 64; 125 | sh %= 64; 126 | } 127 | bool neg = isNegative(); 128 | uint64_t mask = ~(((uint64_t)-1) >> sh); 129 | uint64_t maskShift = 64 - sh; // size specific 130 | uint64_t carry = 0; 131 | 132 | for (uint64_t& n : number) { 133 | uint64_t nextCarry = n & mask; 134 | n <<= sh ; 135 | if (carry) { 136 | carry >>= maskShift; 137 | n |= carry; 138 | } 139 | carry = nextCarry; 140 | } 141 | 142 | if (carry) { 143 | uint64_t t = neg ? -1 : 0; 144 | t <<= sh; 145 | carry >>= maskShift; 146 | carry |= t; 147 | number.push_back(carry); 148 | } 149 | 150 | if (neg != isNegative()) { 151 | if (neg) { 152 | number.push_back(-1); 153 | } else { 154 | number.push_back(0); 155 | } 156 | } 157 | 158 | if (q) { 159 | std::vector a(q, 0); 160 | number.insert(number.begin(), a.begin(), a.end()); 161 | } 162 | 163 | eraseLeadingSign(); 164 | 165 | return *this; 166 | } 167 | 168 | 169 | } // namespace 170 | -------------------------------------------------------------------------------- /src/Brat/arithmetics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | Brat Brat::operator + (const Brat& a) const { 32 | Brat b = *this; 33 | b += a; 34 | return b; 35 | } 36 | 37 | Brat& Brat::operator += (const Brat& a) { 38 | numerator *= a.denominator; 39 | numerator += denominator * a.numerator; 40 | denominator *= a.denominator; 41 | simplify(); 42 | return *this; 43 | } 44 | 45 | /* 46 | Bint Bint::operator + (const int64_t a) const { 47 | Bint b = *this; 48 | b += a; 49 | return b; 50 | } 51 | 52 | Bint& Bint::operator += (const int64_t a) { 53 | 54 | } 55 | //*/ 56 | 57 | Brat Brat::operator - (const Brat& a) const { 58 | Brat b(*this); 59 | b -= a; 60 | return b; 61 | } 62 | 63 | Brat& Brat::operator -= (const Brat& a) { 64 | Brat b(a); 65 | b.numerator = - b.numerator; 66 | (*this) += b; 67 | return *this; 68 | } 69 | 70 | Brat Brat::operator * (const Brat& a) const { 71 | Brat b(*this); 72 | b *= a; 73 | return b; 74 | } 75 | 76 | Brat& Brat::operator *= (const Brat& a) { 77 | numerator *= a.numerator; 78 | denominator *= a.denominator; 79 | simplify(); 80 | return *this; 81 | } 82 | 83 | Brat Brat::operator / (const Brat& a) const { 84 | Brat b(*this); 85 | b /= a; 86 | return b; 87 | } 88 | 89 | Brat& Brat::operator /= (const Brat& a) { 90 | numerator *= a.denominator; 91 | denominator *= a.numerator; 92 | simplify(); 93 | return *this; 94 | } 95 | 96 | Brat& Brat::operator ++ () { // prefix 97 | numerator += denominator; 98 | return *this; 99 | } 100 | 101 | Brat Brat::operator ++ (int) { // postfix 102 | Brat b = (*this); 103 | ++(*this); 104 | return b; 105 | } 106 | 107 | 108 | Brat& Brat::operator -- () { // prefix 109 | numerator -= denominator; 110 | return *this; 111 | } 112 | 113 | Brat Brat::operator -- (int) { // postfix 114 | Brat b(*this); 115 | --(*this); 116 | return b; 117 | } 118 | 119 | Brat Brat::operator - () const { // prefix 120 | Brat a(*this); 121 | a.numerator = -a.numerator; 122 | return a; 123 | } 124 | 125 | /* 126 | Bint Bint::operator - (const int64_t a) const { 127 | Bint b(*this); 128 | b -= a; 129 | return b; 130 | } 131 | 132 | Bint& Bint::operator -= (const int64_t a) { 133 | *this += -a; 134 | return *this; 135 | } 136 | 137 | Bint Bint::operator * (const int64_t a) const { 138 | Bint b = *this; 139 | b *= a; 140 | return b; 141 | } 142 | 143 | Bint& Bint::operator *= (const int64_t a) { 144 | 145 | } 146 | 147 | Bint Bint::operator / (const int64_t a) const { 148 | Bint b(*this); 149 | b /= a; 150 | return b; 151 | } 152 | 153 | Bint& Bint::operator /= (const int64_t a) { 154 | Bint c(*this); 155 | Bint res; 156 | 157 | div(c, res, a); 158 | 159 | this->number = res.number; 160 | return (*this); 161 | } 162 | 163 | //////////////////////////////////////////////////////////////////////// 164 | 165 | //*/ 166 | /////////////////////////////////////////////////////////////// 167 | // Left side operators for int 168 | /////////////////////////////////////////////////////////////// 169 | 170 | Brat operator + (const int64_t a, const Brat& b) { 171 | Brat c(a, 1); 172 | c += b; 173 | return c; 174 | } 175 | 176 | Brat operator - (const int64_t a, const Brat& b) { 177 | Brat d(a, 1); 178 | d -= b; 179 | return d; 180 | } 181 | 182 | Brat operator * (const int64_t a, const Brat& b) { 183 | Brat c(a, 1); 184 | c *= b; 185 | return c; 186 | } 187 | 188 | Brat operator / (const int64_t a, const Brat& b) { 189 | Brat c(a, 1); 190 | c /= b; 191 | return c; 192 | } 193 | 194 | } // namespace 195 | -------------------------------------------------------------------------------- /src/Bint/comparison.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | bool Bint::operator == (const int64_t a) const { 32 | if (number.size() != 1) return false; 33 | return (number[0] == (uint64_t)a); 34 | } 35 | 36 | bool Bint::operator == (const Bint &b) const { 37 | const std::vector& n = b.number; 38 | if (number.size() < n.size()) return false; 39 | if (number.size() > n.size()) return false; 40 | 41 | for(int i = (int)n.size() - 1; i >= 0; i--) { 42 | if(number[i] != n[i]) { 43 | return false; 44 | } 45 | } 46 | 47 | return true; 48 | } 49 | 50 | bool Bint::operator != (const int64_t a) const { 51 | if (number.size() != 1) return true; 52 | return (number[0] != (uint64_t)a); 53 | } 54 | 55 | bool Bint::operator != (const Bint &b) const { 56 | const std::vector& n = b.number; 57 | if (number.size() < n.size()) return true; 58 | if (number.size() > n.size()) return true; 59 | 60 | for(int i = (int)n.size() - 1; i >= 0; i--) { 61 | if(number[i] != n[i]) { 62 | return true; 63 | } 64 | } 65 | 66 | return false; 67 | } 68 | 69 | bool Bint::operator > (const Bint& b) const { 70 | bool neg = isNegative(); 71 | bool negB = b.isNegative(); 72 | if (neg != negB) return negB; 73 | 74 | const std::vector& n = b.number; 75 | if (number.size() < n.size()) return neg; 76 | if (number.size() > n.size()) return !neg; 77 | 78 | for(int i = (int)n.size() - 1; i >= 0; i--) { 79 | if(number[i] > n[i]) { 80 | return true; 81 | } 82 | if(number[i] != n[i]) return false; 83 | } 84 | 85 | return false; 86 | } 87 | 88 | bool Bint::operator > (const int64_t a) const { 89 | bool neg = isNegative(); 90 | bool negA = (a < 0); 91 | if (neg != negA) return negA; 92 | if (number.size() > 1) return !neg; 93 | return (number[0] > (uint64_t)a); 94 | } 95 | 96 | bool Bint::operator < (const int64_t a) const { 97 | bool neg = isNegative(); 98 | bool negA = (a < 0); 99 | if (neg != negA) return neg; 100 | if (number.size() > 1) return neg; 101 | return (number[0] < (uint64_t)a); 102 | } 103 | 104 | bool Bint::operator < (const Bint &b) const { 105 | bool neg = isNegative(); 106 | bool negB = b.isNegative(); 107 | if (neg != negB) return neg; 108 | 109 | const std::vector& n = b.number; 110 | if (number.size() < n.size()) return !neg; 111 | if (number.size() > n.size()) return neg; 112 | 113 | for(int i = (int)n.size() - 1; i >= 0; i--) { 114 | if(number[i] < n[i]) { 115 | return true; 116 | } 117 | if(number[i] != n[i]) return false; 118 | } 119 | 120 | return false; 121 | } 122 | 123 | bool Bint::operator <= (const Bint &b) const { 124 | return !(*this > b); 125 | } 126 | 127 | bool Bint::operator >= (const Bint &b) const { 128 | return !(*this < b); 129 | } 130 | 131 | bool Bint::operator <= (const int64_t a) const { 132 | return !(*this > a); 133 | } 134 | 135 | bool Bint::operator >= (const int64_t a) const { 136 | return !(*this < a); 137 | } 138 | 139 | /////////////////////////////////////////////////////////////// 140 | // Left side operators for int 141 | /////////////////////////////////////////////////////////////// 142 | 143 | bool operator <= (const int64_t a, const Bint &b) { 144 | return b < a; 145 | } 146 | 147 | bool operator >= (const int64_t a, const Bint &b) { 148 | return b > a; 149 | } 150 | 151 | bool operator == (const int64_t a, const Bint &b) { 152 | return b == a; 153 | } 154 | 155 | bool operator != (const int64_t a, const Bint &b) { 156 | return b != a; 157 | } 158 | 159 | bool operator < (const int64_t a, const Bint &b) { 160 | return b > a; 161 | } 162 | 163 | bool operator > (const int64_t a, const Bint &b) { 164 | return b < a; 165 | } 166 | 167 | } // namespace 168 | -------------------------------------------------------------------------------- /src/Math.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | 32 | Bint Math::pow(const Bint& a, uint64_t exp) { 33 | Bint temp(1); 34 | if (exp == 0) return temp; 35 | Bint b(a); 36 | while (exp > 1) { 37 | if (exp & 1) { 38 | temp *= b; 39 | } 40 | b *= b; 41 | exp >>= 1; 42 | } 43 | 44 | return b*temp; 45 | } 46 | 47 | Bint Math::modPow(const Bint& base, const uint64_t exp, const uint64_t mod) { 48 | Bint ret; 49 | if (mod == 1) return ret; 50 | ret = 1; 51 | Bint b(base); 52 | Bint x(exp); 53 | 54 | b %= mod; 55 | while(x > 0) { 56 | if ((x & 1) == 1) { 57 | ret *= b; 58 | ret %= mod; 59 | } 60 | x >>= 1; 61 | b *= b; 62 | b %= mod; 63 | } 64 | 65 | return ret; 66 | } 67 | 68 | Bint Math::fact(const uint64_t a) { 69 | Bint ret(1); 70 | if (a <= 1) return ret; 71 | if (a == 2) return a; 72 | 73 | uint64_t c(a); 74 | uint64_t sum = 0; 75 | std::vector bitc; 76 | 77 | while (c != 1) { 78 | bitc.push_back((c-1)|1); 79 | c >>= 1; 80 | sum += c; 81 | } 82 | 83 | uint64_t prev = 1; 84 | Bint result(1); 85 | 86 | for(int i = (int)bitc.size() - 1; i >= 0; --i) { 87 | result *= oddFact(bitc[i], prev + 2); 88 | ret *= result; 89 | prev = bitc[i]; 90 | } 91 | 92 | ret <<= sum; 93 | return ret; 94 | } 95 | 96 | Bint Math::oddFact(const uint64_t a, const uint64_t begin) { 97 | Bint ret(1); 98 | if (a < 3) { 99 | return ret; 100 | } 101 | if (a == 3) { 102 | return a; 103 | } 104 | 105 | uint64_t n = (a - 1) | 1; 106 | if (((n - begin) % 4) == 0) { 107 | ret = n; 108 | n -= 2; 109 | } 110 | 111 | Bint last(n + 2); 112 | last *= (begin - 2); 113 | 114 | for (uint64_t m = (n - begin + 2) * 2; m >= 4; m -= 8) { 115 | last += m; 116 | ret *= last; 117 | } 118 | 119 | return ret; 120 | } 121 | 122 | Bint Math::gcd(const Bint& a, const Bint& b) { 123 | Bint c; 124 | Bint aa(a); 125 | Bint bb(b); 126 | 127 | if (aa < 0) { 128 | aa = -aa; 129 | } 130 | if (bb < 0) { 131 | bb = -bb; 132 | } 133 | 134 | if (a == 0) return bb; 135 | if (b == 0) return aa; 136 | 137 | while(1) { 138 | if (aa > bb) { 139 | aa %= bb; 140 | if (aa == 0) { 141 | c = bb; 142 | break; 143 | } 144 | } else { 145 | bb %= aa; 146 | if (bb == 0) { 147 | c = aa; 148 | break; 149 | } 150 | } 151 | } 152 | 153 | return c; 154 | } 155 | 156 | Bint Math::lcm(const Bint& a, const Bint& b) { 157 | Bint c = a * b / gcd(a, b); 158 | if (c < 0) return -c; 159 | return c; 160 | } 161 | 162 | // Fibonnaci number using Fast Doubling method 163 | Bint Math::fib(const uint64_t a) { 164 | if (a < 2) return a; 165 | 166 | uint64_t c(a); 167 | std::vector bitc; 168 | 169 | while (c != 1) { 170 | bitc.push_back(c & 1); 171 | c >>= 1; 172 | } 173 | 174 | Bint fn(1); 175 | Bint fn1(1); 176 | Bint temp; 177 | 178 | for(int i = (int)bitc.size() - 1; i >= 0; --i) { 179 | temp = fn * (fn1 * 2 - fn); 180 | fn1 = fn1 * fn1 + fn * fn; 181 | if (bitc[i]) { 182 | fn = fn1; 183 | fn1 += temp; 184 | } else { 185 | fn = temp; 186 | } 187 | } 188 | 189 | return fn; 190 | } 191 | 192 | Brat Math::gcd(const Brat& a, const Brat& b) { 193 | Bint numerator = gcd(a.getNumerator(), b.getNumerator()); 194 | Bint denominator = lcm(a.getDenominator(), b.getDenominator()); 195 | Brat c(numerator, denominator); 196 | return c; 197 | } 198 | 199 | Brat Math::lcm(const Brat& a, const Brat& b) { 200 | Brat c = a * b / gcd(a, b); 201 | Brat zero; 202 | if (c < zero) return -c; 203 | return c; 204 | } 205 | 206 | Brat Math::pow(const Brat& a, uint64_t exp) { 207 | Bint b = Math::pow(a.getNumerator(), exp); 208 | Bint c = Math::pow(a.getDenominator(), exp); 209 | Brat d(b, c); 210 | return d; 211 | } 212 | 213 | } // namespace 214 | -------------------------------------------------------------------------------- /src/Bint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | 30 | namespace BeeNum { 31 | 32 | const std::string Bint::alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 33 | 34 | Bint::Bint() { 35 | number.push_back(0); 36 | } 37 | 38 | Bint::Bint(const std::string& s) : Bint() { 39 | std::string::size_type n = s.rfind("::"); 40 | int base; 41 | if (n == std::string::npos) { 42 | base = 10; 43 | setDecimal(s); 44 | } else { 45 | try { 46 | base = std::stoi(s.substr(n + 2)); 47 | } catch (...) { 48 | std::string err("Invalid base! The base should be decimal and not too big."); 49 | throw std::invalid_argument(err); 50 | } 51 | setNumber(s.substr(0, n) , base); 52 | } 53 | 54 | } 55 | 56 | void Bint::setNumber(const std::string& s, int base) { 57 | auto it = s.begin(); 58 | std::string a = alphabet.substr(0, base); 59 | bool neg = (*it == '-'); 60 | if (neg) ++it; 61 | 62 | if (base <= (int)alphabet.size()) { 63 | for(; it != s.end(); ++it) { 64 | (*this) *= base; 65 | // find digit in the alphabet 66 | size_t i = a.find(*it); 67 | if (i == std::string::npos) { 68 | std::string err("Unexpected symbol! - '"); 69 | err.push_back(*it); 70 | err.push_back('\''); 71 | throw std::invalid_argument(err); 72 | }; 73 | (*this) += i; 74 | } 75 | } else { 76 | // If the base is more than size of the alphabet we use ':' as a separator for digits in decimal 77 | std::string::size_type prev = 0; 78 | std::string::size_type n; 79 | while (true) { 80 | n = s.find(':', prev); 81 | int dec; 82 | try { 83 | if (n != std::string::npos) { 84 | dec = std::stoi(s.substr(prev, n - prev)); 85 | } else { 86 | dec = std::stoi(s.substr(prev)); 87 | (*this) *= base; 88 | (*this) += dec; 89 | break; 90 | } 91 | } catch (...) { 92 | std::string err("Unexpected symbol in string!"); 93 | throw std::invalid_argument(err); 94 | } 95 | 96 | (*this) *= base; 97 | (*this) += dec; 98 | prev = n + 1; 99 | } 100 | } 101 | 102 | if (neg) { 103 | *this = -(*this); 104 | } 105 | 106 | eraseLeadingSign(); 107 | } 108 | 109 | Bint::Bint(const char* decimal) : Bint((std::string)decimal) { 110 | 111 | } 112 | 113 | Bint::Bint(const int64_t num) { 114 | number.push_back(num); 115 | } 116 | 117 | void Bint::setDecimal(const std::string& s) { 118 | auto it = s.begin(); 119 | 120 | bool neg = (*it == '-'); 121 | if (neg) ++it; 122 | 123 | for(; it != s.end(); ++it) { 124 | (*this) *= 10; 125 | // add digit 126 | int64_t i = *it - '0'; 127 | if (i > 9) { 128 | std::string s("Unexpected symbol! - "); 129 | s.push_back(*it); 130 | throw std::invalid_argument(s); 131 | } 132 | (*this) += i; 133 | } 134 | 135 | if (neg) { 136 | *this = -(*this); 137 | } 138 | 139 | eraseLeadingSign(); 140 | } 141 | 142 | void Bint::eraseLeadingSign() { 143 | bool neg = isNegative(); 144 | uint64_t comp = 0; 145 | 146 | if (neg) { 147 | comp = -1; 148 | } 149 | 150 | for (size_t i = number.size() - 1; i != 0; i--) { 151 | if (number[i] != comp) break; 152 | bool sign = number[i-1] >> 63; 153 | // erase last 154 | if (neg == sign) number.erase(number.end()-1); 155 | } 156 | } 157 | 158 | void Bint::extendNumberBySizeOf(Bint& extNumber, const Bint& a) { 159 | const std::vector& bin = a.number; 160 | std::vector& ext = extNumber.number; 161 | 162 | int diff = (int)bin.size() - (int)ext.size(); 163 | int num = extNumber.isNegative() ? -1 : 0; 164 | 165 | for(int i = 0; i < diff; i++) { 166 | ext.push_back(num); 167 | } 168 | } 169 | 170 | bool Bint::isNegative() const { 171 | uint64_t last = number.back(); 172 | last >>= 63; // size specific 173 | return last; 174 | } 175 | 176 | 177 | } // namespace 178 | -------------------------------------------------------------------------------- /tests/brat-comparison.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Brat a; 13 | Brat b; 14 | 15 | std::vector> data = { 16 | {"500000000000000000000/200000000000000000000000000", "50000000004000000000000/400000000000000000000", "0"}, 17 | {"537483929/484588458292993", "543563/24994884934885", "1"}, 18 | {"2/3", "6/11", "1"}, 19 | {"2/3", "2/3", "0"}, 20 | {"-2/3", "6/-11", "0"}, 21 | }; 22 | 23 | /////////////////////////////////////////////////////////// 24 | std::cout << "comparison:" << std::endl; 25 | 26 | std::cout << "operator >:" << std::endl; 27 | std::cout << "positives:" << std::endl; 28 | for (auto& s : data) { 29 | a = s[0]; 30 | std::cout << "a = " << a << std::endl; 31 | b = s[1]; 32 | std::cout << "b = " << b << std::endl; 33 | 34 | bool t = (s[2] != "0"); 35 | std::cout << "t = " << t << std::endl; 36 | bool c = a > b; 37 | std::cout << "c = a > b" << std::endl; 38 | std::cout << "c = " << c << std::endl; 39 | assert(t == c); 40 | std::cout << std::endl; 41 | } 42 | 43 | std::cout << "negatives:" << std::endl; 44 | for (auto& s : data) { 45 | a = s[0]; 46 | a = -a; 47 | std::cout << "a = " << a << std::endl; 48 | b = s[1]; 49 | b = -b; 50 | std::cout << "b = " << b << std::endl; 51 | 52 | bool t = !(s[2] != "0"); 53 | if (a == b) { 54 | t = !t; 55 | } 56 | std::cout << "t = " << t << std::endl; 57 | bool c = a > b; 58 | std::cout << "c = a > b" << std::endl; 59 | std::cout << "c = " << c << std::endl; 60 | assert(t == c); 61 | std::cout << std::endl; 62 | } 63 | 64 | /////////////////////////////////////////////////////////// 65 | 66 | std::cout << "operator <=:" << std::endl; 67 | std::cout << "positives:" << std::endl; 68 | for (auto& s : data) { 69 | a = s[0]; 70 | std::cout << "a = " << a << std::endl; 71 | b = s[1]; 72 | std::cout << "b = " << b << std::endl; 73 | 74 | bool t = !(s[2] != "0"); 75 | std::cout << "t = " << t << std::endl; 76 | bool c = (a <= b); 77 | std::cout << "c = a <= b" << std::endl; 78 | std::cout << "c = " << c << std::endl; 79 | assert(t == c); 80 | std::cout << std::endl; 81 | } 82 | 83 | std::cout << "negatives:" << std::endl; 84 | for (auto& s : data) { 85 | a = s[0]; 86 | a = -a; 87 | std::cout << "a = " << a << std::endl; 88 | b = s[1]; 89 | b = -b; 90 | std::cout << "b = " << b << std::endl; 91 | 92 | bool t = (s[2] != "0"); 93 | if (a == b) { 94 | t = !t; 95 | } 96 | std::cout << "t = " << t << std::endl; 97 | bool c = (a <= b); 98 | std::cout << "c = a <= b" << std::endl; 99 | std::cout << "c = " << c << std::endl; 100 | assert(t == c); 101 | std::cout << std::endl; 102 | } 103 | 104 | /////////////////////////////////////////////////////////// 105 | 106 | std::cout << "operator <:" << std::endl; 107 | std::cout << "positives:" << std::endl; 108 | for (auto& s : data) { 109 | a = s[0]; 110 | std::cout << "a = " << a << std::endl; 111 | b = s[1]; 112 | std::cout << "b = " << b << std::endl; 113 | 114 | bool t = !(s[2] != "0"); 115 | if (a == b) { 116 | t = false; 117 | } 118 | std::cout << "t = " << t << std::endl; 119 | bool c = (a < b); 120 | std::cout << "c = a < b" << std::endl; 121 | std::cout << "c = " << c << std::endl; 122 | assert(t == c); 123 | std::cout << std::endl; 124 | } 125 | 126 | std::cout << "negatives:" << std::endl; 127 | for (auto& s : data) { 128 | a = s[0]; 129 | a = -a; 130 | std::cout << "a = " << a << std::endl; 131 | b = s[1]; 132 | b = -b; 133 | std::cout << "b = " << b << std::endl; 134 | 135 | bool t = (s[2] != "0"); 136 | if (a == b) { 137 | t = false; 138 | } 139 | std::cout << "t = " << t << std::endl; 140 | bool c = (a < b); 141 | std::cout << "c = a < b" << std::endl; 142 | std::cout << "c = " << c << std::endl; 143 | assert(t == c); 144 | std::cout << std::endl; 145 | } 146 | 147 | /////////////////////////////////////////////////////////// 148 | 149 | std::cout << "operator >=:" << std::endl; 150 | std::cout << "positives:" << std::endl; 151 | for (auto& s : data) { 152 | a = s[0]; 153 | std::cout << "a = " << a << std::endl; 154 | b = s[1]; 155 | std::cout << "b = " << b << std::endl; 156 | 157 | bool t = (s[2] != "0"); 158 | if (a == b) { 159 | t = true; 160 | } 161 | std::cout << "t = " << t << std::endl; 162 | bool c = (a >= b); 163 | std::cout << "c = a >= b" << std::endl; 164 | std::cout << "c = " << c << std::endl; 165 | assert(t == c); 166 | std::cout << std::endl; 167 | } 168 | 169 | std::cout << "negatives:" << std::endl; 170 | for (auto& s : data) { 171 | a = s[0]; 172 | a = -a; 173 | std::cout << "a = " << a << std::endl; 174 | b = s[1]; 175 | b = -b; 176 | std::cout << "b = " << b << std::endl; 177 | 178 | bool t = !(s[2] != "0"); 179 | if (a == b) { 180 | t = true; 181 | } 182 | std::cout << "t = " << t << std::endl; 183 | bool c = (a >= b); 184 | std::cout << "c = a >= b" << std::endl; 185 | std::cout << "c = " << c << std::endl; 186 | assert(t == c); 187 | std::cout << std::endl; 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /tests/fibonnaci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace BeeNum; 9 | 10 | 11 | int main() { 12 | Bint a; 13 | Bint c; 14 | 15 | std::vector> data = { 16 | {"10", "55"}, 17 | {"11", "89"}, 18 | {"399", "108788617463475645289761992289049744844995705477812699099751202749393926359816304226"}, 19 | {"400", "176023680645013966468226945392411250770384383304492191886725992896575345044216019675"}, 20 | {"401", "284812298108489611757988937681460995615380088782304890986477195645969271404032323901"}, 21 | {"0", "0"}, 22 | {"1", "1"}, 23 | {"2", "1"}, 24 | {"10000", "33644764876431783266621612005107543310302148460680063906564769974680081442166662368155595513633734025582065332680836159373734790483865268263040892463056431887354544369559827491606602099884183933864652731300088830269235673613135117579297437854413752130520504347701602264758318906527890855154366159582987279682987510631200575428783453215515103870818298969791613127856265033195487140214287532698187962046936097879900350962302291026368131493195275630227837628441540360584402572114334961180023091208287046088923962328835461505776583271252546093591128203925285393434620904245248929403901706233888991085841065183173360437470737908552631764325733993712871937587746897479926305837065742830161637408969178426378624212835258112820516370298089332099905707920064367426202389783111470054074998459250360633560933883831923386783056136435351892133279732908133732642652633989763922723407882928177953580570993691049175470808931841056146322338217465637321248226383092103297701648054726243842374862411453093812206564914032751086643394517512161526545361333111314042436854805106765843493523836959653428071768775328348234345557366719731392746273629108210679280784718035329131176778924659089938635459327894523777674406192240337638674004021330343297496902028328145933418826817683893072003634795623117103101291953169794607632737589253530772552375943788434504067715555779056450443016640119462580972216729758615026968443146952034614932291105970676243268515992834709891284706740862008587135016260312071903172086094081298321581077282076353186624611278245537208532365305775956430072517744315051539600905168603220349163222640885248852433158051534849622434848299380905070483482449327453732624567755879089187190803662058009594743150052402532709746995318770724376825907419939632265984147498193609285223945039707165443156421328157688908058783183404917434556270520223564846495196112460268313970975069382648706613264507665074611512677522748621598642530711298441182622661057163515069260029861704945425047491378115154139941550671256271197133252763631939606902895650288268608362241082050562430701794976171121233066073310059947366875"}, 25 | {"10001", "54438373113565281338734260993750380135389184554695967026247715841208582865622349017083051547938960541173822675978026317384359584751116241439174702642959169925586334117906063048089793531476108466259072759367899150677960088306597966641965824937721800381441158841042480997984696487375337180028163763317781927941101369262750979509800713596718023814710669912644214775254478587674568963808002962265133111359929762726679441400101575800043510777465935805362502461707918059226414679005690752321895868142367849593880756423483754386342639635970733756260098962462668746112041739819404875062443709868654315626847186195620146126642232711815040367018825205314845875817193533529827837800351902529239517836689467661917953884712441028463935449484614450778762529520961887597272889220768537396475869543159172434537193611263743926337313005896167248051737986306368115003088396749587102619524631352447499505204198305187168321623283859794627245919771454628218399695789223798912199431775469705216131081096559950638297261253848242007897109054754028438149611930465061866170122983288964352733750792786069444761853525144421077928045979904561298129423809156055033032338919609162236698759922782923191896688017718575555520994653320128446502371153715141749290913104897203455577507196645425232862022019506091483585223882711016708433051169942115775151255510251655931888164048344129557038825477521111577395780115868397072602565614824956460538700280331311861485399805397031555727529693399586079850381581446276433858828529535803424850845426446471681531001533180479567436396815653326152509571127480411928196022148849148284389124178520174507305538928717857923509417743383331506898239354421988805429332440371194867215543576548565499134519271098919802665184564927827827212957649240235507595558205647569365394873317659000206373126570643509709482649710038733517477713403319028105575667931789470024118803094604034362953471997461392274791549730356412633074230824051999996101549784667340458326852960388301120765629245998136251652347093963049734046445106365304163630823669242257761468288461791843224793434406079917883360676846711185597501"}, 26 | }; 27 | 28 | /////////////////////////////////////////////////////////// 29 | 30 | std::cout << "Fibonnaci:" << std::endl; 31 | 32 | std::cout << "positives:" << std::endl; 33 | for (auto& s : data) { 34 | a = s[0]; 35 | std::cout << "a = " << a << std::endl; 36 | std::cout << "a = " << a.bin() << std::endl; 37 | c = Math::fib(std::stoi(a)); 38 | std::cout << "c = " << c << std::endl; 39 | std::cout << "s = " << s[1] << std::endl; 40 | assert(c.toString()==s[1]); 41 | std::cout << std::endl; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /tests/division.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace BeeNum; 8 | 9 | 10 | int main() { 11 | Bint a; 12 | Bint b; 13 | Bint c; 14 | 15 | std::vector> data = { 16 | {"563456345634562456245643563456345634563657456745676345634563456345661", "245635675674678567856785678545674567", "2293870155818927461038824163537040", "194671830340138360905494231965883981"}, 17 | {"83453834556575478678469789567895678546534563455634563456345624562456345634563456345661", "2305843009213693952", "36192331491393999030911367620299278682605219448051027508900256529311", "361706202184918589"}, 18 | {"345345997282345246457356724523465356745677423452345245656736562452452346456245", "4611686018427387904", "74884976102538365282049165625998607397784258852309259060588","1168204170632128693"}, 19 | {"9223372036854775810", "9223372036854775808", "1", "2"}, 20 | {"64435345345345223423", "18446744073709551616", "3", "9095113124216568575"}, 21 | {"653453453453453453443333333333333333333333333333333333333333333333333", "36893488147419103232", "17711891346309742104832430041142880365138504809389", "18880027887859488085"}, 22 | {"64435345345", "18446744073709551616", "0", "64435345345"}, 23 | {"0", "18446744073709551616", "0", "0"}, 24 | //{"0", "0", "0", "0"}, 25 | }; 26 | 27 | /////////////////////////////////////////////////////////// 28 | 29 | std::cout << "division:" << std::endl; 30 | 31 | std::cout << "positives:" << std::endl; 32 | for (auto& s : data) { 33 | a = s[0]; 34 | std::cout << "a = " << a << std::endl; 35 | std::cout << "a = " << a.bin() << std::endl; 36 | b = s[1]; 37 | std::cout << "b = " << b << std::endl; 38 | std::cout << "b = " << b.bin() << std::endl; 39 | c = a / b; 40 | std::cout << "c = " << c << std::endl; 41 | std::cout << "c = " << c.bin() << std::endl; 42 | std::cout << "s = " << s[2] << std::endl; 43 | assert(c.toString()==s[2]); 44 | std::cout << std::endl; 45 | } 46 | 47 | std::cout << "negatives:" << std::endl; 48 | for (auto& s : data) { 49 | a = "-"+s[0]; 50 | std::cout << "a = " << a << std::endl; 51 | std::cout << "a = " << a.bin() << std::endl; 52 | b = s[1]; 53 | std::cout << "b = " << b << std::endl; 54 | std::cout << "b = " << b.bin() << std::endl; 55 | c = a / b; 56 | std::cout << "c = " << c << std::endl; 57 | std::cout << "c = " << c.bin() << std::endl; 58 | if (s[2] == "0") { 59 | std::cout << "s = " << (s[2]) << std::endl; 60 | assert(c.toString()==s[2]); 61 | } else { 62 | std::cout << "s = " << ("-"+s[2]) << std::endl; 63 | assert(c.toString()=="-"+s[2]); 64 | } 65 | std::cout << std::endl; 66 | } 67 | 68 | for (auto& s : data) { 69 | a = s[0]; 70 | std::cout << "a = " << a << std::endl; 71 | std::cout << "a = " << a.bin() << std::endl; 72 | b = "-"+s[1]; 73 | std::cout << "b = " << b << std::endl; 74 | std::cout << "b = " << b.bin() << std::endl; 75 | c = a / b; 76 | std::cout << "c = " << c << std::endl; 77 | std::cout << "c = " << c.bin() << std::endl; 78 | if (s[2] == "0") { 79 | std::cout << "s = " << (s[2]) << std::endl; 80 | assert(c.toString()==s[2]); 81 | } else { 82 | std::cout << "s = " << ("-"+s[2]) << std::endl; 83 | assert(c.toString()=="-"+s[2]); 84 | } 85 | std::cout << std::endl; 86 | } 87 | 88 | /////////////////////////////////////////////////////////// 89 | std::cout << "reminder:" << std::endl; 90 | 91 | std::cout << "positives:" << std::endl; 92 | for (auto& s : data) { 93 | a = s[0]; 94 | std::cout << "a = " << a << std::endl; 95 | std::cout << "a = " << a.bin() << std::endl; 96 | b = s[1]; 97 | std::cout << "b = " << b << std::endl; 98 | std::cout << "b = " << b.bin() << std::endl; 99 | c = a % b; 100 | std::cout << "c = " << c << std::endl; 101 | std::cout << "c = " << c.bin() << std::endl; 102 | std::cout << "s = " << s[3] << std::endl; 103 | assert(c.toString()==s[3]); 104 | std::cout << std::endl; 105 | } 106 | 107 | std::cout << "negatives:" << std::endl; 108 | for (auto& s : data) { 109 | a = "-"+s[0]; 110 | std::cout << "a = " << a << std::endl; 111 | std::cout << "a = " << a.bin() << std::endl; 112 | b = s[1]; 113 | std::cout << "b = " << b << std::endl; 114 | std::cout << "b = " << b.bin() << std::endl; 115 | c = a % b; 116 | std::cout << "c = " << c << std::endl; 117 | std::cout << "c = " << c.bin() << std::endl; 118 | if (s[3] == "0") { 119 | std::cout << "s = " << s[3] << std::endl; 120 | assert(c.toString()==s[3]); 121 | } else { 122 | std::cout << "s = " << ("-"+s[3]) << std::endl; 123 | assert(c.toString()=="-"+s[3]); 124 | } 125 | std::cout << std::endl; 126 | } 127 | 128 | for (auto& s : data) { 129 | a = s[0]; 130 | std::cout << "a = " << a << std::endl; 131 | std::cout << "a = " << a.bin() << std::endl; 132 | b = "-"+s[1]; 133 | std::cout << "b = " << b << std::endl; 134 | std::cout << "b = " << b.bin() << std::endl; 135 | c = a % b; 136 | std::cout << "c = " << c << std::endl; 137 | std::cout << "c = " << c.bin() << std::endl; 138 | if (s[3] == "0") { 139 | std::cout << "s = " << s[3] << std::endl; 140 | assert(c.toString()==s[3]); 141 | } else { 142 | std::cout << "s = " << ("-"+s[3]) << std::endl; 143 | assert(c.toString()=="-"+s[3]); 144 | } 145 | std::cout << std::endl; 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /include/BeeNum/Bint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | 27 | #ifndef TIGERTV_BIG_INTEGER_H 28 | #define TIGERTV_BIG_INTEGER_H 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | 36 | namespace BeeNum { 37 | 38 | 39 | class Bint { 40 | private: 41 | std::vector number; 42 | static const std::string alphabet; 43 | 44 | void addUintWithCarry(uint64_t& operand1res, const uint64_t operand2, bool& carry) const; 45 | void mult(uint64_t& operand1High, uint64_t& operand2Low) const; 46 | Bint& bitOperation(const Bint& a, std::function&& lambda); 47 | Bint& bitOperation(const int64_t a, std::function&& lambda); 48 | void eraseLeadingSign(); 49 | void extendNumberBySizeOf(Bint& extNumber, const Bint&a); 50 | uint64_t div(const uint64_t& dividend, const uint64_t& divisor, uint64_t& prevRmd) const; 51 | void div(Bint& rmdDividend, Bint& resQuot, const Bint& divisor) const; 52 | void setDecimal(const std::string& s); 53 | void setNumber(const std::string& num, int base); 54 | bool isNegative() const; 55 | std::string base2(const uint64_t base) const; 56 | Bint& urshift(const uint64_t shift); 57 | void addUintAt(uint64_t index, uint64_t operand); 58 | 59 | public: 60 | // Constructors 61 | Bint(); 62 | Bint(int64_t num); 63 | Bint(const char* decimal); 64 | Bint(const std::string& decimal); 65 | 66 | // String representation 67 | std::string bin() const; 68 | std::string hex() const; 69 | std::string oct() const; 70 | std::string toString() const; 71 | std::string base(const uint64_t base) const; 72 | operator std::string() const; 73 | 74 | // Bits 75 | Bint operator & (const Bint& a) const; 76 | Bint& operator &= (const Bint& a); 77 | Bint operator | (const Bint& a) const; 78 | Bint& operator |= (const Bint& a); 79 | Bint operator ^ (const Bint& a) const; 80 | Bint& operator ^= (const Bint& a); 81 | 82 | Bint operator & (const int64_t a) const; 83 | Bint& operator &= (const int64_t a); 84 | Bint operator | (const int64_t a) const; 85 | Bint& operator |= (const int64_t a); 86 | Bint operator ^ (const int64_t a) const; 87 | Bint& operator ^= (const int64_t a); 88 | 89 | Bint operator ~ () const; // prefix 90 | 91 | // Arithmetics 92 | Bint operator ++ (int); // postfix 93 | Bint& operator ++ (); // prefix 94 | Bint operator -- (int); // postfix 95 | Bint& operator -- (); // prefix 96 | Bint operator - () const; // prefix 97 | 98 | Bint operator + (const Bint& a) const; 99 | Bint& operator += (const Bint& a); 100 | Bint operator - (const Bint& a) const; 101 | Bint& operator -= (const Bint& a); 102 | Bint operator * (const Bint& a) const; 103 | Bint& operator *= (const Bint& a); 104 | Bint operator / (const Bint& a) const; 105 | Bint& operator /= (const Bint& a); 106 | Bint operator % (const Bint& a) const; 107 | Bint& operator %= (const Bint& a); 108 | 109 | Bint operator + (const int64_t a) const; 110 | Bint& operator += (const int64_t a); 111 | Bint operator - (const int64_t a) const; 112 | Bint& operator -= (const int64_t a); 113 | Bint operator * (const int64_t a) const; 114 | Bint& operator *= (const int64_t a); 115 | Bint operator / (const int64_t a) const; 116 | Bint& operator /= (const int64_t a); 117 | Bint operator % (const int64_t a) const; 118 | Bint& operator %= (const int64_t a); 119 | 120 | // Shifts 121 | Bint operator << (const uint64_t shift) const; 122 | Bint& operator <<= (const uint64_t shift); 123 | Bint operator >> (const uint64_t shift) const; 124 | Bint& operator >>= (const uint64_t shift); 125 | 126 | // Comparison 127 | bool operator <= (const Bint &b) const; 128 | bool operator >= (const Bint &b) const; 129 | bool operator == (const Bint &b) const; 130 | bool operator != (const Bint &b) const; 131 | bool operator < (const Bint &b) const; 132 | bool operator > (const Bint &b) const; 133 | 134 | bool operator <= (const int64_t a) const; 135 | bool operator >= (const int64_t a) const; 136 | bool operator == (const int64_t a) const; 137 | bool operator != (const int64_t a) const; 138 | bool operator < (const int64_t a) const; 139 | bool operator > (const int64_t a) const; 140 | }; 141 | 142 | // Input-output 143 | std::ostream& operator << (std::ostream& strm, const Bint& a); 144 | std::istream& operator >> (std::istream& strm, Bint& a); 145 | 146 | // Left side operators for int 147 | // Arithmetics 148 | Bint operator + (const int64_t a, const Bint& b); 149 | Bint operator - (const int64_t a, const Bint& b); 150 | Bint operator * (const int64_t a, const Bint& b); 151 | Bint operator / (const int64_t a, const Bint& b); 152 | Bint operator % (const int64_t a, const Bint& b); 153 | // Comparison 154 | bool operator <= (const int64_t a, const Bint &b); 155 | bool operator >= (const int64_t a, const Bint &b); 156 | bool operator == (const int64_t a, const Bint &b); 157 | bool operator != (const int64_t a, const Bint &b); 158 | bool operator < (const int64_t a, const Bint &b); 159 | bool operator > (const int64_t a, const Bint &b); 160 | // Bits 161 | Bint operator & (const int64_t a, const Bint &b); 162 | Bint operator | (const int64_t a, const Bint &b); 163 | Bint operator ^ (const int64_t a, const Bint &b); 164 | 165 | 166 | } // namespace 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BeeNum 2 | 3 | [![github-actions][github-shield]][github-link] 4 | 5 | BeeNum is an arbitrary-precision arithmetic library. 6 | 7 | Integers: 8 | 9 | ```cpp 10 | Bint a = "372542872459"; 11 | Bint b = "-29351077"; 12 | Bint c = "-SomeNumbersAreHere::62"; // base 62 13 | Bint d = "-9:10:79:100:16:3:35:72:76:15:11::101"; // base 101 14 | 15 | a *= b; 16 | 17 | std::cout << "a = " << a << std::endl; 18 | std::cout << "a bin = " << a.bin() << std::endl; 19 | std::cout << "a hex = " << a.hex() << std::endl; 20 | std::cout << "a oct = " << a.oct() << std::endl; 21 | std::cout << "a b12 = " << a.base(12) << std::endl; 22 | std::cout << "a b16 = " << a.base(16) << std::endl; 23 | std::cout << "a b62 = " << a.base(62) << std::endl; 24 | std::cout << "a b100 = " << a.base(100) << std::endl; 25 | std::cout << "a b101 = " << a.base(101) << std::endl; 26 | std::cout << "-a hex= " << (-a).hex() << std::endl; 27 | 28 | a = Math::fib(2344); // fibonnaci 29 | std::cout << "a = " << a << std::endl; 30 | a = Math::fact(2344); // factorial 31 | std::cout << "a = " << a << std::endl; 32 | ``` 33 | 34 | Output: 35 | ``` 36 | a = -10934534535345288343 37 | a bin = 0b11111111111111111111111111111111111111111111111111111111111111110110100001000000101110101100011000010100100000001100101101101001 38 | a hex = 0xffffffffffffffff6840bac61480cb69 39 | a oct = 03777777777777777777776641005654302440145551 40 | a b12 = -4b1864994618b07247::12 41 | a b16 = -97bf4539eb7f3497::16 42 | a b62 = -d1KhCnN5DsH::62 43 | a b100 = -10:93:45:34:53:53:45:28:83:43::100 44 | a b101 = -9:100:79:38:16:3:35:72:76:15::101 45 | -a hex= 0x000000000000000097bf4539eb7f3497 46 | a = 3292636163395024367203468473569524756643504121012844896096537327933868120094412497040602775152572215865563160589549803525642230638215962365456769283299059545111493596481118009871253620689741369268903929271547189925964105732185114343148279766732776564135330585999837804716970141613627707728875235226521977279570816674613873171176272739184670585253011586091130410738892672880825317801152473484664507980075569727857490445475808429292084727199544336720900623844157649066893717994088750765435083 47 | a = 18986731798629253220671300885142313336688051876196376804540809802650384949875016046615025899503961641732182336769103319236840437449601140671345984851122721760131425534692229714763062905706733176858764135567064645253395447124350553194118836976515601454707475528418211056034505325558468514159427351101210191037468366245147748594544386889782543056511487999423544977122220805265509368951204457302756776184253126536690153653560525087929088238381804507254728800284235626611808430966867812714467440288124340104117163434977554850405794886100682302288719156275876275718371597637020180068184872749169441320994584204543773758506427693721479790800353586089617913383642335280314764406644108579303724751553233935673801543700550057589203642191894024441356820608970357620806648980451443210104281574896831860393625299107261500826172297883189703447349325084648382181401548201515803154905132260754707273822348477759858681931356514452652308138353931293765302587300137853372212059322653471731019805728188271770665929592706918489675023678472402481200169648713630855769721907614959515245031508071721734364908914158156765292622987366523323825306330006388632879942791108532222293747076165916385308540348065162099420676827494513945931036618827913395343181877720089116742614812573793441052904664214203421586759617621045410073999823507579665443942630881672450889794320463076008268044935918323157982323419097228830010253358567770813771632941826618084290764056570319108427902698367479270212888808442153805337077616641891588881995223117780326278915631362143204568789060785049480302006513861524845865088567485529441181010835855979328158749166377381431970695779575358333029908777416422251888072656444310371548375646187903056536200775538667593845640688159776624307179042155770501955596507112208925877418647661698909089334513601260764744079642668918814133981159210013185007430448829612312590750966052218329613009885758487725012645183399374446966400343710500229743517994579512211778305821315452037663448384359008712746554743563695597899962398792198953207386563015713325853243368905934724894037960940203172745457473361221952022780818119733939386730022286037753659179995599044998299225384675544288247773022441761574512805080011426952888524431496801701343791715866682983213421176407470580958153944894180372833898396951358591123637162223275455018230132572369087231185427157437735113245037721132363363089820207760870493064985233254236978437834883425069210661667842530222643416477193000685852204548497327600396736361471995966156388125617461662973714871175165393803037986068831895152702187291043143587354876070398215076956346546896870756726174343734967388568991503280563232502639127051069490770269775485598919487019822923070203239399599113857677814872931597959356897737116181935057355145856679107041868462403503056312048753370610618818479313717984973731187149395837803235622283351016727908384161231986685723451668915759269631965011148211781992729321011891994427417806321293428256761047272995307509396567383043817980953183716007888971731311055776572987330685771351381621753829368484649954731777285849850227974618409751398604232248583442941535515169271016821507528312535692304613067872048115577282775226049960431806664829243853690181474548772162891717351444657278575921596333661131649399790050435650930799521456256533398680540530387079828934996959383096402932596561382460657697600504830550396946792160710884086957868097199833400518561815696723401787241109245791997501020486315207488798370181773331571637855818818392178904936144338020981349706959770552392103705300176739575287920891298039747361395434819278019236107227722831211006920481041916074835301721327955081851450334634328977309235312358912146091192117139933462833966638675095982453151036275426337143448474443512834273818436156178140720856450886486201695969071980754475666969143707675261793429105094105021435989964701996111617305161623537608389993066191482747214723924559064471191337079455023930267826784331775024635894903570649051429331250896504549265516421641546270315375284888185589436028704563950029840541115513353331555002418537800186372685656829267765364153612999333131781815498749534656426378436263536479397639930741990815861876033747239238520703280868684915525975492553554476848292646371118646096175276178571398658703852116237716162230718602325016792105123734576543387659370675079823329947176207503269312966721041104200890431451709685865411433290248443977831955806443786004586882170906819390531266590433033160649838162339220211433315462183511171802272865747569241746467509706961938267318421056255772004580063086623783804291288101078815931516136062215315011494108563515891177534955673425966444579329085806278042141202822918075590913677956615462546351505567372785876175190154408568738375966719975425928213252148265376654742080938474985605022522680070423638096126115059709750701161433668387743405972262513648627340520827876331741697501676338464739571415652430554287515985102424229977317892089939697064501164207042372245198839273275852365080938798049588329474047396348021286640487525535835710829960302504501690698457360747113272425617913260655466065868820632760299128672524045569246672596837372820282176555804907559021531314867069848612569843623896030864239871530039442189124840511198416141164018823179586578296067846193677171630606882168555712976966006745518181984561671462854924351736310328848101052875633695942109481414285832632383925818498983238607092334223794394099963340884089525233665632971418510954372377930853842944023749488952610251903043203815650502989059986529769404003730405991894336564742895176736999067802642747345202943584768239298864522853626742781553911719582631288576742515660004555411356243085629794582242993246103944810020372132627666332059477395566696381327419127139774701863345549345480875293533512958489088752720950646419079839808242575748317678381049153260998814285991785527435390648835193869871207192774945047028183521979946299078138528734048519270965094474584980049119031503884376949465263519088394544156521180204709593375392065997839454881390198958699127408741667861098986310619116674538804410255504517779335362842869106587579802474163349358644268640694474122251248280024770779495615147737535251591247605105847143837687925011749775121470676170688365777815820067342397333806988641971860623433269568646544165343060029519196303055694062276092092771104283160477696000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 48 | ``` 49 | 50 | Factorial of 4000 takes: 51 | ``` 52 | Time difference = 90651[µs] (g++ -O0) 53 | Time difference = 15621[µs] (g++ -Ofast) 54 | ``` 55 | 56 | Rationals(fractions): 57 | ```cpp 58 | Brat a(1, "34534534"); 59 | Brat b("-SomeNumbersAreHere::62", "-SomeNumbersAreHere::62"); // base 62 60 | Brat c = "-9:10:79:100:16:3:35:72:76:15:11::101 / 2"; // base 101 61 | 62 | a += b; 63 | a *= c; 64 | 65 | std::cout << "a = " << a << std::endl; 66 | std::cout << "a b62 = " << a.base(62) << std::endl; 67 | std::cout << "a point = " << a.point(50) << std::endl; 68 | std::cout << "a point b62 = " << a.point(50, 62) << std::endl; 69 | ``` 70 | 71 | Output: 72 | ``` 73 | a = -8481309383972525015147919680/1364114093 74 | a b62 = -b1SuMDAel1Q1KSPK::62/1ujGod::62 75 | a point = -6217448692521150439.53872535792356189666607307751053342427421135073633 76 | a point b62 = -7phYORB5xyv.xoRkTP8foonNxN1XMIa36GVhBAE59zioI0aAFYKQVLym6m6QrT::62 77 | ``` 78 | 79 | [github-shield]: https://img.shields.io/github/workflow/status/tigertv/BeeNum/Release.svg?style=for-the-badge&logo=github 80 | [github-link]: https://github.com/tigertv/BeeNum/actions 81 | -------------------------------------------------------------------------------- /src/Bint/arithmetics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * This file is part of the BeeNum (https://github.com/tigertv/BeeNum). 5 | * Copyright (c) 2020 Max Vetrov(tigertv). 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | 28 | 29 | namespace BeeNum { 30 | 31 | Bint Bint::operator + (const Bint& a) const { 32 | Bint b = *this; 33 | b += a; 34 | return b; 35 | } 36 | 37 | Bint Bint::operator + (const int64_t a) const { 38 | Bint b = *this; 39 | b += a; 40 | return b; 41 | } 42 | 43 | Bint& Bint::operator += (const Bint& a) { 44 | if (a.number.size() == 1) return (*this) += a.number[0]; 45 | 46 | Bint aa(a); 47 | // no need so many calls to extend 48 | extendNumberBySizeOf(*this, aa); 49 | extendNumberBySizeOf(aa, *this); 50 | 51 | std::vector& bin = aa.number; 52 | 53 | int j = 0; 54 | bool carry = false; 55 | 56 | bool neg = isNegative(); 57 | bool negA = aa.isNegative(); 58 | 59 | for(; j < (int)number.size(); j++) { 60 | addUintWithCarry(number[j], bin[j], carry); 61 | } 62 | 63 | // check signed overflow 64 | if ((neg == negA) && (neg != isNegative())) { 65 | // refactor it 66 | if (neg) { 67 | number.push_back(-1); 68 | } else { 69 | number.push_back(0); 70 | } 71 | } 72 | 73 | // TODO: check need 74 | eraseLeadingSign(); 75 | return *this; 76 | } 77 | 78 | Bint& Bint::operator += (const int64_t a) { 79 | bool neg = isNegative(); 80 | bool negA = (a < 0); 81 | bool carry = false; 82 | addUintWithCarry(number[0], a, carry); 83 | 84 | if (negA) { 85 | for(int j = 1; j < (int)number.size(); j++) { 86 | addUintWithCarry(number[j], -1, carry); 87 | } 88 | } else { 89 | for(int j = 1; carry && j < (int)number.size(); j++) { 90 | addUintWithCarry(number[j], 0, carry); 91 | } 92 | } 93 | 94 | // check signed overflow 95 | if ((neg == negA) && (neg != isNegative())) { 96 | if (neg) { 97 | number.push_back(-1); 98 | } else { 99 | number.push_back(0); 100 | } 101 | } 102 | 103 | // TODO: check need 104 | eraseLeadingSign(); 105 | return *this; 106 | } 107 | 108 | Bint Bint::operator * (const Bint& a) const { 109 | Bint b = *this; 110 | b *= a; 111 | return b; 112 | } 113 | 114 | Bint Bint::operator * (const int64_t a) const { 115 | Bint b = *this; 116 | b *= a; 117 | return b; 118 | } 119 | 120 | Bint& Bint::operator *= (const int64_t a) { 121 | if (a == 1) return *this; 122 | 123 | int64_t aa = a; 124 | bool neg = ((aa < 0) != isNegative()); 125 | 126 | if (isNegative()) { 127 | *this = -(*this); 128 | } 129 | 130 | if (aa < 0) { 131 | aa = -aa; 132 | } 133 | 134 | uint64_t bigCarry = 0; 135 | bool carry = false; 136 | for(int i = 0; i < (int)number.size(); ++i) { 137 | uint64_t opH = aa; 138 | mult(opH, number[i]); 139 | addUintWithCarry(number[i], bigCarry, carry); 140 | bigCarry = opH; 141 | } 142 | 143 | if (bigCarry || carry) { 144 | if (bigCarry != (uint64_t)-1) { 145 | number.push_back(bigCarry + carry); 146 | } else { 147 | number.push_back(0); 148 | number.push_back(1); 149 | } 150 | } 151 | 152 | if (isNegative()) { 153 | number.push_back(0); 154 | } 155 | 156 | eraseLeadingSign(); 157 | 158 | if (neg) { 159 | *this = -(*this); 160 | } 161 | 162 | return *this; 163 | } 164 | 165 | Bint& Bint::operator *= (const Bint& a) { 166 | if (a.number.size() == 1) return (*this) *= a.number[0]; 167 | 168 | Bint aa(a); 169 | 170 | bool neg = (a.isNegative() != isNegative()); 171 | 172 | if (isNegative()) { 173 | *this = -(*this); 174 | } 175 | 176 | if (aa.isNegative()) { 177 | aa = -aa; 178 | } 179 | 180 | std::vector& bin = aa.number; 181 | 182 | Bint c; 183 | uint64_t m = bin.size() * number.size(); 184 | for (uint64_t i = m; i != 0; --i) { 185 | c.number.push_back(0); 186 | } 187 | 188 | for(int j = (int)bin.size() - 1; j >= 0 ; --j) { 189 | for(int i = (int)number.size() - 1; i >= 0 ; --i) { 190 | uint64_t opH = number[i]; 191 | uint64_t opL = bin[j]; 192 | mult(opH, opL); 193 | c.addUintAt(i+j, opL); 194 | c.addUintAt(i+j+1, opH); 195 | } 196 | } 197 | 198 | c.eraseLeadingSign(); 199 | 200 | if (neg) { 201 | c = -c; 202 | } 203 | 204 | this->number = c.number; 205 | return (*this); 206 | } 207 | 208 | void Bint::mult(uint64_t& operand1ResHigh, uint64_t& operand2ResLow) const { 209 | uint64_t low1 = 0x00000000ffffffff & operand1ResHigh; 210 | uint64_t high1 = (0xffffffff00000000 & operand1ResHigh) >> 32; 211 | uint64_t low2 = 0x00000000ffffffff & operand2ResLow; 212 | uint64_t high2 = (0xffffffff00000000 & operand2ResLow) >> 32; 213 | 214 | uint64_t ll = low1 * low2; 215 | uint64_t hh = high1 * high2; 216 | 217 | uint64_t lh = low1 * high2; 218 | uint64_t hl = high1 * low2; 219 | 220 | uint64_t lhh = (lh & 0xffffffff00000000) >> 32; 221 | uint64_t lhl = (lh & 0x00000000ffffffff) << 32; 222 | 223 | uint64_t hlh = (hl & 0xffffffff00000000) >> 32; 224 | uint64_t hll = (hl & 0x00000000ffffffff) << 32; 225 | 226 | uint64_t resL = lhl; 227 | uint64_t resH = lhh; 228 | resH += hlh; 229 | bool carry = false; 230 | addUintWithCarry(resL, hll, carry); 231 | if (carry) { 232 | ++resH; 233 | carry = false; 234 | } 235 | addUintWithCarry(resL, ll, carry); 236 | addUintWithCarry(resH, hh, carry); 237 | operand1ResHigh = resH; 238 | operand2ResLow = resL; 239 | } 240 | 241 | Bint& Bint::operator ++ () { // prefix 242 | *this += 1; 243 | return *this; 244 | } 245 | 246 | Bint Bint::operator ++ (int) { // postfix 247 | Bint b = *this; 248 | *this += 1; 249 | return b; 250 | } 251 | 252 | Bint Bint::operator - (const Bint& a) const { 253 | Bint b(*this); 254 | b -= a; 255 | return b; 256 | } 257 | 258 | Bint Bint::operator - (const int64_t a) const { 259 | Bint b(*this); 260 | b -= a; 261 | return b; 262 | } 263 | 264 | Bint& Bint::operator -= (const Bint& a) { 265 | Bint aa(a); 266 | aa = -aa; 267 | *this += aa; 268 | return *this; 269 | } 270 | 271 | Bint& Bint::operator -= (const int64_t a) { 272 | *this += -a; 273 | return *this; 274 | } 275 | 276 | Bint& Bint::operator -- () { // prefix 277 | *this -= 1; 278 | return *this; 279 | } 280 | 281 | Bint Bint::operator -- (int) { // postfix 282 | Bint b = *this; 283 | *this -= 1; 284 | return b; 285 | } 286 | 287 | Bint Bint::operator / (const Bint& a) const { 288 | Bint b(*this); 289 | b /= a; 290 | return b; 291 | } 292 | 293 | Bint Bint::operator / (const int64_t a) const { 294 | Bint b(*this); 295 | b /= a; 296 | return b; 297 | } 298 | 299 | Bint& Bint::operator /= (const Bint& a) { 300 | Bint c(*this); 301 | Bint res; 302 | 303 | div(c, res, a); 304 | 305 | this->number = res.number; 306 | return (*this); 307 | } 308 | 309 | Bint& Bint::operator /= (const int64_t a) { 310 | Bint c(*this); 311 | Bint res; 312 | 313 | div(c, res, a); 314 | 315 | this->number = res.number; 316 | return (*this); 317 | } 318 | 319 | Bint Bint::operator % (const Bint& a) const { 320 | Bint b(*this); 321 | b %= a; 322 | return b; 323 | } 324 | 325 | Bint Bint::operator % (const int64_t a) const { 326 | Bint b(*this); 327 | b %= a; 328 | return b; 329 | } 330 | 331 | Bint& Bint::operator %= (const Bint& a) { 332 | Bint c(*this); 333 | Bint res; 334 | 335 | div(c, res, a); 336 | 337 | this->number = c.number; 338 | return (*this); 339 | } 340 | 341 | Bint& Bint::operator %= (const int64_t a) { 342 | Bint c(*this); 343 | Bint res; 344 | 345 | div(c, res, a); 346 | 347 | this->number = c.number; 348 | return (*this); 349 | } 350 | 351 | //////////////////////////////////////////////////////////////////////// 352 | 353 | void Bint::addUintWithCarry(uint64_t& operand1res, const uint64_t operand2, bool& carry) const { 354 | uint64_t bigCarry = (operand1res & 1) + (operand2 & 1) + carry; 355 | uint64_t result = (operand1res >> 1) + (operand2 >> 1) + (bigCarry >> 1); 356 | carry = (bool)(result & 0x8000000000000000); 357 | result <<= 1; 358 | result |= (bigCarry & 1); 359 | operand1res = result; 360 | } 361 | 362 | // it doesn't check bounds 363 | void Bint::addUintAt(uint64_t index, uint64_t operand) { 364 | bool carry = false; 365 | addUintWithCarry(number[index], operand, carry); 366 | while(carry) { 367 | ++index; 368 | if (number[index] != (uint64_t)-1) { 369 | ++number[index]; 370 | break; 371 | } 372 | number[index] = 0; 373 | } 374 | } 375 | 376 | uint64_t Bint::div(const uint64_t& dividend, const uint64_t& divisor, uint64_t& prevRmd) const { 377 | if (divisor == 0) { 378 | throw std::invalid_argument("Division by zero!"); 379 | } 380 | 381 | uint64_t quot = 0; 382 | uint64_t rmd = 0; 383 | 384 | // count prevRmd 385 | if (prevRmd) { 386 | quot = (uint64_t)-1 / divisor; 387 | rmd = (uint64_t)-1 % divisor + 1; 388 | if (rmd == divisor) { 389 | ++quot; 390 | rmd = 0; 391 | } 392 | 393 | quot *= prevRmd; 394 | rmd *= prevRmd; 395 | } 396 | 397 | // division of dividend and divisor 398 | quot += dividend / divisor; 399 | rmd += dividend % divisor; 400 | 401 | quot += rmd / divisor; 402 | rmd %= divisor; 403 | 404 | prevRmd = rmd; 405 | return quot; 406 | } 407 | 408 | void Bint::div(Bint& rmdDividend, Bint& resQuot, const Bint& divisor) const { 409 | if (divisor == 0) { 410 | throw std::invalid_argument("Division by zero!"); 411 | } 412 | 413 | Bint& a = rmdDividend; 414 | Bint d = divisor; 415 | Bint& c = resQuot; 416 | 417 | bool neg = (a.isNegative() != d.isNegative()); 418 | 419 | if (a.isNegative()) { 420 | a = -a; 421 | } 422 | 423 | if (d.isNegative()) { 424 | d = -d; 425 | } 426 | 427 | if (a < d) { 428 | // c = 0; 429 | if (neg) { 430 | a = -a; 431 | } 432 | return; 433 | } 434 | 435 | Bint dvsr = d; 436 | 437 | std::vector& dnum = d.number; 438 | 439 | // add zeros at the end 440 | size_t diff = a.number.size() - dnum.size(); 441 | for(size_t i = diff; i != 0; --i) { 442 | dnum.insert(dnum.begin(), 0); 443 | } 444 | 445 | // find where to subtruct 446 | while(a >= d) { 447 | d <<= 1; 448 | } 449 | 450 | while(d > a) { 451 | d >>= 1; 452 | } 453 | 454 | // do subtruction 455 | while(d >= dvsr) { 456 | c <<= 1; 457 | if (d <= a) { 458 | c.number[0] |= 1; 459 | a -= d; 460 | } 461 | d >>= 1; 462 | } 463 | 464 | if (neg) { 465 | c = -c; 466 | a = -a; 467 | } 468 | 469 | } 470 | 471 | Bint Bint::operator - () const { // prefix 472 | Bint r(*this); 473 | r = ~r + 1; 474 | return r; 475 | } 476 | 477 | /////////////////////////////////////////////////////////////// 478 | // Left side operators for int 479 | /////////////////////////////////////////////////////////////// 480 | 481 | Bint operator + (const int64_t a, const Bint& b) { 482 | return b + a; 483 | } 484 | 485 | Bint operator - (const int64_t a, const Bint& b) { 486 | return -(b - a); 487 | } 488 | 489 | Bint operator * (const int64_t a, const Bint& b) { 490 | return b * a; 491 | } 492 | 493 | Bint operator / (const int64_t a, const Bint& b) { 494 | Bint aa(a); 495 | return aa / b; 496 | } 497 | 498 | Bint operator % (const int64_t a, const Bint& b) { 499 | Bint aa(a); 500 | return aa % b; 501 | } 502 | 503 | } // namespace 504 | -------------------------------------------------------------------------------- /tests/factorial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace BeeNum; 10 | 11 | 12 | int main() { 13 | Bint a; 14 | 15 | std::string s = "18288019515140650133147431755739190442173777107304392197064526954208959797973177364850370286870484107336443041569285571754672461861543557333942615617956996716745284831597317498818760937482804980419576512948720610558928129788097800620593429537705326740624453884285091743951756746144447362378722469436194575929579900114212973360658998073977714697261205048663725936337490404066097966637170254021348800944280342285355946649681316260163459743803577175903394733170076841764779082166891184529324230033414145497801832598218518406552257097392530024582738982919104406782168708871495603501905867399966298798534877747923179195791416504408054878974770308650707120878837624986576073340449414854578367383301715706358194127400849855604080473305196833482408079420964275187538889115296655522397723924887154624810659788321005620558369604778657904771918388054319251513981954296741688447246185021250402225010116433016818588036690180177691461779713104301640395708274734701186772756966064611023656528765138735704190876200697145804692125236821066805337175220605745377557452592208653939853278523841448314026548802309860391087939783218946129582647928430739985554883806198749831633640196211202756086016039171607744078776876219661603702759454887945247605749205543464095883664514960293873244842409803801480566600124415293789831496309554117113888561569494314926134470477513516416560102984058751906208865570183683850791317395702861350821464653600469443279077733978568711404244774089509216727922510660941411716412467443445414001188915966547283773988670739792818897314762082568914041952211779194055311405259158538932388745292324386826830135904886472292289993848482289254307628467614523292519222687689180219788377184005246290896703260524910362136627321135976515358528150143796798116836263053229733971612275184896139539613129329008449214723196703789119820971205922195513915546814704778682373487718946560822811623038853887054357316290622378472322045316639418491798517077275839637525427601452961835674484434498885698840692468550825765131610925966585339561854456154229048295742274725126218799745448031391826295221114381890600683208441558088271228618006589059444108806652992787854634497487158675770983422610936590600627170500972481399444145398522756870626097250230229195799277299921844954715690883242553569256657132515663544931830393317518828986443942138971609142621397646808351809694603734872977984148002699965137870448199866167162949256435040416146886823942144459105175033488395869910405207521329016842673168563837531518918339627724066152933627236730561155418227888673513937454508103826102827706121560330906016404162420051373313654570111102003319577878502216919170112074608722852376799943191590480651623958062982829452035227119036502426583752512199824089725611711059153935434418985109241404135069047109527514730648502064630431371185922523036941621026392783813435540195800531988645430344745298845640017082732623248838473771603478336326662579219137601422632057648758807935233915527562817942378675243919886800056209434731407685691942327092464101136254795499159351103542747723434544436366313104996373661654989465498180892716462805042227038222104784062626027480151567377841821316292095295686368619300417863327530764301323081902435971165925163513225511176258919471673437553320934916910573999020966087207663133871516530391787535755420348174519954013015999193335205032571176460105005716115305748669364682675265014310223271762807620242805617435594927890676408953057384890719681225840400396698155624793888816156585043604782961704971397764959404751358445856914581957186533573207690355894150776647727994156425641953755517727965486096675384222232344185537279888780570854092084221993660761154788359777439798490851148031275123759286793224660188593768897291749180357297185650430735063126035278321749629995702200115722386600046772883018963166273463715186812543356173550341233310175600817771447170656517505385258772069067139665478506263898380526394388218036388768999161538645432932116471146392562992204259450889291928261780531925618148311151259088519869787637913607866079920830781433275298468534248595471485354420794089854693167644320115900404444471266030942746376074187982809857292874382829734306879420308783010740784767155894363033186129183748698373599293267795620690003900348542140553208244771165593739117369452474295075445169488356550100854423929030967163401348223503674045821834526710830392520955478859202303175309815706259592416130388770535449570146586161954289529234209342432075461261173246383180702862172009624828852517861214008242944903162464816939278645210656431141653019224783906038062818006434258491952705341708781231767324026544165240012431457995565227331912056216396141277926932316783631899833106810492890045890947294731794016389385348294079360921757589715698098491612254898203787546124091057862387229987442131738499764391062422228395736099751277880661280909246369674792326056952220508861243875642482808175793303703933394191224832165950388337931626643339913192088808753619030386928808349931733881036690498513779587801764477865791351420222949860738228995728065763459283625096944678593378349990211317403358327367677358882377095918185840441346045760435580063918587956888086127034558064154832456098224664532422114583653763989534559801683261113731162039500068729224661509382267286483841867542303955164213391663536072749966590737898408144092699675796793165775891429992491955485860639629542416955757565163223827874193321274119938618709482020627749094917473754346320653165690129809741806883246764053966717253521140010801409998318494470531219051920354752556183478378238398583402765337923843167749738355049636714529840534145950376598809459294819192486096200503652538835417613002983933634477053826438814791235363934440952835213240806543802505241445900981152753843778634021300832293332432473400040109754281828950625464331409151961292319287863535740382445771128522343533054993071872524564127962306298218521662304206610010638488461150361786151832595182055013210238035059473479841417644445066550217093994746959565730463201996845756999575031950401331385688683576883429289274419202816101239071817771853612534620088858074904095239406471009098851796038360101243053736361346640211872570375441319261567131238168652234864182359667285536913841122976956009892970909409178865928472056691904571596961458646895132972589012090613887584436018692038947475932753085268106507554394567201654757930957224629573401948677157237825005540282635839895509019254240256916422227590032685003087320017232658420681209681389364174854034319152111706246564733896551636271748411627920466475472421243033805492052542237647091252577811952376244836844025673570936216945539206875730684120187779664758451508678786539887154966732995692212544207529457534936853900663520665102592278581210192104846016594846265525000394264201946315492667174670489454576610993722063668720936949698308641684437046485292906040368218708947194882991333823400676584552108673913669306118549159369734833071319506680872661886898225398171896329288732499509337836463164384614967690283284184136334006184670970038275153458133098776493171693249836721707632973537518273692928527497068121779606865163943692606596848941143683627629169873171114739189794632775706536177409526869936538136348369630762610163490694986911903178859927739423796596582439105912599204583810744740479342404550513976713360591833475711496976836332005885151231030818986389033126325119226309584818058301429763149472903925739659774337307109687940297813700796873400566095281249251559137923743113469044584820584542770746490047535898370961450995287930441328833542933636539386097851378739174078158132593877463567524868470795313740375647059352650583871001646082364842709333314532933141725314262510333047099681128329792983694287727106008519184538377065089964546579000542260452715147077137452076302879112802094308224402060706282308208678850263037733351444756065285721900833083634023860920356321356382318484421995141074387149942542550133039926139155010190614633196727199469768170121209097613598302048321148497175007150184555423280152476407230065108963493864309805262458731715886593175689747530567359088332598961192319881186961400055356294945140450806114214490420494488195417136403967132286869444062615622815233336396279517485469862880809956041938378161336156979526713793454354319018535526139196959277008828634440008764782171726908279132449346924807112458895951881542382952497102061566169481361027449429416228859029591798532192088531772405831332410104172391828682208239266557146168642210154401086974397003647170356217905465594944933170065175291981240572835024374361017977695084363373226470846255498368067535698751768103817520605779489720985090002595078926475029239124403277040719184010486962844211160986922952144938430963756963408787147933184107904312838985994963982784496688190643908936394858404598837762653245968848299901455260080572627872653099337092686312650606546084656202210845053932679131706841390889951865628810708670194485207654079244417321332232196041180225814997707988397637369268804955010409293139079608620689856756139863786355461818276369292665568749282154818479663283704713663666842236273009790537968973379093662517795316051746410279831975339791651704861188979834156418998505732384020730350075052669695594594753081616632885311572351609352631187129393729557398993321794518158269658073683417584260274184235030846683698193879109933863561435059993549597333514217973995915742796206889856584584493875193805504685107321011420502217815128118404137521250590361329385146997427292035829509205811367395885622247504950811752188165627552137681095618860955664505372763469788466067973748736658759105548049054658237200096293754479296344115915560231138432518248450383276234795400180535655551222536669390799317067896797756236783441752907948891802488298281245615590113512482344591092230909649423933991714557108941323849548468680509335203770970493785006636718394242326057416155509029270066096293813080877339787718442773014833232754755736783313789547145535129557193581885962158684756484475219230828423777756012721234731368785218564362953263092286535139160440838713013861328416662947756104857391740722209360021068158824717926850831589591367302143596625426553706038593255843919505223140871543995210720444637571268651195165483531243799087083070940544241515809139594158704843980567202482856647644447362604252961907705738740354460336586792214638225365973993001974668174157206242597452556046629209551599663117912609702944345176608757619561247872050409609062772362769045711709729061066411540898769707847042980034982033351136308779676287974627667703893888026848748953201438481632037717854462054861859986684636917120883602793194058658599425778515519713798214407689849211487929150179918547200558584524139792439377469676039518101451697712860634235352474290575260172151562129240720796835619967878383018961055921622371480562682714603085506932806187937976625431071742833007749235636990700120567425836156233607547500827789537909071263596294926763891075439575973972560478399510790078797663071024149826759934524980569432847819403219226207098701759952415628476519584752248050578584198211799092030838909208236225141975964892778944163008811179723219354847713753084628828883321692575327835658786892010648865205021985527642612795652759365359359048052205587306960853879351302215329380382709288672566169552660197788055450054177652374955319992805345989662399494012874012278677451052584166987084866267245492968785684175508510910492913793478551456991152291522750377308973310200505007906906671435839262115546753934391579860133029544403932422271218975046896384482252108820546415274174791693426071019927278518520520164621127271231748277979659289204850823018535192067323372368224831050642902153626845618478009622824733150764188329304815843651352730897836727021023023627320228373645802602496000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; //4000! 16 | 17 | uint64_t d = 4000; 18 | std::cout << "factorial:" << std::endl; 19 | std::cout << "a = " << d << std::endl; 20 | std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); 21 | a = Math::fact(d); 22 | std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); 23 | std::cout << "a = " << a << std::endl; 24 | 25 | assert(a.toString() == s); 26 | 27 | std::cout << "Time difference = " << std::chrono::duration_cast(end - begin).count() << "[µs]" << std::endl; 28 | std::cout << "Time difference = " << std::chrono::duration_cast (end - begin).count() << "[ns]" << std::endl; 29 | std::cout << std::endl; 30 | 31 | a = Math::fact(22); 32 | std::cout << "a = fact(22) " << std::endl; 33 | std::cout << "a = " << a << std::endl; 34 | assert(a.toString() == "1124000727777607680000"); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /tests/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace BeeNum; 10 | 11 | 12 | int main() { 13 | Bint a; 14 | Bint b; 15 | std::string s = "18288019515140650133147431755739190442173777107304392197064526954208959797973177364850370286870484107336443041569285571754672461861543557333942615617956996716745284831597317498818760937482804980419576512948720610558928129788097800620593429537705326740624453884285091743951756746144447362378722469436194575929579900114212973360658998073977714697261205048663725936337490404066097966637170254021348800944280342285355946649681316260163459743803577175903394733170076841764779082166891184529324230033414145497801832598218518406552257097392530024582738982919104406782168708871495603501905867399966298798534877747923179195791416504408054878974770308650707120878837624986576073340449414854578367383301715706358194127400849855604080473305196833482408079420964275187538889115296655522397723924887154624810659788321005620558369604778657904771918388054319251513981954296741688447246185021250402225010116433016818588036690180177691461779713104301640395708274734701186772756966064611023656528765138735704190876200697145804692125236821066805337175220605745377557452592208653939853278523841448314026548802309860391087939783218946129582647928430739985554883806198749831633640196211202756086016039171607744078776876219661603702759454887945247605749205543464095883664514960293873244842409803801480566600124415293789831496309554117113888561569494314926134470477513516416560102984058751906208865570183683850791317395702861350821464653600469443279077733978568711404244774089509216727922510660941411716412467443445414001188915966547283773988670739792818897314762082568914041952211779194055311405259158538932388745292324386826830135904886472292289993848482289254307628467614523292519222687689180219788377184005246290896703260524910362136627321135976515358528150143796798116836263053229733971612275184896139539613129329008449214723196703789119820971205922195513915546814704778682373487718946560822811623038853887054357316290622378472322045316639418491798517077275839637525427601452961835674484434498885698840692468550825765131610925966585339561854456154229048295742274725126218799745448031391826295221114381890600683208441558088271228618006589059444108806652992787854634497487158675770983422610936590600627170500972481399444145398522756870626097250230229195799277299921844954715690883242553569256657132515663544931830393317518828986443942138971609142621397646808351809694603734872977984148002699965137870448199866167162949256435040416146886823942144459105175033488395869910405207521329016842673168563837531518918339627724066152933627236730561155418227888673513937454508103826102827706121560330906016404162420051373313654570111102003319577878502216919170112074608722852376799943191590480651623958062982829452035227119036502426583752512199824089725611711059153935434418985109241404135069047109527514730648502064630431371185922523036941621026392783813435540195800531988645430344745298845640017082732623248838473771603478336326662579219137601422632057648758807935233915527562817942378675243919886800056209434731407685691942327092464101136254795499159351103542747723434544436366313104996373661654989465498180892716462805042227038222104784062626027480151567377841821316292095295686368619300417863327530764301323081902435971165925163513225511176258919471673437553320934916910573999020966087207663133871516530391787535755420348174519954013015999193335205032571176460105005716115305748669364682675265014310223271762807620242805617435594927890676408953057384890719681225840400396698155624793888816156585043604782961704971397764959404751358445856914581957186533573207690355894150776647727994156425641953755517727965486096675384222232344185537279888780570854092084221993660761154788359777439798490851148031275123759286793224660188593768897291749180357297185650430735063126035278321749629995702200115722386600046772883018963166273463715186812543356173550341233310175600817771447170656517505385258772069067139665478506263898380526394388218036388768999161538645432932116471146392562992204259450889291928261780531925618148311151259088519869787637913607866079920830781433275298468534248595471485354420794089854693167644320115900404444471266030942746376074187982809857292874382829734306879420308783010740784767155894363033186129183748698373599293267795620690003900348542140553208244771165593739117369452474295075445169488356550100854423929030967163401348223503674045821834526710830392520955478859202303175309815706259592416130388770535449570146586161954289529234209342432075461261173246383180702862172009624828852517861214008242944903162464816939278645210656431141653019224783906038062818006434258491952705341708781231767324026544165240012431457995565227331912056216396141277926932316783631899833106810492890045890947294731794016389385348294079360921757589715698098491612254898203787546124091057862387229987442131738499764391062422228395736099751277880661280909246369674792326056952220508861243875642482808175793303703933394191224832165950388337931626643339913192088808753619030386928808349931733881036690498513779587801764477865791351420222949860738228995728065763459283625096944678593378349990211317403358327367677358882377095918185840441346045760435580063918587956888086127034558064154832456098224664532422114583653763989534559801683261113731162039500068729224661509382267286483841867542303955164213391663536072749966590737898408144092699675796793165775891429992491955485860639629542416955757565163223827874193321274119938618709482020627749094917473754346320653165690129809741806883246764053966717253521140010801409998318494470531219051920354752556183478378238398583402765337923843167749738355049636714529840534145950376598809459294819192486096200503652538835417613002983933634477053826438814791235363934440952835213240806543802505241445900981152753843778634021300832293332432473400040109754281828950625464331409151961292319287863535740382445771128522343533054993071872524564127962306298218521662304206610010638488461150361786151832595182055013210238035059473479841417644445066550217093994746959565730463201996845756999575031950401331385688683576883429289274419202816101239071817771853612534620088858074904095239406471009098851796038360101243053736361346640211872570375441319261567131238168652234864182359667285536913841122976956009892970909409178865928472056691904571596961458646895132972589012090613887584436018692038947475932753085268106507554394567201654757930957224629573401948677157237825005540282635839895509019254240256916422227590032685003087320017232658420681209681389364174854034319152111706246564733896551636271748411627920466475472421243033805492052542237647091252577811952376244836844025673570936216945539206875730684120187779664758451508678786539887154966732995692212544207529457534936853900663520665102592278581210192104846016594846265525000394264201946315492667174670489454576610993722063668720936949698308641684437046485292906040368218708947194882991333823400676584552108673913669306118549159369734833071319506680872661886898225398171896329288732499509337836463164384614967690283284184136334006184670970038275153458133098776493171693249836721707632973537518273692928527497068121779606865163943692606596848941143683627629169873171114739189794632775706536177409526869936538136348369630762610163490694986911903178859927739423796596582439105912599204583810744740479342404550513976713360591833475711496976836332005885151231030818986389033126325119226309584818058301429763149472903925739659774337307109687940297813700796873400566095281249251559137923743113469044584820584542770746490047535898370961450995287930441328833542933636539386097851378739174078158132593877463567524868470795313740375647059352650583871001646082364842709333314532933141725314262510333047099681128329792983694287727106008519184538377065089964546579000542260452715147077137452076302879112802094308224402060706282308208678850263037733351444756065285721900833083634023860920356321356382318484421995141074387149942542550133039926139155010190614633196727199469768170121209097613598302048321148497175007150184555423280152476407230065108963493864309805262458731715886593175689747530567359088332598961192319881186961400055356294945140450806114214490420494488195417136403967132286869444062615622815233336396279517485469862880809956041938378161336156979526713793454354319018535526139196959277008828634440008764782171726908279132449346924807112458895951881542382952497102061566169481361027449429416228859029591798532192088531772405831332410104172391828682208239266557146168642210154401086974397003647170356217905465594944933170065175291981240572835024374361017977695084363373226470846255498368067535698751768103817520605779489720985090002595078926475029239124403277040719184010486962844211160986922952144938430963756963408787147933184107904312838985994963982784496688190643908936394858404598837762653245968848299901455260080572627872653099337092686312650606546084656202210845053932679131706841390889951865628810708670194485207654079244417321332232196041180225814997707988397637369268804955010409293139079608620689856756139863786355461818276369292665568749282154818479663283704713663666842236273009790537968973379093662517795316051746410279831975339791651704861188979834156418998505732384020730350075052669695594594753081616632885311572351609352631187129393729557398993321794518158269658073683417584260274184235030846683698193879109933863561435059993549597333514217973995915742796206889856584584493875193805504685107321011420502217815128118404137521250590361329385146997427292035829509205811367395885622247504950811752188165627552137681095618860955664505372763469788466067973748736658759105548049054658237200096293754479296344115915560231138432518248450383276234795400180535655551222536669390799317067896797756236783441752907948891802488298281245615590113512482344591092230909649423933991714557108941323849548468680509335203770970493785006636718394242326057416155509029270066096293813080877339787718442773014833232754755736783313789547145535129557193581885962158684756484475219230828423777756012721234731368785218564362953263092286535139160440838713013861328416662947756104857391740722209360021068158824717926850831589591367302143596625426553706038593255843919505223140871543995210720444637571268651195165483531243799087083070940544241515809139594158704843980567202482856647644447362604252961907705738740354460336586792214638225365973993001974668174157206242597452556046629209551599663117912609702944345176608757619561247872050409609062772362769045711709729061066411540898769707847042980034982033351136308779676287974627667703893888026848748953201438481632037717854462054861859986684636917120883602793194058658599425778515519713798214407689849211487929150179918547200558584524139792439377469676039518101451697712860634235352474290575260172151562129240720796835619967878383018961055921622371480562682714603085506932806187937976625431071742833007749235636990700120567425836156233607547500827789537909071263596294926763891075439575973972560478399510790078797663071024149826759934524980569432847819403219226207098701759952415628476519584752248050578584198211799092030838909208236225141975964892778944163008811179723219354847713753084628828883321692575327835658786892010648865205021985527642612795652759365359359048052205587306960853879351302215329380382709288672566169552660197788055450054177652374955319992805345989662399494012874012278677451052584166987084866267245492968785684175508510910492913793478551456991152291522750377308973310200505007906906671435839262115546753934391579860133029544403932422271218975046896384482252108820546415274174791693426071019927278518520520164621127271231748277979659289204850823018535192067323372368224831050642902153626845618478009622824733150764188329304815843651352730897836727021023023627320228373645802602496000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; //4000! 16 | 17 | 18 | uint64_t d = 4000; 19 | std::cout << "a = " << d << std::endl; 20 | std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); 21 | a = Math::fact(d); 22 | std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); 23 | 24 | //assert(a.toString()=="6689502913449127057588118054090372586752746333138029810295671352301633557244962989366874165271984981308157637893214090552534408589408121859898481114389650005964960521256960000000000000000000000000000"); // 120! 25 | //assert(a.toString()==s); 26 | 27 | //std::cout << "a = " << a << std::endl; 28 | std::cout << "a b1000 = " << a.base(1000) << std::endl; 29 | //std::cout << "s = " << "6689502913449127057588118054090372586752746333138029810295671352301633557244962989366874165271984981308157637893214090552534408589408121859898481114389650005964960521256960000000000000000000000000000" << std::endl; 30 | /* 31 | std::cout << "a bin = " << a.bin() << std::endl; 32 | std::cout << "a hex = " << a.hex() << std::endl; 33 | std::cout << "a oct = " << a.oct() << std::endl; 34 | std::cout << "a b12 = " << a.base(12) << std::endl; 35 | std::cout << "a b16 = " << a.base(16) << std::endl; 36 | std::cout << "a b62 = " << a.base(62) << std::endl; 37 | std::cout << "a b100 = " << a.base(100) << std::endl; 38 | std::cout << "a b101 = " << a.base(101) << std::endl; 39 | std::cout << "a b1001 = " << a.base(1001) << std::endl; 40 | 41 | //*/ 42 | std::cout << "Time difference = " << std::chrono::duration_cast(end - begin).count() << "[µs]" << std::endl; 43 | std::cout << "Time difference = " << std::chrono::duration_cast (end - begin).count() << "[ns]" << std::endl; 44 | std::cout << std::endl; 45 | 46 | } 47 | --------------------------------------------------------------------------------