Problem p00788 (C++)

Buggy submission (status: Runtime Error):
#include <cassert>
#include <cmath>
#include <iostream>
#include <set>
#include <vector>

using namespace std;

const double eps = 1e-11;

bool eq(double a, double b) { return abs(b - a) < eps; }

int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }

const double inf = 1e30;

int main() {
  int p, n;
  while (cin >> p >> n) {
    if (p == 0 && n == 0)
      break;
    double rp = sqrt(p);

    double min_diff_lower = inf;
    double min_diff_upper = inf;
    int ans_lower_p, ans_lower_q, ans_upper_p, ans_upper_q;

    for (int i = 1; i <= n; ++i) {
      int r = n;
      int l = 1;
      int cnt = 0;
      int m;
      while (cnt++ < 20) {
        m = (r + l) / 2;
        if ((double)m / i > rp) {
          r = m;
        } else {
          l = m;
        }
      }
      ++m;
      if ((double)m / i <= rp)
        --m;

      assert(rp - (double)m / i > 0);
      if (min_diff_lower > rp - (double)m / i) {
        min_diff_lower = rp - (double)m / i;
        ans_lower_p = m;
        ans_lower_q = i;
      }

      for (int j = m + 1; j <= n; ++j) {
        if ((double)j / i > rp) {
          m = j;
          break;
        }
      }

      if (((double)m / i - rp) > 0 && min_diff_upper > ((double)m / i - rp)) {
        min_diff_upper = (double)m / i - rp;
        ans_upper_p = m;
        ans_upper_q = i;
      }
    }

    int lower_gcd = gcd(ans_lower_p, ans_lower_q);
    int upper_gcd = gcd(ans_upper_p, ans_upper_q);
    ans_lower_p /= lower_gcd;
    ans_lower_q /= lower_gcd;

    ans_upper_p /= upper_gcd;
    ans_upper_q /= upper_gcd;

    cout << ans_upper_p << "/" << ans_upper_q << " " << ans_lower_p << "/"
         << ans_lower_q << endl;
  }

  return 0;
}

Fixed submission:
#include <cassert>
#include <cmath>
#include <iostream>
#include <set>
#include <vector>

using namespace std;

const double eps = 1e-11;

bool eq(double a, double b) { return abs(b - a) < eps; }

int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }

const double inf = 1e30;

int main() {
  int p, n;
  while (cin >> p >> n) {
    if (p == 0 && n == 0)
      break;
    double rp = sqrt(p);

    double min_diff_lower = inf;
    double min_diff_upper = inf;
    int ans_lower_p, ans_lower_q, ans_upper_p, ans_upper_q;

    for (int i = 1; i <= n; ++i) {
      int r = n;
      int l = 1;
      int cnt = 0;
      int m;
      while (cnt++ < 20) {
        m = (r + l) / 2;
        if ((double)m / i > rp) {
          r = m;
        } else {
          l = m;
        }
      }
      ++m;
      if (rp - (double)m / i < 0)
        --m;

      assert(rp - (double)m / i > 0);
      if (min_diff_lower > rp - (double)m / i) {
        min_diff_lower = rp - (double)m / i;
        ans_lower_p = m;
        ans_lower_q = i;
      }

      for (int j = m + 1; j <= n; ++j) {
        if ((double)j / i > rp) {
          m = j;
          break;
        }
      }

      if (((double)m / i - rp) > 0 && min_diff_upper > ((double)m / i - rp)) {
        min_diff_upper = (double)m / i - rp;
        ans_upper_p = m;
        ans_upper_q = i;
      }
    }

    int lower_gcd = gcd(ans_lower_p, ans_lower_q);
    int upper_gcd = gcd(ans_upper_p, ans_upper_q);
    ans_lower_p /= lower_gcd;
    ans_lower_q /= lower_gcd;

    ans_upper_p /= upper_gcd;
    ans_upper_q /= upper_gcd;

    cout << ans_upper_p << "/" << ans_upper_q << " " << ans_lower_p << "/"
         << ans_lower_q << endl;
  }

  return 0;
}