MCPcopy Create free account
hub / github.com/Meituan-Dianping/SQLAdvisor / do_div_mod

Function do_div_mod

strings/decimal.c:2211–2461  ·  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

2209 but then, decimal_mul() should be rewritten too :(
2210*/
2211static 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.

Callers 2

decimal_divFunction · 0.85
decimal_modFunction · 0.85

Calls 1

remove_leading_zeroesFunction · 0.85

Tested by

no test coverage detected