| @@ -9,7 +9,7 @@ · 8 unmodified lines |
| 9 | 9 | void |
| 10 | 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 | 13 | mpdigit qd, *up, *vp, *qp; |
| 14 | 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 | 23 | // division by one or small powers of two |
| 24 | 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 | 28 | if(quotient != nil){ |
| 27 | 29 | sign = divisor->sign; |
| 28 | 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 | 49 | mpassign(mpzero, quotient); |
| 48 | 50 | return; |
| 49 | 51 | } |
| 52 | + |
| 53 | + qsign = divisor->sign * dividend->sign; |
| 54 | + rsign = dividend->sign; |
| 50 | 55 | |
| 51 | 56 | // D1: shift until divisor, v, has hi bit set (needed to make trial |
| 52 | 57 | // divisor accurate) |
| @@ -119,14 +124,15 @@ mpdiv(mpint *dividend, mpint *divisor, mpint *quotient, mpint *remainder) · 66 unmodified lines |
| 119 | 124 | if(qp != nil){ |
| 120 | 125 | assert((quotient->flags & MPtimesafe) == 0); |
| 121 | 126 | mpnorm(quotient); |
| 122 | | − if(dividend->sign != divisor->sign) |
| 123 | | − quotient->sign = -1; |
| 127 | + if(quotient->top != 0) |
| 128 | + quotient->sign = qsign; |
| 124 | 129 | } |
| 125 | 130 | |
| 126 | 131 | if(remainder != nil){ |
| 127 | 132 | assert((remainder->flags & MPtimesafe) == 0); |
| 128 | 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 | 138 | mpfree(t); |