naive division algorithm (Knuth's Algorithm D in 4.3.1) - it's ok for short numbers also we're using alloca() to allocate a temporary buffer XXX if this library is to be used with huge numbers of thousands of digits, fast division must be implemented and alloca should be changed to malloc (or at least fallback to malloc if alloca() fails) but then, decimal_mul() should be rewritten to
| 2209 | but then, decimal_mul() should be rewritten too :( |
| 2210 | */ |
| 2211 | static int do_div_mod(const decimal_t *from1, const decimal_t *from2, |
| 2212 | decimal_t *to, decimal_t *mod, int scale_incr) |
| 2213 | { |
| 2214 | int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1, |
| 2215 | frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2, |
| 2216 | UNINIT_VAR(error), i, intg0, frac0, len1, len2, dintg, div_mod=(!mod); |
| 2217 | dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1, |
| 2218 | *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry; |
| 2219 | dec2 norm_factor, x, guess, y; |
| 2220 | |
| 2221 | if (mod) |
| 2222 | to=mod; |
| 2223 | |
| 2224 | sanity(to); |
| 2225 | |
| 2226 | /* removing all the leading zeroes */ |
| 2227 | i= ((prec2 - 1) % DIG_PER_DEC1) + 1; |
| 2228 | while (prec2 > 0 && *buf2 == 0) |
| 2229 | { |
| 2230 | prec2-= i; |
| 2231 | i= DIG_PER_DEC1; |
| 2232 | buf2++; |
| 2233 | } |
| 2234 | if (prec2 <= 0) /* short-circuit everything: from2 == 0 */ |
| 2235 | return E_DEC_DIV_ZERO; |
| 2236 | for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ; |
| 2237 | DBUG_ASSERT(prec2 > 0); |
| 2238 | |
| 2239 | i=((prec1-1) % DIG_PER_DEC1)+1; |
| 2240 | while (prec1 > 0 && *buf1 == 0) |
| 2241 | { |
| 2242 | prec1-=i; |
| 2243 | i=DIG_PER_DEC1; |
| 2244 | buf1++; |
| 2245 | } |
| 2246 | if (prec1 <= 0) |
| 2247 | { /* short-circuit everything: from1 == 0 */ |
| 2248 | decimal_make_zero(to); |
| 2249 | return E_DEC_OK; |
| 2250 | } |
| 2251 | for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ; |
| 2252 | DBUG_ASSERT(prec1 > 0); |
| 2253 | |
| 2254 | /* let's fix scale_incr, taking into account frac1,frac2 increase */ |
| 2255 | if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0) |
| 2256 | scale_incr=0; |
| 2257 | |
| 2258 | dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2); |
| 2259 | if (dintg < 0) |
| 2260 | { |
| 2261 | dintg/=DIG_PER_DEC1; |
| 2262 | intg0=0; |
| 2263 | } |
| 2264 | else |
| 2265 | intg0=ROUND_UP(dintg); |
| 2266 | if (mod) |
| 2267 | { |
| 2268 | /* we're calculating N1 % N2. |
no test coverage detected