예제 #1
0
파일: DateUtils.cpp 프로젝트: kanbang/Colt
MAPM DateUtils::convertDMY2Absolute(MAPM day, MAPM month, MAPM year)
{
  MAPM prevYear = year - 1;
  if(year.sign() < 0) ++prevYear;
  MAPM absolute = ( prevYear * 365 ) + prevYear.integer_divide(4) - prevYear.integer_divide(100) +
    prevYear.integer_divide(400);

  if(isLeapYear(year))
    absolute+=days_before_month_leap[asInt(month)-1];
  else
    absolute+=days_before_month[asInt(month)-1];
  absolute+= day;
  return absolute - 1;
}
예제 #2
0
/** Returns the mod of its operands as a Numeric */
Numeric::Ptr ATFloatOrDerivedImpl::mod(const Numeric::Ptr &other, const DynamicContext* context) const {
    if(other->getPrimitiveTypeIndex() == AnyAtomicType::DECIMAL) {
        // if other is a decimal, promote it to xs:float
        return this->mod((const Numeric::Ptr )other->castAs(this->getPrimitiveTypeIndex(), context), context);
    } else if (other->getPrimitiveTypeIndex() == AnyAtomicType::DOUBLE) {
        // if other is a double, promote this to xs:double
        return ((const Numeric::Ptr )this->castAs(other->getPrimitiveTypeIndex(), context))->mod(other, context);
    } else if (other->getPrimitiveTypeIndex() == AnyAtomicType::FLOAT) {
        // same primitive type, can make comparison
        const ATFloatOrDerivedImpl* otherImpl = (ATFloatOrDerivedImpl*)(const Numeric*)other;
        if(this->isNaN() || otherImpl->isNaN() || this->isInfinite() || otherImpl->isZero()) {
            return notANumber(context);
        } else if(otherImpl->isInfinite() || this->isZero()) {
            return (const Numeric::Ptr )this->castAs(AnyAtomicType::FLOAT, context);
        } else {
            MAPM result = _float;
            MAPM r;
            r = result.integer_divide(otherImpl->_float);
            result -= r * otherImpl->_float;
            if (result == 0 && isNegative())
                return negZero(context);
            return newFloat(result, context);
        }
    } else {
        assert(false); // should never get here, numeric types are xs:decimal, xs:float, xs:integer and xs:double
        return 0;
    }
}
예제 #3
0
/** Returns the arithmetic product of its operands as a Numeric */
Numeric::Ptr ATDecimalOrDerivedImpl::mod(const Numeric::Ptr &other, const DynamicContext* context) const {
  if(this->isOfType(other->getTypeURI(), other->getTypeName(), context)) {
    // if both are of the same type exactly, we can perform the modulo
    const ATDecimalOrDerivedImpl* otherImpl = (ATDecimalOrDerivedImpl*)(const Numeric*)other;
  
    if(otherImpl->isZero()) {
      XQThrow2(::IllegalArgumentException, X("ATDecimalOrDerivedImpl::mod"), X("Division by zero [err:FOAR0001]"));
    }
  
    MAPM result = _decimal;
    MAPM r;
    r = result.integer_divide(otherImpl->_decimal);
    result -= r * otherImpl->_decimal;
    // if integer, return xs:integer, otherwise xs:decimal    
    if(_isInteger) {
      return context->getItemFactory()->createInteger(result, context);
    }
    return context->getItemFactory()->createDecimal(result, context);
  } else if(this->getPrimitiveTypeIndex() != other->getPrimitiveTypeIndex()) {
    // if other is not a decimal, then we need to promote this to a float or double
    return ((const Numeric::Ptr )this->castAs(other->getPrimitiveTypeIndex(), context))->mod(other, context);
  } else if (this->isInstanceOfType(other->getTypeURI(), other->getTypeName(), context)) {
    // here we know we have two decimals, and this is 'lower' in the hierarchy than other
    // so cast this to other's type
    return ((const Numeric::Ptr )this->castAs(AnyAtomicType::DECIMAL, other->getTypeURI(), other->getTypeName(), context))->mod(other, context);
  } else if (other->isInstanceOfType(this->getTypeURI(), this->getTypeName(), context)) {
    // here we have two decimals, and this is 'higher' in the hierarchy than other
    // so cast other to this' type
    return this->mod((const Numeric::Ptr )other->castAs(AnyAtomicType::DECIMAL, this->getTypeURI(), this->getTypeName(), context), context);
  } else {
    // we have two separate branches.  if either is instance of integer, cast it to integer, otherwise, cast to decimal
    // revisit: this is not the prettiest way to do it.  You would want to go up the tree one by one instead of
    // jumping to integer and decimal
    ATDecimalOrDerived::Ptr first;
    ATDecimalOrDerived::Ptr second; 
    if(this->_isInteger) {
      first = (const ATDecimalOrDerived::Ptr )this->castAs(AnyAtomicType::DECIMAL, SchemaSymbols::fgURI_SCHEMAFORSCHEMA,
                           SchemaSymbols::fgDT_INTEGER, context);
    } else {
      first = (const ATDecimalOrDerived::Ptr )this->castAs(AnyAtomicType::DECIMAL, context);
    }
    
    if(((ATDecimalOrDerivedImpl*)(const Numeric*)other)->_isInteger) {
      second = (const ATDecimalOrDerived::Ptr )other->castAs(AnyAtomicType::DECIMAL, SchemaSymbols::fgURI_SCHEMAFORSCHEMA,
                            SchemaSymbols::fgDT_INTEGER, context);
    } else {
      second = (const ATDecimalOrDerived::Ptr )other->castAs(AnyAtomicType::DECIMAL, context);
    }
    return first->mod(second, context);
  }

}