Try this:
#include <iostream>
#include <cmath>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#define TOLERANCE 0.0000001
using namespace std;
using namespace boost::posix_time;
bool active(true);
// just adjust the calc if this isn't the right formula
//
// EMI = [P x R x (1+R)^N] / [(1+R)^N-1]
//
double calc(double p, double r, double n) {
return p * r * pow(r + 1.0, n) / (pow(r + 1.0, n) - 1.0);
}
void timeout_loop() {
ptime start = microsec_clock::local_time();
time_duration timeout(seconds(10));
while(active) {
boost::this_thread::sleep(milliseconds(1));
if((microsec_clock::local_time() - start).total_milliseconds() > timeout.total_milliseconds()) {
cout << "timeout" << endl;
active = false;
}
}
}
int main() {
double p(50000.0);
double target(4368.0);
double n(12.0);
double min(0.0);
double max(1.0);
double current = (max + min) / 2.0;
boost::thread timeout_thread(timeout_loop);
while(active) {
double emi = calc(p, current, n);
if((target - emi) > TOLERANCE) {
min = current;
current = (max + min) / 2.0;
} else if((emi - target) > TOLERANCE) {
max = current;
current = (max + min) / 2.0;
} else {
cout << setprecision(12) << current << endl;
break;
}
}
active = false;
timeout_thread.join();
return 0;
}