From 27472e604eeb74b3b60313d38d537c7e0e83151b Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 8 Oct 2016 15:07:23 +0200 Subject: Fix sign issues in divmod --- bigint.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++---------- bigint.h | 8 ++++++-- biginttest.py | 13 +++++++------ 3 files changed, 65 insertions(+), 18 deletions(-) diff --git a/bigint.cpp b/bigint.cpp index a9763dd..639d263 100644 --- a/bigint.cpp +++ b/bigint.cpp @@ -321,9 +321,42 @@ pair Bigint::divmod(const Bigint &div) const { // cerr<<"divmod("< p=divmod(div,1,bitcdiff/29+10); //ignores all signs + /* To let the result come out correctly, we apply case analysis to the signs of the arguments. + * As a guiding example, these two cases can be examined. + * The code was tested with many large random numbers (also negative), using a Python script. + * (1) 4 = 1* 3 + 1 6 = 2* 3 + 0 + * (2) 4 = -1*-3 + 1 6 = -2*-3 + 0 + * (3) -4 = -2* 3 + 2 -6 = -2* 3 + 0 + * (4) -4 = 2*-3 + 2 -6 = 2*-3 + 0 + */ + if(sign==1){ + if(div.sign==1){ // (1) + //nothing to do + } else { // (2) + p.first.sign=-1; + } + } else { + if(div.sign==1){ // (3) + p.first.sign=-1; + if(p.second!=0){ + p.first-=1; + p.second=div-p.second; + } + } else { // (4) + if(p.second!=0){ + p.first+=1; + p.second.sign=-1; + p.second-=div; + } + } + } + p.first.normalise(); + p.second.normalise(); + return p; } +//ignores all signs, and always returns positive numbers! pair Bigint::divmod(const Bigint &div,int depth,int maxdepth) const { if(depth>maxdepth)assert(false); // cerr<<"divmod("<=abs(b) or a!=q*b+r: + print("Error: {} divmod {}".format(a,b)) + print("Diff: {}".format(a-q*b-r)) + sys.exit(1) proc.kill() -- cgit v1.2.3-54-g00ecf