#include #include #include #include "Spigot.hpp" Spigot::Spigot(int requestedNumDigits) { /* create list for number of digits times 10 / 3 */ this->spigotListLength = (requestedNumDigits * 10) / 3; this->spigotList.resize(this->spigotListLength, 2); // list is initialized with all 2 this->carry = 0; return; } void Spigot::pump(void) { int tempPreDigit = 0; int j = this->spigotListLength - 1; int i = j; /* * This could be handled using boost::compute * with a BOOST_COMPUTE_FUNCTION that just * multiplies every item by 10. */ while(i >= 0) { this->spigotList[i] *= 10; i--; } this->carry = 0; i = j; // note this does *not* handle the i=0 case /* * This might also be able to be sped up * with OpenCL/boost::compute by creating * another custom function, but because * the carry has to be passed along this might * not work well */ while(i > 0) { this->spigotList[i] += this->carry; this->carry = (this->spigotList[i] / (i * 2 + 1)) * i; this->spigotList[i] = this->spigotList[i] % (i * 2 + 1); i--; } // special case of i = 0 this->spigotList[0] += this->carry; tempPreDigit = this->spigotList[0] / 10; this->spigotList[0] -= (tempPreDigit * 10); try { // handle the cases depending on the tempPreDigit if(tempPreDigit >= 0 && tempPreDigit <= 8) { // output all predigits long unsigned pdLen = this->preDigits.size(); for(long unsigned int j = 0; j < pdLen; j++) { std::cout << this->preDigits.back(); this->preDigits.pop_back(); } this->preDigits.insert(this->preDigits.begin(), tempPreDigit); } else if(tempPreDigit == 9) { this->preDigits.insert(this->preDigits.begin(), tempPreDigit); } else if(tempPreDigit == 10) { tempPreDigit = 0; long unsigned pdLen = this->preDigits.size(); for(long unsigned int j = 0; j < pdLen; j++) { std::cout << (this->preDigits.back() + 1) % 10; this->preDigits.pop_back(); } this->preDigits.insert(this->preDigits.begin(), tempPreDigit); } else { std::cout << "We should never have gotten here -- shit has hit the fan!" << std::endl; } } catch (int e) { std::cout << "An exception " << e << " occurred." << std::endl; } std::cout << std::flush; return; }