LongNumber LongNumber::operator -(LongNumber const& other) const { if (container.isStatic() && other.container.isStatic()) { // both numbers are inside long long type long long val1 = container.getValue() * (container.hasSign() ? -1 : 1); long long val2 = other.container.getValue() * (other.container.hasSign() ? -1 : 1); if (checkAdd(val1, -val2, val1)) return LongNumber(NumberContainer(val1)); } if (container.hasSign() ^ other.container.hasSign()) // different signs, just add them, // use sign of left operand return LongNumber(add(container, other.container)); else { // same sign, below |X| >= |y| int comp = compareAbs(container, other.container); if (comp >= 0) // X - y, us sign of X return LongNumber(sub(container, other.container)); else { // y - X, use opposite to sign of X NumberContainer numCont = sub(other.container, container); numCont.setSign(!other.container.hasSign()); return LongNumber(numCont); } } }
LongNumber LongNumber::operator +(LongNumber const& other) const { if (container.isStatic() && other.container.isStatic()) { // both numbers are inside long long type long long val1 = container.getValue() * (container.hasSign() ? -1 : 1); long long val2 = other.container.getValue() * (other.container.hasSign() ? -1 : 1); if (checkAdd(val1, val2, val1)) return LongNumber(NumberContainer(val1)); } if (container.hasSign() ^ other.container.hasSign()) { // different signs, substract min abs from greater by abs // use sign of greater by abs int comp = compareAbs(container, other.container); if (comp >= 0) return LongNumber(sub(container, other.container)); else return LongNumber(sub(other.container, container)); } else // same signs, just add them return LongNumber(add(container, other.container)); }
NumberContainer LongNumber::sub(const NumberContainer& left, const NumberContainer& right) { int leftLen = left.length(); int rightLen = right.length(); int len = leftLen > rightLen ? leftLen : rightLen; long long val = 0, tens = 1; bool isStatic = true; char borrowed = 0; int nonZeroDigit = 0;// last non zero digit (length of result) for (int i = 0; i < len; i++) { char leftDigit = i < leftLen ? left.getDigit(i) : 0; char rightDigit = i < rightLen ? right.getDigit(i) : 0; char sum = (char)(leftDigit - rightDigit + borrowed); char digit = (sum + 10) % 10; nonZeroDigit = digit > 0 ? i : nonZeroDigit; if (isStatic) { long long dt = 0; if (!checkMult(tens, digit, dt)) isStatic = false; else if (!checkAdd(val, dt, val)) isStatic = false; // if this exceeds, next iteration tens * digit will exceed else if (i < len - 1 && !checkMult(tens, 10, tens)) isStatic = false; } borrowed = (sum < 0 ? -1 : 0); } NumberContainer result(0); if (isStatic) { result = NumberContainer(true, 0); result.setSign(left.hasSign()); result.setValue(val); } else { result = NumberContainer(false, nonZeroDigit + 1); borrowed = 0; for (int i = 0; i < len; i++) { char leftDigit = i < leftLen ? left.getDigit(i) : 0; char rightDigit = i < rightLen ? right.getDigit(i) : 0; char sum = (char)(leftDigit - rightDigit + borrowed); char digit = (sum + 10) % 10; result.setDigit(i, digit); borrowed = (sum < 0 ? -1 : 0); } result.setSign(left.hasSign()); } return result; }
/******************************************************************************** * LongNumber * public methods *********************************************************************************/ LongNumber::LongNumber(char const* strnum) : container(0) { bool hasSign = false; bool isStatic = true; while (*strnum == ' ') strnum++; if (*strnum == '+') strnum++; else if (*strnum == '-') { strnum++; hasSign = true; } char const* iter = strnum; long long curVal = 0; int curLength = 0; while (*iter != 0) { curLength++; if (isStatic) { if (*iter < '0' || *iter > '9') throw FormatException("Wrong character"); char digit = *iter - '0'; if (!checkMult(curVal, 10, curVal)) isStatic = false; else if (!checkAdd(curVal, digit, curVal)) isStatic = false; } iter++; } container = NumberContainer(isStatic, curLength); container.setSign(hasSign); if (isStatic) container.setValue(curVal); else { int position = 0; iter--; while (iter != strnum) { if (*iter < '0' || *iter > '9') { container.~NumberContainer(); throw FormatException("Wrong character"); } container.setDigit(position, *iter - '0'); position++; iter--; } container.setDigit(position, *iter - '0'); } }
void PacingGod::notifyViolation( const IB::Contract& c ) { std::string farm; std::string lazyC; checkAdd( c, &lazyC, &farm ); controlGlobal.notifyViolation(); if( farm.empty() ) { DEBUG_PRINTF( "set violation lazy" ); assert( controlLazy.find(lazyC) != controlLazy.end() && controlHmds.find(farm) == controlHmds.end() ); controlLazy[lazyC]->notifyViolation(); } else { DEBUG_PRINTF( "set violation farm %s", farm.c_str() ); assert( controlHmds.find(farm) != controlHmds.end() && controlLazy.find(lazyC) == controlLazy.end() ); controlHmds[farm]->notifyViolation(); } }
void PacingGod::addRequest( const IB::Contract& c ) { std::string farm; std::string lazyC; checkAdd( c, &lazyC, &farm ); controlGlobal.addRequest(); if( farm.empty() ) { DEBUG_PRINTF( "add request lazy" ); assert( controlLazy.find(lazyC) != controlLazy.end() && controlHmds.find(farm) == controlHmds.end() ); controlLazy[lazyC]->addRequest(); } else { DEBUG_PRINTF( "add request farm %s", farm.c_str() ); assert( controlHmds.find(farm) != controlHmds.end() && controlLazy.find(lazyC) == controlLazy.end() ); controlHmds[farm]->addRequest(); } }
int PacingGod::countLeft( const IB::Contract& c ) { std::string farm; std::string lazyC; checkAdd( c, &lazyC, &farm ); bool laziesCleared = laziesAreCleared(); if( farm.empty() || !laziesCleared ) { // we have to use controlGlobal if any contract's farm is ambiguous assert( (controlLazy.find(lazyC) != controlLazy.end() && controlHmds.find(farm) == controlHmds.end()) || !laziesCleared ); int left = controlGlobal.countLeft(); DEBUG_PRINTF( "get count left global %d", left ); return left; } else { assert( (controlHmds.find(farm) != controlHmds.end() && controlLazy.empty()) || laziesCleared ); int left = controlHmds.find(farm)->second->countLeft(); DEBUG_PRINTF( "get count left farm %s %d", farm.c_str(), left ); return controlHmds.find(farm)->second->countLeft(); } }
int PacingGod::goodTime( const IB::Contract& c ) { const char* dbg; std::string farm; std::string lazyC; checkAdd( c, &lazyC, &farm ); bool laziesCleared = laziesAreCleared(); if( farm.empty() || !laziesCleared ) { // we have to use controlGlobal if any contract's farm is ambiguous assert( (controlLazy.find(lazyC) != controlLazy.end() && controlHmds.find(farm) == controlHmds.end() ) || !laziesCleared ); int t = controlGlobal.goodTime(&dbg); DEBUG_PRINTF( "get good time global %s %d", dbg, t ); return t; } else { assert( (controlHmds.find(farm) != controlHmds.end() && controlLazy.empty()) || laziesCleared ); int t = controlHmds.find(farm)->second->goodTime(&dbg); DEBUG_PRINTF( "get good time farm %s %s %d", farm.c_str(), dbg, t ); return t; } }