Integer Integer::operator *(Integer Y) { digitList* pTail = Y.digits; while (length() > Y.length()) { while (pTail->getNextDigit() != NULL) pTail = pTail->getNextDigit(); digitList* pTemp = new digitList(); pTail->nextDigit = pTemp; pTail = pTemp; } if (length() < Y.length()) { Integer* pThis = this; return Y * (*pThis); } Integer P; if (digits->getNextDigit() == NULL) P = Integer(digits->digit * Y.digits->digit); else { Integer P1, P2, P3, P4; int l = length(); int n = l / 2; P1 = leftDigits(n) * Y.leftDigits(n); P2 = rightDigits(l - n) * Y.leftDigits(n); P3 = leftDigits(n) * Y.rightDigits(l - n); P4 = rightDigits(l - n) * Y.rightDigits(l - n); P2 = P2 + P3; P2 = P2.shift(n); P4 = P4.shift(2 * n); P = P1 + P2; P = P + P4; } // truong hop nhan mot so voi so khong if (P.digits == NULL) { digitList* node = new digitList(); P.digits = node; } P = P.trimDigit(); if ((sign == Y.sign) || ((P.digits->getDigit() == 0) && (P.digits->getNextDigit() == NULL))) return Integer(1, P.digits); else return Integer(-1, P.digits); }
static void eval(Thread& thread, A const& a, Integer const& d, int64_t nonzero, Value& out) { A r(nonzero); int64_t j = 0; typename A::Element const* ae = a.v(); typename Integer::Element const* de = d.v(); typename A::Element* re = r.v(); int64_t length = d.length(); for(int64_t i = 0; i < length; i++) { if(Integer::isNA(de[i])) re[j++] = A::NAelement; else if(de[i] != 0) re[j++] = ae[de[i]-1]; } out = r; }
static void eval(Thread& thread, A const& a, Integer const& d, int64_t nonzero, Value& out) { std::set<Integer::Element> index; typename A::Element const* ae = a.v(); typename Integer::Element const* de = d.v(); int64_t length = d.length(); for(int64_t i = 0; i < length; i++) if(-de[i] > 0 && -de[i] <= (int64_t)a.length()) index.insert(-de[i]); // iterate through excluded elements copying intervening ranges. A r(a.length()-index.size()); typename A::Element* re = r.v(); int64_t start = 1; int64_t k = 0; for(std::set<Integer::Element>::const_iterator i = index.begin(); i != index.end(); ++i) { int64_t end = *i; for(int64_t j = start; j < end; j++) re[k++] = ae[j-1]; start = end+1; } for(int64_t j = start; j <= a.length(); j++) re[k++] = ae[j-1]; out = r; }
void SubsetSlow(Thread& thread, Value const& a, Value const& i, Value& out) { if(i.isDouble() || i.isInteger()) { Integer index = As<Integer>(thread, i); int64_t positive = 0, negative = 0; for(int64_t i = 0; i < index.length(); i++) { if(index[i] > 0 || Integer::isNA(index[i])) positive++; else if(index[i] < 0) negative++; } if(positive > 0 && negative > 0) _error("mixed subscripts not allowed"); else if(positive > 0) { switch(a.type()) { case Type::Null: out = Null::Singleton(); break; #define CASE(Name,...) case Type::Name: SubsetInclude<Name>::eval(thread, (Name const&)a, index, positive, out); break; VECTOR_TYPES_NOT_NULL(CASE) #undef CASE default: _error(std::string("NYI: Subset of ") + Type::toString(a.type())); break; }; } else if(negative > 0) {
static int unsigned_rem_result_length(Integer& x, Integer& y) { return y.length(); }
static int unsigned_quo_result_length(Integer& x, Integer& y) { return max(x.length() - y.length() + 1, 0); }
static int unsigned_mul_result_length(Integer& x, Integer& y) { return x.is_zero() || y.is_zero() ? 0 : x.length() + y.length(); }
static int unsigned_sub_result_length(Integer& x, Integer& y) { return x.length(); }
static int unsigned_add_result_length(Integer& x, Integer& y) { return max(x.length(), y.length()) + 1; }