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

Function decimal_round

strings/decimal.c:1561–1766  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1559*/
1560
1561int
1562decimal_round(const decimal_t *from, decimal_t *to, int scale,
1563 decimal_round_mode mode)
1564{
1565 int frac0=scale>0 ? ROUND_UP(scale) : (scale + 1)/DIG_PER_DEC1,
1566 frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
1567 intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
1568
1569 dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
1570 int first_dig;
1571
1572 sanity(to);
1573
1574 switch (mode) {
1575 case HALF_UP:
1576 case HALF_EVEN: round_digit=5; break;
1577 case CEILING: round_digit= from->sign ? 10 : 0; break;
1578 case FLOOR: round_digit= from->sign ? 0 : 10; break;
1579 case TRUNCATE: round_digit=10; break;
1580 default: DBUG_ASSERT(0);
1581 }
1582
1583 /*
1584 For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
1585 For internal testing here (ifdef MAIN) we always use len == 100/4
1586 */
1587 DBUG_ASSERT(from->len == to->len);
1588
1589 if (unlikely(frac0+intg0 > len))
1590 {
1591 frac0=len-intg0;
1592 scale=frac0*DIG_PER_DEC1;
1593 error=E_DEC_TRUNCATED;
1594 }
1595
1596 if (scale+from->intg < 0)
1597 {
1598 decimal_make_zero(to);
1599 return E_DEC_OK;
1600 }
1601
1602 if (to != from)
1603 {
1604 dec1 *p0= buf0 + intg0 + MY_MAX(frac1, frac0);
1605 dec1 *p1= buf1 + intg0 + MY_MAX(frac1, frac0);
1606
1607 DBUG_ASSERT(p0 - buf0 <= len);
1608 DBUG_ASSERT(p1 - buf1 <= len);
1609
1610 while (buf0 < p0)
1611 *(--p1) = *(--p0);
1612
1613 buf0=to->buf;
1614 buf1=to->buf;
1615 to->sign=from->sign;
1616 to->intg= MY_MIN(intg0, len) * DIG_PER_DEC1;
1617 }
1618

Callers 6

decimal_shiftFunction · 0.85
my_decimal2binaryFunction · 0.85
my_decimal_roundFunction · 0.85
my_decimal_floorFunction · 0.85
my_decimal_ceilingFunction · 0.85
my_decimal2intFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected