From 104a896ad53a55e4d8caf89a163be942bbb76f9e Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Mon, 30 Oct 2023 21:23:55 +0800 Subject: [PATCH] upd: write / --- include/int2048.h | 6 ++ src/int2048.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++-- tester/cases/3.py | 95 ++++++++++++++++++++++++++++++++ tester/config.json | 3 +- 4 files changed, 232 insertions(+), 5 deletions(-) create mode 100755 tester/cases/3.py diff --git a/include/int2048.h b/include/int2048.h index aa30e6d..aca88de 100644 --- a/include/int2048.h +++ b/include/int2048.h @@ -49,6 +49,8 @@ root= 6 __int128_t QuickPow(__int128_t v, long long q); void NTTTransform(__int128_t *, int, bool); + void RightMoveBy(int); + public: int2048(); int2048(long long); @@ -90,6 +92,10 @@ root= 6 int2048 &operator*=(const int2048 &); friend int2048 operator*(int2048, const int2048 &); + inline friend void UnsignedDivide(int2048 &, const int2048 *); + int2048 &Divide(const int2048 &); + friend int2048 Divide(int2048, const int2048 &); + int2048 &operator/=(const int2048 &); friend int2048 operator/(int2048, const int2048 &); diff --git a/src/int2048.cpp b/src/int2048.cpp index 6bd9f77..7f7e0dd 100644 --- a/src/int2048.cpp +++ b/src/int2048.cpp @@ -425,7 +425,10 @@ inline void UnsignedMultiply(int2048 &A, const int2048 *pB) { kPow10[(A.num_length - 1) % int2048::kNum] == 0) { A.num_length--; - if (A.num_length == 0) throw "UnsignedMultiply: num_length==0"; + if (A.num_length == 0) { + A.num_length = 1; + break; + } } delete[] pDA; delete[] pDB; @@ -462,12 +465,134 @@ int2048 operator*(int2048 A, const int2048 &B) { return std::move(A); } -int2048 &int2048::operator/=(const int2048 &) { - // 实现复合除法逻辑 +void int2048::RightMoveBy(int L) { + if (L >= this->num_length) { + this->num_length = 1; + this->val[0] = 0; + return; + } + int big_move = L / int2048::kNum; + int small_move = L % int2048::kNum; + for (int i = 0; i < this->num_length - big_move; i++) { + this->val[i] = this->val[i + big_move]; + } + for (int i = this->num_length - big_move; i < this->num_length; i++) { + this->val[i] = 0; + } + this->num_length -= big_move * int2048::kNum; + if (small_move == 0) return; + const static int kPow10[9] = {1, 10, 100, 1000, 10000, + 100000, 1000000, 10000000, 100000000}; + for (int i = 0; i < this->num_length; i++) { + this->val[i] /= kPow10[small_move]; + if (i + 1 < this->num_length) { + this->val[i] += this->val[i + 1] % kPow10[small_move] * + kPow10[int2048::kNum - small_move]; + } + } + this->num_length -= small_move; } -int2048 operator/(int2048, const int2048 &) { +inline void UnsignedDivide(int2048 &A, const int2048 *pB) { + int L1 = A.num_length, L2 = pB->num_length; + if (2 * L1 - L2 - 1 < 0) { + A = std::move(int2048(0)); + return; + } + if (UnsignedCmp(A, *pB) < 0) { + A = std::move(int2048(0)); + return; + } + int2048 x; + /*init x as 10^(L1-L2)*/ + x.ClaimMem(L1 - L2 + 1); + x.num_length = L1 - L2 + 1; + memset(x.val, 0, x.buf_length * sizeof(int)); + const static int kPow10[9] = {1, 10, 100, 1000, 10000, + 100000, 1000000, 10000000, 100000000}; + x.val[(x.num_length - 1) / int2048::kNum] = + kPow10[(x.num_length - 1) % int2048::kNum]; + /*reset x.num_length*/ + while (x.val[(x.num_length - 1) / int2048::kNum] / + kPow10[(x.num_length - 1) % int2048::kNum] == + 0) { + x.num_length--; + if (x.num_length == 0) throw "UnsignedMultiply: num_length==0"; + } + int2048 x_pre(x); + int2048 kOne(1); + UnsignedMinus(x_pre, &kOne); + while (true) { + /** + * x_{n+1}=2*x_n-x_n*x_n*B/(10^L1)) + */ + int2048 tmp = *pB; + UnsignedMultiply(tmp, &x); + UnsignedMultiply(tmp, &x); + tmp.RightMoveBy(L1); + int2048 x_next = x; + UnsignedAdd(x_next, &x); + UnsignedMinus(x_next, &tmp); + if (UnsignedCmp(x_next, x) == 0) break; + if (UnsignedCmp(x_next, x_pre) == 0) break; + x_pre = std::move(x); + x = std::move(x_next); + } + /*ret=A*x/10^(L1)*/ + UnsignedMultiply(x, &A); + x.RightMoveBy(L1); + /*remain=A -B*ret*/ + int2048 tmp = *pB; + UnsignedMultiply(tmp, &x); + if (UnsignedCmp(A, tmp) < 0) { + x -= 1; + tmp = *pB; + UnsignedMultiply(tmp, &x); + } + UnsignedMinus(A, &tmp); + int2048 remain = std::move(A); + while (UnsignedCmp(remain, *pB) >= 0) { + UnsignedMinus(remain, pB); + UnsignedAdd(x, &kOne); + } + A = std::move(x); +} +int2048 &int2048::Divide(const int2048 &B) { + if (this == &B) { + *this = std::move(int2048(1)); + return *this; + } + if (B.num_length == 1 && B.val[0] == 0) { + *this = std::move(int2048(0)); + return *this; + // throw "Divide: divide by zero"; + } + int2048 origin_A(*this); + int flag_store = this->flag * B.flag; + UnsignedDivide(*this, &B); + this->flag = flag_store; + if (this->flag == -1) { + if (origin_A != (*this) * B) { + *this -= 1; + } + } + if (this->num_length == 1 && this->val[0] == 0) this->flag = 1; + return *this; +} +int2048 Divide(int2048 A, const int2048 &B) { + A.Divide(B); + return std::move(A); +} + +int2048 &int2048::operator/=(const int2048 &B) { + // 实现复合除法逻辑 + return this->Divide(B); +} + +int2048 operator/(int2048 A, const int2048 &B) { // 实现除法逻辑 + A.Divide(B); + return std::move(A); } int2048 &int2048::operator%=(const int2048 &) { diff --git a/tester/cases/3.py b/tester/cases/3.py new file mode 100755 index 0000000..11c7a88 --- /dev/null +++ b/tester/cases/3.py @@ -0,0 +1,95 @@ +#!/usr/bin/python3 +from os import system +from sys import exit +from random import randint +import sys +""" +this script is used to test * operator +""" + +sys.set_int_max_str_digits(10000000) + +code_cpp_pre=""" +#include +#include "/home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/include/int2048.h" +using namespace std; +using namespace sjtu; +int main() +{ +""" +code_cpp_suf=""" +return 0; +} +""" +def_cpp="int2048 a_0(0),a_1(0),a_2(0),a_3(0),a_4(0),a_5(0),a_6(0),a_7(0),a_8(0),a_9(0);" + + +code_python_pre="""#!/usr/bin/python3 +import sys +sys.set_int_max_str_digits(10000000) +""" +def_python="a_0,a_1,a_2,a_3,a_4,a_5,a_6,a_7,a_8,a_9=0,0,0,0,0,0,0,0,0,0" + + +opt_cpp=[] +opt_python=[] + +if True: + for i in range(0,10): + val=randint(-10**2,10**2) + opt_cpp.append("a_"+str(i)+"=int2048(\""+str(val)+"\");") + opt_python.append("a_"+str(i)+"="+str(val)) + opt_cpp.append("a_"+str(i)+".print(); puts(\"\");") + opt_python.append("print(a_"+str(i)+")") + +if True: + for i in range(1): + aid=randint(0,9) + bid=randint(0,9) + cid=randint(0,9) + op='/' + bflag="+" + if randint(0,1)==0: + bflag="-" + cflag="+" + if randint(0,1)==0: + cflag="-" + opt_cpp.append("a_"+str(aid)+"=("+bflag+"a_"+str(bid)+")"+op+"("+cflag+"a_"+str(cid)+");") + opt_python.append("a_"+str(aid)+"=("+bflag+"a_"+str(bid)+")"+op+op+"("+cflag+"a_"+str(cid)+")") + opt_cpp.append("a_"+str(aid)+".print(); puts(\"\");") + opt_python.append("print(a_"+str(aid)+")") + opt_cpp.append("a_"+str(bid)+".print(); puts(\"\");") + opt_python.append("print(a_"+str(bid)+")") + opt_cpp.append("a_"+str(cid)+".print(); puts(\"\");") + opt_python.append("print(a_"+str(cid)+")") + +if False: + for i in range(10): + aid=randint(0,9) + bid=randint(0,9) + op='/=' + opt_cpp.append("a_"+str(aid)+op+"a_"+str(bid)+";") + opt_python.append("a_"+str(aid)+op+"a_"+str(bid)) + opt_cpp.append("a_"+str(aid)+".print(); puts(\"\");") + opt_python.append("print(a_"+str(aid)+")") + +sourc_cpp=open("/tmp/3.cpp","w") +print(code_cpp_pre,file=sourc_cpp) +print(def_cpp,file=sourc_cpp) +for opt in opt_cpp: + print(opt,file=sourc_cpp) +print(code_cpp_suf,file=sourc_cpp) +sourc_cpp.close() +system("g++ /tmp/3.cpp -I /home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/include/ -L /home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/build/src/ -lint2048 -g -o /tmp/3") +system("/tmp/3 > /tmp/3_cpp.out") + +sourc_python=open("/tmp/3.py","w") +print(code_python_pre,file=sourc_python) +print(def_python,file=sourc_python) +for opt in opt_python: + print(opt,file=sourc_python) +sourc_python.close() +system("chmod +x /tmp/3.py") +system("/tmp/3.py > /tmp/3_python.out") + +exit(system("diff -b -B -u /tmp/3_cpp.out /tmp/3_python.out > /tmp/3.diff")//256) \ No newline at end of file diff --git a/tester/config.json b/tester/config.json index e9f683a..1f6e036 100644 --- a/tester/config.json +++ b/tester/config.json @@ -26,6 +26,7 @@ {"command":"timeout -s 9 10s /home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/build/data/C2T17 >/tmp/C2T17.out && diff -b -B -u /tmp/C2T17.out /home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/data/Integer2/17.out >/tmp/diffC2T17","uid":"#27","tid":"/2/17"}, {"command":"timeout -s 9 10s /home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/build/data/C2T18 >/tmp/C2T18.out && diff -b -B -u /tmp/C2T18.out /home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/data/Integer2/18.out >/tmp/diffC2T18","uid":"#28","tid":"/2/18"}, {"command":"/home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/tester/cases/1.py","uid":"#29","tid":"/3/1"}, - {"command":"/home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/tester/cases/2.py","uid":"#30","tid":"/3/2"} + {"command":"/home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/tester/cases/2.py","uid":"#30","tid":"/3/2"}, + {"command":"/home/happyzym/CSWorkSpace/Proc/BigHomework/BH-int2048-2023/tester/cases/3.py","uid":"#31","tid":"/3/3"} ] } \ No newline at end of file