Exemplo n.º 1
0
inline void ObNumber::div_uint32(const ObNumber &dividend, uint32_t divisor, ObNumber &quotient, ObNumber &remainder)
{
    OB_ASSERT(0 < dividend.nwords_);
    OB_ASSERT(MAX_NWORDS >= dividend.nwords_);
    OB_ASSERT(0 < divisor);
    int64_t carry = 0;
    for (int i = dividend.nwords_ - 1; i >= 0; --i)
    {
        carry = carry * BASE + dividend.words_[i];
        quotient.words_[i] = static_cast<uint32_t> (carry / divisor);
        carry = carry % divisor;
    }
    quotient.nwords_ = dividend.nwords_;
    quotient.remove_leading_zeroes();

    if (0 == carry)
    {
        remainder.set_zero(); // remainder is zero
    }
    else
    {
        remainder.words_[0] = static_cast<uint32_t> (carry);
        remainder.nwords_ = 1;
    }
}
Exemplo n.º 2
0
 static int int_decimal(const ObObjCastParams &params, const ObExprObj &in, ObExprObj &out)
 {
     UNUSED(params);
     OB_ASSERT(in.get_type() == ObIntType);
     ObNumber num;
     num.from(in.get_int());
     out.set_decimal(num); // @todo optimize
     return OB_SUCCESS;
 }
Exemplo n.º 3
0
 static int mtime_decimal(const ObObjCastParams &params, const ObExprObj &in, ObExprObj &out)
 {
     UNUSED(params);
     OB_ASSERT(in.get_type() == ObModifyTimeType);
     ObNumber num;
     num.from(static_cast<int64_t> (in.get_mtime()));
     out.set_decimal(num);
     return OB_SUCCESS;
 }
