// g++ -lgmpxx -lgmp #include <gmpxx.h> #include <string> #include <iostream> #include <ctime> #include <cerrno> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> mpq_class now() { struct timespec t; if (clock_gettime(CLOCK_MONOTONIC, &t)) { throw std::runtime_error(std::strerror(errno)); } return t.tv_sec + mpq_class(t.tv_nsec) / 1000000000; } class Measurer { public: Measurer(char const * input_filename) : current_time(0), fd(open(input_filename, O_RDONLY)) { } ~Measurer() { close(fd); } void measure() { last_time = current_time; last_value = current_value; lseek(fd, 0, SEEK_SET); int len = read(fd, buf, sizeof(buf)); buf[len] = 0; if (buf[len-1] == '\n') { buf[len-1] = 0; } current_time = now(); current_value = buf; if (last_time != 0) { time_change = current_time - last_time; accumulated_time += time_change * 2; accumulated_timevalues += time_change * (last_value + current_value); } } mpq_class value() { return accumulated_timevalues / accumulated_time; } mpq_class & time() { return last_time; } private: int fd; mpq_class last_time; mpq_class last_value; mpq_class current_time; mpq_class current_value; mpq_class time_change; mpq_class accumulated_time; mpq_class accumulated_timevalues; char buf[1024]; }; int main(int argc, char **argv) { if (argc != 2) { std::cout << "Usage: " << argv[0] << " filepath-containing-a-changing-number" << std::endl; return -1; } Measurer measurer(argv[1]); mpq_class start_time = now(); while ("reading numbers from filepath") { measurer.measure(); if (start_time + 1 <= measurer.time()) { std::cout << "Average: " << measurer.value().get_d() << std::endl; start_time += 1; } } }