MCPcopy Create free account
hub / github.com/MariaDB/server / do_div_mod

Function do_div_mod

strings/decimal.c:2276–2526  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

2274 but then, decimal_mul() should be rewritten too :(
2275*/
2276static int do_div_mod(const decimal_t *from1, const decimal_t *from2,
2277 decimal_t *to, decimal_t *mod, int scale_incr)
2278{
2279 int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
2280 frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
2281 UNINIT_VAR(error), i, intg0, frac0, len1, len2, dintg, div_mod=(!mod);
2282 dec1 *buf0, *buf1=from1->buf, *buf2=from2->buf, *tmp1,
2283 *start2, *stop2, *stop1, *stop0, norm2, carry, *start1, dcarry;
2284 dec2 norm_factor, x, guess, y;
2285
2286 if (mod)
2287 to=mod;
2288
2289 sanity(to);
2290
2291 /* removing all the leading zeroes */
2292 i= ((prec2 - 1) % DIG_PER_DEC1) + 1;
2293 while (prec2 > 0 && *buf2 == 0)
2294 {
2295 prec2-= i;
2296 i= DIG_PER_DEC1;
2297 buf2++;
2298 }
2299 if (prec2 <= 0) /* short-circuit everything: from2 == 0 */
2300 return E_DEC_DIV_ZERO;
2301 for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ;
2302 DBUG_ASSERT(prec2 > 0);
2303
2304 i=((prec1-1) % DIG_PER_DEC1)+1;
2305 while (prec1 > 0 && *buf1 == 0)
2306 {
2307 prec1-=i;
2308 i=DIG_PER_DEC1;
2309 buf1++;
2310 }
2311 if (prec1 <= 0)
2312 { /* short-circuit everything: from1 == 0 */
2313 decimal_make_zero(to);
2314 return E_DEC_OK;
2315 }
2316 for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ;
2317 DBUG_ASSERT(prec1 > 0);
2318
2319 /* let's fix scale_incr, taking into account frac1,frac2 increase */
2320 if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0)
2321 scale_incr=0;
2322
2323 dintg=(prec1-frac1)-(prec2-frac2)+(*buf1 >= *buf2);
2324 if (dintg < 0)
2325 {
2326 dintg/=DIG_PER_DEC1;
2327 intg0=0;
2328 }
2329 else
2330 intg0=ROUND_UP(dintg);
2331 if (mod)
2332 {
2333 /* we're calculating N1 % N2.

Callers 2

decimal_divFunction · 0.85
decimal_modFunction · 0.85

Calls 1

ROUND_UPFunction · 0.85

Tested by

no test coverage detected