Created
November 26, 2013 22:50
-
-
Save agam/7667742 to your computer and use it in GitHub Desktop.
Pi Compute Client for http://www.reddit.com/r/dailyprogrammer/comments/1qply1/111513_challenge_129_hard_baking_pi/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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