| @@ -9,7 +9,7 @@ · 8 unmodified lines |
| 9 | void | 9 | void |
| 10 | mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder) | 10 | mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder) |
| 11 | { | 11 | { |
| 12 | int j, s, vn, sign; | 12 | int j, s, vn, sign, qsign, rsign; |
| 13 | mpdigit qd, *up, *vp, *qp; | 13 | mpdigit qd, *up, *vp, *qp; |
| 14 | mpint *u, *v, *t; | 14 | mpint *u, *v, *t; |
| 15 | | 15 | |
| @@ -22,7 +22,9 @@ mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder) · 6 unmodified lines |
| 22 | | 22 | |
| 23 | // division by one or small powers of two | 23 | // division by one or small powers of two |
| 24 | if(divisor->top == 1 && (divisor->p[0] & divisor->p[0]-1) == 0){ | 24 | if(divisor->top == 1 && (divisor->p[0] & divisor->p[0]-1) == 0){ |
| 25 | vlong r = (vlong)dividend->sign * (dividend->p[0] & divisor->p[0]-1); | 25 | vlong r = 0; |
| | 26 | if(dividend->top > 0) |
| | 27 | r = (vlong)dividend->sign * (dividend->p[0] & divisor->p[0]-1); |
| 26 | if(quotient != nil){ | 28 | if(quotient != nil){ |
| 27 | sign = divisor->sign; | 29 | sign = divisor->sign; |
| 28 | for(s = 0; ((divisor->p[0] >> s) & 1) == 0; s++) | 30 | for(s = 0; ((divisor->p[0] >> s) & 1) == 0; s++) |
| @@ -47,6 +49,9 @@ mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder) · 18 unmodified lines |
| 47 | mpassign(mpzero, quotient); | 49 | mpassign(mpzero, quotient); |
| 48 | return; | 50 | return; |
| 49 | } | 51 | } |
| | 52 | |
| | 53 | qsign = divisor->sign * dividend->sign; |
| | 54 | rsign = dividend->sign; |
| 50 | | 55 | |
| 51 | // D1: shift until divisor, v, has hi bit set (needed to make trial | 56 | // D1: shift until divisor, v, has hi bit set (needed to make trial |
| 52 | // divisor accurate) | 57 | // divisor accurate) |
| @@ -119,14 +124,15 @@ mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder) · 66 unmodified lines |
| 119 | if(qp != nil){ | 124 | if(qp != nil){ |
| 120 | assert((quotient->flags & MPtimesafe) == 0); | 125 | assert((quotient->flags & MPtimesafe) == 0); |
| 121 | mpnorm(quotient); | 126 | mpnorm(quotient); |
| 122 | if(dividend->sign != divisor->sign) | 127 | if(quotient->top != 0) |
| 123 | quotient->sign = -1; | 128 | quotient->sign = qsign; |
| 124 | } | 129 | } |
| 125 | | 130 | |
| 126 | if(remainder != nil){ | 131 | if(remainder != nil){ |
| 127 | assert((remainder->flags & MPtimesafe) == 0); | 132 | assert((remainder->flags & MPtimesafe) == 0); |
| 128 | mpright(u, s, remainder); // u is the remainder shifted | 133 | mpright(u, s, remainder); // u is the remainder shifted |
| 129 | remainder->sign = dividend->sign; | 134 | if(remainder->top != 0) |
| | 135 | remainder->sign = rsign; |
| 130 | } | 136 | } |
| 131 | | 137 | |
| 132 | mpfree(t); | 138 | mpfree(t); |