Ejemplo n.º 1
0
NValue NValue::opDivideDecimals(const NValue lhs, const NValue rhs) const {
    if ((lhs.getValueType() != VALUE_TYPE_DECIMAL) ||
        (rhs.getValueType() != VALUE_TYPE_DECIMAL))
    {
        throw SQLException(SQLException::dynamic_sql_error, "No decimal NValue in decimal subtract");
    }

    if (lhs.isNull() || rhs.isNull()) {
        TTInt retval;
        retval.SetMin();
        return getDecimalValue( retval );
    }

    TTLInt calc;
    calc.FromInt(lhs.getDecimal());
    calc *= NValue::kMaxScaleFactor;
    if (calc.Div(rhs.getDecimal())) {
        char message[4096];
        snprintf( message, 4096, "Attempted to divide %s by %s causing overflow/underflow (or divide by zero)",
                lhs.createStringFromDecimal().c_str(), rhs.createStringFromDecimal().c_str());
        throw SQLException(SQLException::data_exception_numeric_value_out_of_range,
                           message);
    }
    TTInt retval;
    if (retval.FromInt(calc)  || retval > NValue::s_maxDecimal || retval < s_minDecimal) {
        char message[4096];
        snprintf( message, 4096, "Attempted to divide %s by %s causing overflow. Unscaled result was %s",
                lhs.createStringFromDecimal().c_str(), rhs.createStringFromDecimal().c_str(),
                calc.ToString(10).c_str());
        throw SQLException(SQLException::data_exception_numeric_value_out_of_range,
                           message);
    }
    return getDecimalValue(retval);
}
Ejemplo n.º 2
0
/**
 * Serialize sign and value using radix point (no exponent).
 */
std::string NValue::createStringFromDecimal() const {
    assert(!isNull());
    std::ostringstream buffer;
    TTInt scaledValue = getDecimal();
    if (scaledValue.IsSign()) {
        buffer << '-';
    }
    TTInt whole(scaledValue);
    TTInt fractional(scaledValue);
    whole /= NValue::kMaxScaleFactor;
    fractional %= NValue::kMaxScaleFactor;
    if (whole.IsSign()) {
        whole.ChangeSign();
    }
    buffer << whole.ToString(10);
    buffer << '.';
    if (fractional.IsSign()) {
        fractional.ChangeSign();
    }
    std::string fractionalString = fractional.ToString(10);
    for (int ii = static_cast<int>(fractionalString.size()); ii < NValue::kMaxDecScale; ii++) {
        buffer << '0';
    }
    buffer << fractionalString;
    return buffer.str();
}
Ejemplo n.º 3
0
Decimal Decimal::op_subtract(const Decimal rhs) const {

  TTInt rett;
  rett = this->GetTTInt();
  rett.Sub(rhs.GetTTInt());

  Decimal ret;
  ret.SetTTInt(rett);

  return ret;
}
Ejemplo n.º 4
0
Decimal Decimal::op_add(const Decimal rhs) const {

  TTInt rett;
  rett = this->GetTTInt();
  rett.Add(rhs.GetTTInt());

  Decimal ret;
  ret.SetTTInt(rett);

  return ret;
}
Ejemplo n.º 5
0
string Decimal::toString(unsigned number_of_fractinal_digits) const {
  if (isNull()) return "NULL";
  string ress = "";
  TTInt rest = this->word[0];
  rest.ToString(ress);
  int sign = 0;
  if (rest.IsSign()) sign = 1;
  while ((Decimal::kMaxDecScale + sign - (int) ress.length()) >= 0)
    ress.insert(sign, "0");
  if(number_of_fractinal_digits > 0)
    ress.insert(ress.length() - Decimal::kMaxDecScale, ".");
  ress.erase(ress.size() - Decimal::kMaxDecScale + number_of_fractinal_digits,
             Decimal::kMaxDecScale - number_of_fractinal_digits);
  return ress;
}
Ejemplo n.º 6
0
/*
 * Avoid scaling both sides if possible. E.g, don't turn dec * 2 into
 * (dec * 2*kMaxScale*E-12). Then the result of simple multiplication
 * is a*b*E-24 and have to further multiply to get back to the assumed
 * E-12, which can overflow unnecessarily at the middle step.
 */
NValue NValue::opMultiplyDecimals(const NValue &lhs, const NValue &rhs) const {
    if ((lhs.getValueType() != VALUE_TYPE_DECIMAL) &&
        (rhs.getValueType() != VALUE_TYPE_DECIMAL))
    {
        throw SQLException(SQLException::dynamic_sql_error, "Non-decimal NValue in decimal multiply");
    }

    if (lhs.isNull() || rhs.isNull()) {
        TTInt retval;
        retval.SetMin();
        return getDecimalValue( retval );
    }

    if ((lhs.getValueType() == VALUE_TYPE_DECIMAL) &&
        (rhs.getValueType() == VALUE_TYPE_DECIMAL))
    {
        TTLInt calc;
        calc.FromInt(lhs.getDecimal());
        calc *= rhs.getDecimal();
        calc /= NValue::kMaxScaleFactor;
        TTInt retval;
        if (retval.FromInt(calc)  || retval > NValue::s_maxDecimal || retval < s_minDecimal) {
            char message[4096];
            snprintf(message, 4096, "Attempted to multiply %s by %s causing overflow/underflow. Unscaled result was %s",
                    lhs.createStringFromDecimal().c_str(), rhs.createStringFromDecimal().c_str(),
                    calc.ToString(10).c_str());
            throw SQLException(SQLException::data_exception_numeric_value_out_of_range,
                               message);
        }
        return getDecimalValue(retval);
    } else if  (lhs.getValueType() != VALUE_TYPE_DECIMAL)
    {
        TTLInt calc;
        calc.FromInt(rhs.getDecimal());
        calc *= lhs.castAsDecimalAndGetValue();
        calc /= NValue::kMaxScaleFactor;
        TTInt retval;
        retval.FromInt(calc);
        if (retval.FromInt(calc)  || retval > NValue::s_maxDecimal || retval < s_minDecimal) {
            char message[4096];
            snprintf(message, 4096, "Attempted to multiply %s by %s causing overflow/underflow. Unscaled result was %s",
                    lhs.createStringFromDecimal().c_str(), rhs.createStringFromDecimal().c_str(),
                    calc.ToString(10).c_str());
            throw SQLException(SQLException::data_exception_numeric_value_out_of_range,
                               message);
        }
        return getDecimalValue(retval);
    }
    else
    {
        TTLInt calc;
        calc.FromInt(lhs.getDecimal());
        calc *= rhs.castAsDecimalAndGetValue();
        calc /= NValue::kMaxScaleFactor;
        TTInt retval;
        retval.FromInt(calc);
        if (retval.FromInt(calc)  || retval > NValue::s_maxDecimal || retval < s_minDecimal) {
            char message[4096];
            snprintf(message, 4096, "Attempted to multiply %s by %s causing overflow/underflow. Unscaled result was %s",
                    lhs.createStringFromDecimal().c_str(), rhs.createStringFromDecimal().c_str(),
                    calc.ToString(10).c_str());
            throw SQLException(SQLException::data_exception_numeric_value_out_of_range,
                               message);
        }
        return getDecimalValue(retval);
   }
}