int ObNumber::div(const ObNumber &other, ObNumber &res) const { int ret = OB_SUCCESS; res.set_zero(); if (other.is_zero()) { jlog(WARNING, "divisor is zero"); ret = JD_DIVISION_BY_ZERO; } else if (!this->is_zero()) { res.vscale_ = QUOTIENT_SCALE; ObNumber dividend = *this; ObNumber divisor = other; ObNumber remainder; bool res_is_neg = false; if (dividend.is_negative()) { negate(dividend, dividend); res_is_neg = true; } if (dividend.vscale_ > DOUBLE_PRECISION_NDIGITS) { dividend.round_fraction_part(DOUBLE_PRECISION_NDIGITS); } if (divisor.vscale_ > SINGLE_PRECISION_NDIGITS) { divisor.round_fraction_part(SINGLE_PRECISION_NDIGITS); } if (dividend.vscale_ < divisor.vscale_ || res.vscale_ > dividend.vscale_ - divisor.vscale_) { if (OB_SUCCESS != (ret = dividend.left_shift(static_cast<int8_t> (res.vscale_ + divisor.vscale_ - dividend.vscale_), true))) { jlog(WARNING, "left shift overflow, err=%d res_vscale=%hhd other_vscale=%hhd this_vscale=%hhd", ret, res.vscale_, divisor.vscale_, dividend.vscale_); } } if (OB_LIKELY(OB_SUCCESS == ret)) { if (divisor.is_negative()) { negate(divisor, divisor); res_is_neg = !res_is_neg; } divisor.remove_leading_zeroes_unsigned(); div_words(dividend, divisor, res, remainder); if (OB_UNLIKELY(res_is_neg)) { negate(res, res); } res.remove_leading_zeroes(); } } return ret; }