Skip to content

Instantly share code, notes, and snippets.

@agam
Created November 26, 2013 22:50
Show Gist options
  • Select an option

  • Save agam/7667742 to your computer and use it in GitHub Desktop.

Select an option

Save agam/7667742 to your computer and use it in GitHub Desktop.
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <limits>
#include <string>
#include <vector>
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/StreamSocket.h"
using namespace std;
double Series(unsigned int digit, int j) {
double termsum = 0.0;
for (int k = 0; k < digit; k++) {
double numerator = pow(16.0, digit - k);
double denominator = (8 * k + j);
termsum += (numerator / denominator);
termsum -= floor(termsum);
}
for (int k = digit; ; k++) {
double numerator = 1.0;
double denominator = (8 * k + j) * pow(16, k - digit);
double fraction = numerator / denominator;
if (fraction - 0.0 < 1e-32) break;
termsum += (numerator / denominator);
termsum -= floor(termsum);
}
return termsum;
}
double ComputePiDigit(unsigned int digit) {
double value = (4 * Series(digit, 1) -
2 * Series(digit, 4) -
1 * Series(digit, 5) -
1 * Series(digit, 6));
value = value - (unsigned long long) value + 1.0;
return value;
}
// Special case for very first client connection: digitNum == -1
// Value has valid hex range, or else '1000'
struct PiState {
int digitNum;
unsigned int value;
};
int main(int argc, char **argv) {
cout << "Connecting to " << argv[1] << ":" << argv[2] << endl;
static const int kMaxDigits = 250;
// Connect to the server, work with upto 10000 digits, then stop.
Poco::Net::SocketAddress sa(argv[1], atoi(argv[2]));
PiState my_pi_state;
// First request is special
my_pi_state.digitNum = -1;;
my_pi_state.value = 1000;
while (my_pi_state.digitNum < kMaxDigits) {
Poco::Net::StreamSocket socket(sa);
socket.setReceiveTimeout(100000);
// contact server, give current result, get new digit to compute
char bufstr[10];
snprintf(bufstr, 10, "%d-%u", my_pi_state.digitNum, my_pi_state.value);
socket.sendBytes(bufstr, 10);
socket.receiveBytes(bufstr, 10);
sscanf(bufstr, "*%d*", &my_pi_state.digitNum);
double calculated_value = ComputePiDigit(my_pi_state.digitNum);
// common case: compute the current digit and send it to the server
cout << "Digit: " << dec << my_pi_state.digitNum << "...";
float hexval = fabs(calculated_value);
my_pi_state.value =
static_cast<unsigned int>(16.0 * (hexval - floor(hexval)));
cout << "Value: " << hex << my_pi_state.value << endl;
// Anti-performance, but we want to work slowly here so I can start up
// multiple clients and show their interleaved output :)
sleep(1);
}
cout << "Pi Client exiting ..." << endl << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment