frac.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. /* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */
  2. var frac = function frac(x, D, mixed) {
  3. var n1 = Math.floor(x), d1 = 1;
  4. var n2 = n1+1, d2 = 1;
  5. if(x !== n1) while(d1 <= D && d2 <= D) {
  6. var m = (n1 + n2) / (d1 + d2);
  7. if(x === m) {
  8. if(d1 + d2 <= D) { d1+=d2; n1+=n2; d2=D+1; }
  9. else if(d1 > d2) d2=D+1;
  10. else d1=D+1;
  11. break;
  12. }
  13. else if(x < m) { n2 = n1+n2; d2 = d1+d2; }
  14. else { n1 = n1+n2; d1 = d1+d2; }
  15. }
  16. if(d1 > D) { d1 = d2; n1 = n2; }
  17. if(!mixed) return [0, n1, d1];
  18. var q = Math.floor(n1/d1);
  19. return [q, n1 - q*d1, d1];
  20. };
  21. frac.cont = function cont(x, D, mixed) {
  22. var sgn = x < 0 ? -1 : 1;
  23. var B = x * sgn;
  24. var P_2 = 0, P_1 = 1, P = 0;
  25. var Q_2 = 1, Q_1 = 0, Q = 0;
  26. var A = Math.floor(B);
  27. while(Q_1 < D) {
  28. A = Math.floor(B);
  29. P = A * P_1 + P_2;
  30. Q = A * Q_1 + Q_2;
  31. if((B - A) < 0.00000005) break;
  32. B = 1 / (B - A);
  33. P_2 = P_1; P_1 = P;
  34. Q_2 = Q_1; Q_1 = Q;
  35. }
  36. if(Q > D) { if(Q_1 > D) { Q = Q_2; P = P_2; } else { Q = Q_1; P = P_1; } }
  37. if(!mixed) return [0, sgn * P, Q];
  38. var q = Math.floor(sgn * P/Q);
  39. return [q, sgn*P - q*Q, Q];
  40. };
  41. // eslint-disable-next-line no-undef
  42. if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac;