package com.github.valodzka.frac;

import java.io.IOException; import java.lang.IllegalArgumentException;

import org.jruby.Ruby; import org.jruby.anno.JRubyMethod;

public class frac_ext {

@JRubyMethod
public static double[] find_fracs(double rv, long dv)
{
  long m[][] = new long[2][2];
  long ai;
  long maxden = dv;
  double startx = rv;
  double x = rv;

  int sign = 1;

  if (maxden <= 0) {
    throw new IllegalArgumentException("maximum denominator should be > 0");
  }

  if (x < 0) {
    sign = -1;
    x = -x;
  }

  startx = x;

  /* initialize matrix */
  m[0][0] = m[1][1] = 1;
  m[0][1] = m[1][0] = 0;

  /* loop finding terms until denom gets too big */
  while (m[1][0] *  ( ai = (long) x ) + m[1][1] <= maxden) {
    long t;
    t = m[0][0] * ai + m[0][1];
    m[0][1] = m[0][0];
    m[0][0] = t;
    t = m[1][0] * ai + m[1][1];
    m[1][1] = m[1][0];
    m[1][0] = t;
    if(x == (long) ai) break;     // AF: division by zero
    x = 1/(x - ai);
    if(x > (double) 0x7FFFFFFF) break;  // AF: representation failure
  }

  {
    /* now remaining x is between 0 and 1/ai */
    /* approx as either 0 or 1/m where m is max that will fit in maxden */
    /* first try zero */
    double num1 = sign*m[0][0];
    double den1 = m[1][0];
    double err1 = startx - (m[0][0] / m[1][0]);

    /* now try other possibility */
    ai = (maxden - m[1][1]) / m[1][0];
    m[0][0] = m[0][0] * ai + m[0][1];
    m[1][0] = m[1][0] * ai + m[1][1];

    double num2 = sign*m[0][0];
    double den2 = m[1][0];
    double err2 = startx - (m[0][0] / m[1][0]);

    return new double[]{ num1, den1, err1, num2, den2, err2 };
  }

}

};