Exemplo n.º 4
0
void ObObj::print_value(FILE* fd)
{
  switch (get_type())
  {
    case ObNullType:
      fprintf(fd, "nil");
      break;
    case ObIntType:
      fprintf(fd, "%ld", value_.int_val);
      break;
    case ObVarcharType:
      fprintf(fd, "%.*s", val_len_, value_.varchar_val);
      break;
    case ObFloatType:
      fprintf(fd, "%2f", value_.float_val);
      break;
    case ObDoubleType:
      fprintf(fd, "%2lf", value_.double_val);
      break;
    case ObDateTimeType:
      fprintf(fd, "%s", time2str(value_.time_val));
      break;
    case ObPreciseDateTimeType:
      fprintf(fd, "%s", time2str(value_.precisetime_val));
      break;
    case ObModifyTimeType:
      fprintf(fd, "%s", time2str(value_.modifytime_val));
      break;
    case ObCreateTimeType:
      fprintf(fd, "%s", time2str(value_.createtime_val));
      break;
    case ObSeqType:
      fprintf(fd, "seq");
      break;
    case ObExtendType:
      fprintf(fd, "%lde", value_.ext_val);
      break;
    case ObBoolType:
      fprintf(fd, "%c", value_.bool_val ? 'Y': 'N');
      break;
    case ObDecimalType:
      {
        char num_buf[ObNumber::MAX_PRINTABLE_SIZE];
        ObNumber num;
        get_decimal(num);
        num.to_string(num_buf, ObNumber::MAX_PRINTABLE_SIZE);
        fprintf(fd, "%s", num_buf);
        break;
      }
    default:
      break;
  }
}
Exemplo n.º 5
0
int ObNumber::cast_to_int64(int64_t &i64) const
{
    int ret = OB_SUCCESS;
    i64 = 0;
    bool is_neg = is_negative();
    ObNumber pos_clone = *this;
    if (is_neg)
    {
        negate(*this, pos_clone);
    }

    ObNumber remainder;
    int vscale = vscale_;
    int digits[DOUBLE_PRECISION_NDIGITS];
    int digit_idx = DOUBLE_PRECISION_NDIGITS - 1;
    while (!pos_clone.is_zero())
    {
        div_uint32(pos_clone, 10, pos_clone, remainder);
        if (vscale > 0)
        {
            vscale--;
        }
        else
        {
            OB_ASSERT(digit_idx >= 0);
            if (remainder.is_zero())
            {
                digits[digit_idx--] = 0;
            }
            else
            {
                OB_ASSERT(1 == remainder.nwords_);
                OB_ASSERT(remainder.words_[0] < 10 && remainder.words_[0] > 0);
                digits[digit_idx--] = remainder.words_[0];
            }
        } // end while
    }
    OB_ASSERT(digit_idx >= -1);
    for (int i = digit_idx + 1; i < DOUBLE_PRECISION_NDIGITS; ++i)
    {
        i64 = i64 * 10 + digits[i];
    }
    if (is_neg)
    {
        i64 = -i64;
    }
    return ret;
}
Exemplo n.º 6
0
int ObObj::set_decimal(const ObNumber &num, int8_t precision, int8_t scale, bool is_add /*= false*/)
{
  int ret = OB_SUCCESS;
  set_flag(is_add);
  meta_.type_ = ObDecimalType;
  meta_.dec_precision_ = static_cast<uint8_t>(precision) & META_PREC_MASK;
  meta_.dec_scale_ = static_cast<uint8_t>(scale) & META_SCALE_MASK;
  int8_t nwords = 0;
  int8_t vscale = 0;
  uint32_t words[ObNumber::MAX_NWORDS];
  ret = num.round_to(precision, scale, nwords, vscale, words);
  if (OB_SUCCESS == ret)
  {
    if (nwords <= 3)
    {
      meta_.dec_nwords_ = static_cast<uint8_t>(nwords - 1) & META_NWORDS_MASK;
      meta_.dec_vscale_ = static_cast<uint8_t>(vscale) & META_VSCALE_MASK;
      memcpy(reinterpret_cast<uint32_t*>(&val_len_), words, sizeof(uint32_t)*nwords);
    }
    else
    {
      //@todo, use ob_pool.h to allocate memory
      ret = OB_NOT_IMPLEMENT;
    }
  }
  return ret;
}
Exemplo n.º 7
0
int ObNumber::negate(ObNumber &res) const
{
    int ret = OB_SUCCESS;
    if (this->nwords_ >= MAX_NWORDS)
    {
        jlog(WARNING, "value out of range to do negate");
        ret = JD_VALUE_OUT_OF_RANGE;
    }
    else
    {
        res = *this;
        res.extend_words(static_cast<int8_t> (this->nwords_ + 1));
        negate(res, res);
        res.remove_leading_zeroes();
    }
    return ret;
}
Exemplo n.º 8
0
bool ObObj::is_true() const
{
  bool ret = false;
  switch (get_type())
  {
    case ObBoolType:
      ret = value_.bool_val;
      break;
    case ObVarcharType:
      ret = (val_len_ > 0);
      break;
    case ObIntType:
      ret = (value_.int_val != 0);
      break;
    case ObDecimalType:
      {
        ObNumber dec;
        bool is_add = false;
        if (OB_SUCCESS == get_decimal(dec, is_add))
        {
          ret = !dec.is_zero();
        }
        break;
      }
    case ObFloatType:
      ret = (fabsf(value_.float_val) > FLOAT_EPSINON);
      break;
    case ObDoubleType:
      ret = (fabs(value_.double_val) > DOUBLE_EPSINON);
      break;
    case ObDateTimeType:
    case ObPreciseDateTimeType:
    case ObCreateTimeType:
    case ObModifyTimeType:
      {
        int64_t ts1 = 0;
        get_timestamp(ts1);
        ret = (0 != ts1);
        break;
      }
    default:
      break;
  }
  return ret;
}
Exemplo n.º 9
0
int ObNumber::round_to(int8_t precision, int8_t scale, int8_t &nwords, int8_t &vscale, uint32_t *words) const
{
    OB_ASSERT(precision >= scale && 0 <= scale && NULL != words);
    int ret = OB_SUCCESS;
    ObNumber clone = *this;
    bool is_neg = is_negative();
    if (is_neg)
    {
        negate(clone, clone);
    }
    if (clone.vscale_ > scale)
    {
        clone.right_shift(static_cast<int8_t> (clone.vscale_ - scale));
        clone.remove_leading_zeroes();
    }
    ObNumber clone_clone = clone;
    int8_t vprec = 0;
    ObNumber remainder;
    while (!clone_clone.is_zero())
    {
        div_uint32(clone_clone, 10, clone_clone, remainder);
        clone_clone.remove_leading_zeroes();
        ++vprec;
    }
    if (vprec > precision)
    {
        ret = JD_VALUE_OUT_OF_RANGE;
        jlog(WARNING, "value is not representable with the precision and scale, p=%hhd s=%hhd vp=%hhd vs=%hhd",
                precision, scale, vprec, this->vscale_);
    }
    else
    {
        if (is_neg)
        {
            negate(clone, clone);
        }
        nwords = clone.nwords_;
        vscale = clone.vscale_;
        for (int8_t i = 0; i < clone.nwords_; ++i)
        {
            words[i] = clone.words_[i];
        }
    }
    return ret;
}
Exemplo n.º 10
0
 static int varchar_decimal(const ObObjCastParams &params, const ObExprObj &in, ObExprObj &out)
 {
     int ret = OB_SUCCESS;
     UNUSED(params);
     OB_ASSERT(in.get_type() == ObVarcharType);
     const string &varchar = in.get_varchar();
     ObNumber num;
     if (OB_SUCCESS != (ret = num.from(varchar.data(), varchar.length())))
     {
         jlog(WARNING, "failed to convert varchar to decimal, err=%d varchar=%.*s",
                 ret, varchar.length(), varchar.data());
     }
     else
     {
         out.set_decimal(num); // @todo optimize
     }
     return OB_SUCCESS;
 }
