A.M. Rowsell
bc12d981d0
The Windows exe has to be linked statically, because Windows is stupid and doesn't have dynamic libraries like the stdc++ lib available. Maybe it's in some .dll somewhere, but I can't be bothered. Linux is just better. The change to the location of flush will make the output look more "spigot"-like, ie with large numbers of digits generated, the digits will be output in small groups instead of a nice smooth digit at a time. For some reason this is how most spigot algorithms do it, and so to me it "looks" correct. It doesn't actually change anything whatsoever other than when the standard output actually gets printed to console.
66 lines
2.2 KiB
C++
66 lines
2.2 KiB
C++
#include <iostream>
|
|
#include <cmath>
|
|
#include <cassert>
|
|
#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;
|
|
while(i >= 0) {
|
|
this->spigotList[i] *= 10;
|
|
i--;
|
|
}
|
|
this->carry = 0;
|
|
i = j;
|
|
// note this does *not* handle the i=0 case
|
|
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;
|
|
}
|