spigotcpp/Spigot.cpp
A.M. Rowsell bc12d981d0
Link Windows exe statically, change location of std::flush
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.
2023-06-20 17:55:09 -04:00

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;
}