Exemplo n.º 11
0
int ObNumber::compare(const ObNumber &other) const
{
    int ret = 0;
    ObNumber res;
    if (OB_SUCCESS != this->sub(other, res))
    {
        // return 0 even if error occur
    }
    else if (res.is_negative())
    {
        ret = -1;
    }
    else if (!res.is_zero())
    {
        ret = 1;
    }
    return ret;
}
Exemplo n.º 12
0
 static int double_decimal(const ObObjCastParams &params, const ObExprObj &in, ObExprObj &out)
 {
     int ret = OB_SUCCESS;
     UNUSED(params);
     OB_ASSERT(in.get_type() == ObDoubleType);
     static const int64_t MAX_DOUBLE_PRINT_SIZE = 64;
     char buf[MAX_DOUBLE_PRINT_SIZE];
     snprintf(buf, MAX_DOUBLE_PRINT_SIZE, "%f", in.get_double());
     ObNumber num;
     if (OB_SUCCESS != (ret = num.from(buf)))
     {
         jlog(WARNING, "failed to convert float to decimal, err=%d", ret);
     }
     else
     {
         out.set_decimal(num);
     }
     return ret;
 }
Exemplo n.º 13
0
void ObNumber::round_fraction_part(int8_t scale)
{
    ObNumber *clone = this;
    ObNumber neg_this;
    bool is_neg = is_negative();
    if (is_neg)
    {
        negate(*this, neg_this);
        clone = &neg_this;
    }
    if (vscale_ > scale)
    {
        clone->right_shift(static_cast<int8_t> (vscale_ - scale));
    }
    if (is_neg)
    {
        negate(*clone, *this);
    }
    remove_leading_zeroes();
}
Exemplo n.º 14
0
int ObObj::get_decimal(ObNumber &num, bool &is_add) const
{
  int ret = OB_OBJ_TYPE_ERROR;
  if (ObDecimalType == meta_.type_)
  {
    ret = OB_SUCCESS;
    is_add = (ADD == meta_.op_flag_);
    int8_t nwords = static_cast<int8_t>(meta_.dec_nwords_ + 1);
    int8_t vscale = meta_.dec_vscale_;
    if (nwords <= 3)
    {
      num.from(vscale, nwords, reinterpret_cast<const uint32_t*>(&val_len_));
    }
    else
    {
      num.from(vscale, nwords, value_.dec_words_);
    }
  }
  return ret;
}
Exemplo n.º 15
0
int ObNumber::add(const ObNumber &other, ObNumber &res) const
{
    int ret = OB_SUCCESS;
    res.set_zero();
    ObNumber n1 = *this;
    ObNumber n2 = other;
    if (n1.vscale_ > SINGLE_PRECISION_NDIGITS)
    {
        n1.round_fraction_part(SINGLE_PRECISION_NDIGITS);
    }
    if (n2.vscale_ > SINGLE_PRECISION_NDIGITS)
    {
        n2.round_fraction_part(SINGLE_PRECISION_NDIGITS);
    }
    int8_t res_nwords = static_cast<int8_t> (std::max(n1.nwords_, n2.nwords_) + 1);
    if (res_nwords > MAX_NWORDS)
    {
        jlog(WARNING, "number out of range");
        ret = JD_VALUE_OUT_OF_RANGE;
    }
    else
    {
        n1.extend_words(res_nwords);
        n2.extend_words(res_nwords);
    }
    if (n1.vscale_ > n2.vscale_)
    {
        ret = n2.left_shift(static_cast<int8_t> (n1.vscale_ - n2.vscale_), false);
    }
    else if (n1.vscale_ < n2.vscale_)
    {
        ret = n1.left_shift(static_cast<int8_t> (n2.vscale_ - n1.vscale_), false);
    }
    if (OB_SUCCESS == ret)
    {
        add_words(n1, n2, res);
        res.remove_leading_zeroes();
    }
    return ret;
}
Exemplo n.º 16
0
int ObNumber::mul(const ObNumber &other, ObNumber &res) const
{
    int ret = OB_SUCCESS;
    res.set_zero();
    if (!this->is_zero() && !other.is_zero())
    {
        ObNumber multiplicand = *this;
        ObNumber multiplier = other;
        bool res_is_neg = false;
        if (multiplicand.is_negative())
        {
            negate(multiplicand, multiplicand);
            res_is_neg = true;
        }
        if (multiplier.is_negative())
        {
            negate(multiplier, multiplier);
            res_is_neg = !res_is_neg;
        }
        if (multiplicand.vscale_ > SINGLE_PRECISION_NDIGITS)
        {
            multiplicand.round_fraction_part(SINGLE_PRECISION_NDIGITS);
        }
        if (multiplier.vscale_ > SINGLE_PRECISION_NDIGITS)
        {
            multiplier.round_fraction_part(SINGLE_PRECISION_NDIGITS);
        }
        res.vscale_ = static_cast<int8_t> (multiplicand.vscale_ + multiplier.vscale_);
        ret = mul_words(multiplicand, multiplier, res);
        res.remove_leading_zeroes();
        if (res_is_neg)
        {
            negate(res, res);
        }
    }
    return ret;
}
Exemplo n.º 17
0
void ObNumber::knuth_div_unsigned(const uint32_t *dividend,
        const ObNumber &divisor,
        ObNumber &quotient, int8_t qidx, ObNumber &remainder)
{
    OB_ASSERT(divisor.words_[divisor.nwords_ - 1] >= HALF_BASE); // (BASE ^ divisor_n)/2 <= divisor
    OB_ASSERT(0 <= qidx && qidx < MAX_NWORDS);
    ObNumber cdividend;
    cdividend.nwords_ = static_cast<int8_t> (divisor.nwords_ + 1);
    for (int8_t i = 0; i < cdividend.nwords_; ++i)
    {
        cdividend.words_[i] = dividend[i];
    }
    ObNumber base;
    base.from(BASE);
    ObNumber p;
    mul_words(base, divisor, p);
    p.remove_leading_zeroes_unsigned();

    int cmp = compare_words_unsigned(cdividend, p);
    if (cmp >= 0)
    {
        sub_words_unsigned(cdividend, p, cdividend);
        knuth_div_unsigned(cdividend.words_, divisor, quotient, qidx, remainder); // recursively called at most once
        quotient.words_[qidx + 1] = 1;
    }
    else
    {
        int8_t n = divisor.nwords_;
        uint64_t q = (UBASE * dividend[n] + dividend[n - 1]) / divisor.words_[n - 1];
        if (q >= UBASE)
        {
            q = UBASE - 1;
        }
        ObNumber Q;
        Q.from(q);
        ObNumber T;
        mul_words(Q, divisor, T);
        T.remove_leading_zeroes_unsigned();
        for (int i = 0; i < 2; ++i)
        {
            cmp = compare_words_unsigned(T, cdividend);
            if (cmp > 0)
            {
                Q.from(--q);
                sub_words_unsigned(T, divisor, T);
            }
            else
            {
                break;
            }
        } // end for
        if (Q.nwords_ == 1)
        {
            quotient.words_[qidx] = Q.words_[0];
        }
        else
        {
            OB_ASSERT(Q.is_zero());
            quotient.words_[qidx] = 0;
        }
        sub_words_unsigned(cdividend, T, remainder);
    }
}
Exemplo n.º 18
0
inline void ObNumber::div_words(const ObNumber &dividend, const ObNumber &divisor, ObNumber &quotient, ObNumber &remainder)
{
    OB_ASSERT(!dividend.is_zero());
    OB_ASSERT(!divisor.is_zero());
    OB_ASSERT(0 < dividend.nwords_ && dividend.nwords_ <= MAX_NWORDS);
    OB_ASSERT(0 < divisor.nwords_ && divisor.nwords_ <= MAX_NWORDS);

    if (1 == divisor.nwords_)
    {
        // fast algorithm
        div_uint32(dividend, divisor.words_[0], quotient, remainder);
    }
    else
    {
        // Knuth's algorithm, Volumn 2, Section 4.3, Page 235
        ObNumber cdivisor;
        ObNumber cdividend;
        if (divisor.words_[divisor.nwords_ - 1] < HALF_BASE)
        {
            // make sure (BASE ^ n)/2 <= divisor
            uint32_t factor = static_cast<uint32_t> (BASE / (divisor.words_[divisor.nwords_ - 1] + 1));
            mul_uint32(divisor, factor, cdivisor, true);
            mul_uint32(dividend, factor, cdividend, true);
            OB_ASSERT(cdivisor.words_[cdivisor.nwords_ - 1] >= HALF_BASE);
        }
        else
        {
            cdividend = dividend;
            cdivisor = divisor;
        }

        if (cdividend.nwords_ < cdivisor.nwords_) // include the case when dividend is zero
        {
            quotient.set_zero();
            remainder = dividend;
        }
        else if (cdividend.nwords_ == cdivisor.nwords_)
        {
            int cmp = compare_words_unsigned(cdividend, cdivisor);
            if (cmp < 0)
            {
                quotient.set_zero();
                remainder = dividend;
            }
            else
            {
                quotient.nwords_ = 1;
                quotient.words_[0] = 1;
                sub_words_unsigned(cdividend, cdivisor, remainder);
            }
        }
        else // dividend.nwords_ >= 1 + divosor.nwords_
        {
            quotient.nwords_ = static_cast<int8_t> (cdividend.nwords_ - cdivisor.nwords_ + 1);
            memset(quotient.words_, 0, sizeof (quotient.words_));
            for (int8_t i = static_cast<int8_t> (cdividend.nwords_ - cdivisor.nwords_ - 1); i >= 0; --i)
            {
                knuth_div_unsigned(&cdividend.words_[i], cdivisor, quotient, i, remainder);
                for (int8_t j = 0; j < cdivisor.nwords_; ++j)
                {
                    cdividend.words_[i + j] = remainder.words_[j];
                }
            }
        }
    }
    if (quotient.nwords_ > 0
            && static_cast<int64_t> (quotient.words_[quotient.nwords_ - 1]) >= HALF_BASE)
    {
        quotient.words_[quotient.nwords_++] = 0; // quotient is always positive
    }
    if (remainder.nwords_ > 0
            && static_cast<int64_t> (remainder.words_[remainder.nwords_ - 1]) >= HALF_BASE)
    {
        remainder.words_[remainder.nwords_++] = 0; // remainder is always positive
    }
}
Exemplo n.º 19
0
void ObObj::dump(const int32_t log_level /*=TBSYS_LOG_LEVEL_DEBUG*/) const
{
  int64_t int_val = 0;
  bool bool_val = false;
  bool is_add = false;
  float float_val = 0.0f;
  double double_val = 0.0f;
  ObString str_val;
  ObNumber num;
  char num_buf[ObNumber::MAX_PRINTABLE_SIZE];
  switch (get_type())
  {
    case ObNullType:
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level), "[%ld] type:ObNull",pthread_self());
      break;
    case ObIntType:
      get_int(int_val,is_add);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObInt, val:%ld,is_add:%s",pthread_self(),int_val,is_add ? "true" : "false");
      break;
    case ObVarcharType:
      get_varchar(str_val);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObVarChar,len :%d,val:",pthread_self(),str_val.length());
      common::hex_dump(str_val.ptr(),str_val.length(),true,log_level);
      break;
    case ObFloatType:
      get_float(float_val,is_add);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObFloat, val:%f,is_add:%s",pthread_self(),float_val,is_add ? "true" : "false");
      break;
    case ObDoubleType:
      get_double(double_val,is_add);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObDouble, val:%f,is_add:%s",pthread_self(),double_val,is_add ? "true" : "false");
      break;
    case ObDateTimeType:
      get_datetime(int_val,is_add);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObDateTime(seconds), val:%ld,is_add:%s",pthread_self(),int_val,is_add ? "true" : "false");
      break;
    case ObPreciseDateTimeType:
      get_precise_datetime(int_val,is_add);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObPreciseDateTime(microseconds), val:%ld,is_add:%s",pthread_self(),int_val,is_add ? "true" : "false");
      break;
    case ObSeqType:
      //TODO
      break;
    case ObCreateTimeType:
      get_createtime(int_val);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObCreateTime, val:%ld",pthread_self(),int_val);
      break;
    case ObModifyTimeType:
      get_modifytime(int_val);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObModifyTime, val:%ld",pthread_self(),int_val);
      break;
    case ObBoolType:
      get_bool(bool_val);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObBool, val:%s",pthread_self(),bool_val?"true":"false");
      break;
    case ObExtendType:
      get_ext(int_val);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObExt, val:%ld",pthread_self(),int_val);
      break;
    case ObDecimalType:
      get_decimal(num, is_add);
      num.to_string(num_buf, ObNumber::MAX_PRINTABLE_SIZE);
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level),
          "[%ld] type:ObDecimalType, val:%s, is_add:%s",
          pthread_self(), num_buf, is_add ? "true" : "false");
      break;
    default:
      TBSYS_LOGGER.logMessage(TBSYS_LOG_NUM_LEVEL(log_level)," [%ld] unexpected type (%d)",pthread_self(),get_type());
      break;
  }
}
Exemplo n.º 20
0
int64_t ObNumber::to_string(char* buf, const int64_t buf_len) const
{
    int64_t pos = 0;
    OB_ASSERT(nwords_ <= MAX_NWORDS);
    OB_ASSERT(nwords_ > 0);
    char inner_buf[MAX_PRINTABLE_SIZE];
    ObNumber clone;
    bool is_neg = is_negative();
    if (is_neg)
    {
        negate(*this, clone);
    }
    else
    {
        clone = *this;
    }
    ObNumber remainder;
    int i = MAX_PRINTABLE_SIZE;
    while (!clone.is_zero())
    {
        div_uint32(clone, 10, clone, remainder);
        if (remainder.is_zero())
        {
            inner_buf[--i] = '0';
        }
        else
        {
            OB_ASSERT(1 == remainder.nwords_);
            OB_ASSERT(remainder.words_[0] < 10 && remainder.words_[0] > 0);
            inner_buf[--i] = static_cast<char> ('0' + remainder.words_[0]);
        }
        OB_ASSERT(0 < i);
    } // end while
    int64_t dec_digits_num = MAX_PRINTABLE_SIZE - i;
    if (0 == dec_digits_num)
    {
        databuff_printf(buf, buf_len, pos, "0");
    }
    else
    {
        if (is_neg)
        {
            databuff_printf(buf, buf_len, pos, "-");
        }
        if (clone.vscale_ >= dec_digits_num)
        {
            // 0.0...0xxx
            databuff_printf(buf, buf_len, pos, "0.");
            for (int j = 0; j < clone.vscale_ - dec_digits_num; ++j)
            {
                databuff_printf(buf, buf_len, pos, "0");
            }
            if (NULL != buf && 0 <= pos && dec_digits_num < buf_len - pos)
            {
                memcpy(buf + pos, inner_buf + i, dec_digits_num);
                pos += dec_digits_num;
                buf[pos] = '\0';
            }
        }
        else
        {
            if (NULL != buf && 0 <= pos && dec_digits_num - clone.vscale_ < buf_len - pos)
            {
                memcpy(buf + pos, inner_buf + i, dec_digits_num - clone.vscale_); // digits before the point
                pos += dec_digits_num - clone.vscale_;
            }
            if (clone.vscale_ > 0)
            {
                if (NULL != buf && 0 <= pos && 1 + clone.vscale_ < buf_len - pos)
                {
                    buf[pos++] = '.';
                    memcpy(buf + pos, inner_buf + i + dec_digits_num - clone.vscale_, clone.vscale_); // digits after the point
                    pos += clone.vscale_;
                }
            }
            if (NULL != buf && 0 <= pos && 0 < buf_len - pos)
            {
                buf[pos] = '\0';
            }
        }
    }
    OB_ASSERT(pos <= buf_len);
    return pos;
}
Exemplo n.º 21
0
int64_t ObObj::to_string(char* buffer, const int64_t length) const
{
  static const char* obj_type_name[] =
  {
    "null",
    "int",
    "float",
    "double",
    "datetime",
    "precisedatetime",
    "varchar",
    "seq",
    "createtime",
    "modifytime",
    "extend",
    "bool",
    "decimal"
  };

  int64_t int_val = 0;
  float float_val = 0.0;
  double double_val = 0.0;
  bool is_add = false;
  ObString str_val;
  int32_t type = meta_.type_;
  int64_t pos = 0;

  if (type > ObMinType && type < ObMaxType)
  {
    databuff_printf(buffer, length, pos, "%s:", obj_type_name[meta_.type_]);
  }
  else
  {
    databuff_printf(buffer, length, pos, "%s", "unknown");
  }

  {
    switch(meta_.type_)
    {
      case ObNullType:
        break;
      case ObIntType:
        get_int(int_val,is_add);
        databuff_printf(buffer, length, pos,  "%s%ld",  is_add ? "+" : "", int_val);
        break;
      case ObVarcharType:
        get_varchar(str_val);
        databuff_printf(buffer, length, pos, "%.*s", str_val.length(), str_val.ptr());
        break;
      case ObFloatType:
        get_float(float_val,is_add);
        databuff_printf(buffer, length, pos, "%s%f",  is_add ? "+" : "", float_val);
        break;
      case ObDoubleType:
        get_double(double_val,is_add);
        databuff_printf(buffer, length, pos, "%s%.12lf",  is_add ? "+" : "", double_val);
        break;
      case ObDateTimeType:
        get_datetime(int_val,is_add);
        databuff_printf(buffer, length, pos, "%s%ld",  is_add ? "+" : "", int_val);
        break;
      case ObPreciseDateTimeType:
        get_precise_datetime(int_val,is_add);
        databuff_printf(buffer, length, pos, "%s%ld",  is_add ? "+" : "", int_val);
        break;
      case ObSeqType:
        //TODO
        break;
      case ObCreateTimeType:
        get_createtime(int_val);
        databuff_printf(buffer, length, pos, "%ld", int_val);
        break;
      case ObModifyTimeType:
        get_modifytime(int_val);
        databuff_printf(buffer, length, pos, "%ld", int_val);
        break;
      case ObExtendType:
        get_ext(int_val);
        if (MIN_OBJECT_VALUE == int_val)
        {
          databuff_printf(buffer, length, pos, "min");
        }
        else if (MAX_OBJECT_VALUE == int_val)
        {
          databuff_printf(buffer, length, pos, "max");
        }
        else
        {
          databuff_printf(buffer, length, pos, "%ld", int_val);
        }
        break;
      case ObBoolType:
        databuff_printf(buffer, length, pos, "%c", value_.bool_val ? 'Y': 'N');
        break;
      case ObDecimalType:
      {
        char num_buf[ObNumber::MAX_PRINTABLE_SIZE];
        ObNumber num;
        get_decimal(num);
        num.to_string(num_buf, ObNumber::MAX_PRINTABLE_SIZE);
        databuff_printf(buffer, length, pos, "%s", num_buf);
        break;
      }
      default:
        break;
    }
  }
  return pos;
}
Exemplo n.º 22
0
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;
}