JAVASCRIPT 27
Fraction.js Guest on 20th April 2021 04:48:26 PM
  1. /**
  2.  * @license Fraction.js v4.0.12 09/09/2015
  3.  * http://www.xarg.org/2014/03/rational-numbers-in-javascript/
  4.  *
  5.  * Copyright (c) 2015, Robert Eisele (robert@xarg.org)
  6.  * Dual licensed under the MIT or GPL Version 2 licenses.
  7.  **/
  8.  
  9.  
  10. /**
  11.  *
  12.  * This class offers the possibility to calculate fractions.
  13.  * You can pass a fraction in different formats. Either as array, as double, as string or as an integer.
  14.  *
  15.  * Array/Object form
  16.  * [ 0 => <nominator>, 1 => <denominator> ]
  17.  * [ n => <nominator>, d => <denominator> ]
  18.  *
  19.  * Integer form
  20.  * - Single integer value
  21.  *
  22.  * Double form
  23.  * - Single double value
  24.  *
  25.  * String form
  26.  * 123.456 - a simple double
  27.  * 123/456 - a string fraction
  28.  * 123.'456' - a double with repeating decimal places
  29.  * 123.(456) - synonym
  30.  * 123.45'6' - a double with repeating last place
  31.  * 123.45(6) - synonym
  32.  *
  33.  * Example:
  34.  *
  35.  * var f = new Fraction("9.4'31'");
  36.  * f.mul([-4, 3]).div(4.9);
  37.  *
  38.  */
  39.  
  40. (function(root) {
  41.  
  42.   "use strict";
  43.  
  44.   // Maximum search depth for cyclic rational numbers. 2000 should be more than enough.
  45.   // Example: 1/7 = 0.(142857) has 6 repeating decimal places.
  46.   // If MAX_CYCLE_LEN gets reduced, long cycles will not be detected and toString() only gets the first 10 digits
  47.   var MAX_CYCLE_LEN = 2000;
  48.  
  49.   // Parsed data to avoid calling "new" all the time
  50.   var P = {
  51.     "s": 1,
  52.     "n": 0,
  53.     "d": 1
  54.   };
  55.  
  56.   function createError(name) {
  57.  
  58.     function errorConstructor() {
  59.       var temp = Error.apply(this, arguments);
  60.       temp['name'] = this['name'] = name;
  61.       this['stack'] = temp['stack'];
  62.       this['message'] = temp['message'];
  63.     }
  64.  
  65.     /**
  66.      * Error constructor
  67.      *
  68.      * @constructor
  69.      */
  70.     function IntermediateInheritor() { }
  71.     IntermediateInheritor.prototype = Error.prototype;
  72.     errorConstructor.prototype = new IntermediateInheritor();
  73.  
  74.     return errorConstructor;
  75.   }
  76.  
  77.   var DivisionByZero = Fraction['DivisionByZero'] = createError('DivisionByZero');
  78.   var InvalidParameter = Fraction['InvalidParameter'] = createError('InvalidParameter');
  79.  
  80.   function assign(n, s) {
  81.  
  82.     if (isNaN(n = parseInt(n, 10))) {
  83.       throwInvalidParam();
  84.     }
  85.     return n * s;
  86.   }
  87.  
  88.   function throwInvalidParam() {
  89.     throw new InvalidParameter();
  90.   }
  91.  
  92.   var parse = function(p1, p2) {
  93.  
  94.     var n = 0, d = 1, s = 1;
  95.     var v = 0, w = 0, x = 0, y = 1, z = 1;
  96.  
  97.     var A = 0, B = 1;
  98.     var C = 1, D = 1;
  99.  
  100.     var N = 10000000;
  101.     var M;
  102.  
  103.     if (p1 === undefined || p1 === null) {
  104.       /* void */
  105.     } else if (p2 !== undefined) {
  106.       n = p1;
  107.       d = p2;
  108.       s = n * d;
  109.     } else
  110.       switch (typeof p1) {
  111.  
  112.         case "object":
  113.           {
  114.             if ("d" in p1 && "n" in p1) {
  115.               n = p1["n"];
  116.               d = p1["d"];
  117.               if ("s" in p1)
  118.                 n *= p1["s"];
  119.             } else if (0 in p1) {
  120.               n = p1[0];
  121.               if (1 in p1)
  122.                 d = p1[1];
  123.             } else {
  124.               throwInvalidParam();
  125.             }
  126.             s = n * d;
  127.             break;
  128.           }
  129.         case "number":
  130.           {
  131.             if (p1 < 0) {
  132.               s = p1;
  133.               p1 = -p1;
  134.             }
  135.  
  136.             if (p1 % 1 === 0) {
  137.               n = p1;
  138.             } else if (p1 > 0) { // check for != 0, scale would become NaN (log(0)), which converges really slow
  139.  
  140.               if (p1 >= 1) {
  141.                 z = Math.pow(10, Math.floor(1 + Math.log(p1) / Math.LN10));
  142.                 p1 /= z;
  143.               }
  144.  
  145.               // Using Farey Sequences
  146.               // http://www.johndcook.com/blog/2010/10/20/best-rational-approximation/
  147.  
  148.               while (B <= N && D <= N) {
  149.                 M = (A + C) / (B + D);
  150.  
  151.                 if (p1 === M) {
  152.                   if (B + D <= N) {
  153.                     n = A + C;
  154.                     d = B + D;
  155.                   } else if (D > B) {
  156.                     n = C;
  157.                     d = D;
  158.                   } else {
  159.                     n = A;
  160.                     d = B;
  161.                   }
  162.                   break;
  163.  
  164.                 } else {
  165.  
  166.                   if (p1 > M) {
  167.                     A += C;
  168.                     B += D;
  169.                   } else {
  170.                     C += A;
  171.                     D += B;
  172.                   }
  173.  
  174.                   if (B > N) {
  175.                     n = C;
  176.                     d = D;
  177.                   } else {
  178.                     n = A;
  179.                     d = B;
  180.                   }
  181.                 }
  182.               }
  183.               n *= z;
  184.             } else if (isNaN(p1) || isNaN(p2)) {
  185.               d = n = NaN;
  186.             }
  187.             break;
  188.           }
  189.         case "string":
  190.           {
  191.             B = p1.match(/\d+|./g);
  192.  
  193.             if (B === null)
  194.               throwInvalidParam();
  195.  
  196.             if (B[A] === '-') {// Check for minus sign at the beginning
  197.               s = -1;
  198.               A++;
  199.             } else if (B[A] === '+') {// Check for plus sign at the beginning
  200.               A++;
  201.             }
  202.  
  203.             if (B.length === A + 1) { // Check if it's just a simple number "1234"
  204.               w = assign(B[A++], s);
  205.             } else if (B[A + 1] === '.' || B[A] === '.') { // Check if it's a decimal number
  206.  
  207.               if (B[A] !== '.') { // Handle 0.5 and .5
  208.                 v = assign(B[A++], s);
  209.               }
  210.               A++;
  211.  
  212.               // Check for decimal places
  213.               if (A + 1 === B.length || B[A + 1] === '(' && B[A + 3] === ')' || B[A + 1] === "'" && B[A + 3] === "'") {
  214.                 w = assign(B[A], s);
  215.                 y = Math.pow(10, B[A].length);
  216.                 A++;
  217.               }
  218.  
  219.               // Check for repeating places
  220.               if (B[A] === '(' && B[A + 2] === ')' || B[A] === "'" && B[A + 2] === "'") {
  221.                 x = assign(B[A + 1], s);
  222.                 z = Math.pow(10, B[A + 1].length) - 1;
  223.                 A += 3;
  224.               }
  225.  
  226.             } else if (B[A + 1] === '/' || B[A + 1] === ':') { // Check for a simple fraction "123/456" or "123:456"
  227.               w = assign(B[A], s);
  228.               y = assign(B[A + 2], 1);
  229.               A += 3;
  230.             } else if (B[A + 3] === '/' && B[A + 1] === ' ') { // Check for a complex fraction "123 1/2"
  231.               v = assign(B[A], s);
  232.               w = assign(B[A + 2], s);
  233.               y = assign(B[A + 4], 1);
  234.               A += 5;
  235.             }
  236.  
  237.             if (B.length <= A) { // Check for more tokens on the stack
  238.               d = y * z;
  239.               s = /* void */
  240.               n = x + d * v + z * w;
  241.               break;
  242.             }
  243.  
  244.             /* Fall through on error */
  245.           }
  246.         default:
  247.           throwInvalidParam();
  248.       }
  249.  
  250.     if (d === 0) {
  251.       throw new DivisionByZero();
  252.     }
  253.  
  254.     P["s"] = s < 0 ? -1 : 1;
  255.     P["n"] = Math.abs(n);
  256.     P["d"] = Math.abs(d);
  257.   };
  258.  
  259.   function modpow(b, e, m) {
  260.  
  261.     var r = 1;
  262.     for (; e > 0; b = (b * b) % m, e >>= 1) {
  263.  
  264.       if (e & 1) {
  265.         r = (r * b) % m;
  266.       }
  267.     }
  268.     return r;
  269.   }
  270.  
  271.  
  272.   function cycleLen(n, d) {
  273.  
  274.     for (; d % 2 === 0;
  275.       d /= 2) {
  276.     }
  277.  
  278.     for (; d % 5 === 0;
  279.       d /= 5) {
  280.     }
  281.  
  282.     if (d === 1) // Catch non-cyclic numbers
  283.       return 0;
  284.  
  285.     // If we would like to compute really large numbers quicker, we could make use of Fermat's little theorem:
  286.     // 10^(d-1) % d == 1
  287.     // However, we don't need such large numbers and MAX_CYCLE_LEN should be the capstone,
  288.     // as we want to translate the numbers to strings.
  289.  
  290.     var rem = 10 % d;
  291.     var t = 1;
  292.  
  293.     for (; rem !== 1; t++) {
  294.       rem = rem * 10 % d;
  295.  
  296.       if (t > MAX_CYCLE_LEN)
  297.         return 0; // Returning 0 here means that we don't print it as a cyclic number. It's likely that the answer is `d-1`
  298.     }
  299.     return t;
  300.   }
  301.  
  302.  
  303.   function cycleStart(n, d, len) {
  304.  
  305.     var rem1 = 1;
  306.     var rem2 = modpow(10, len, d);
  307.  
  308.     for (var t = 0; t < 300; t++) { // s < ~log10(Number.MAX_VALUE)
  309.       // Solve 10^s == 10^(s+t) (mod d)
  310.  
  311.       if (rem1 === rem2)
  312.         return t;
  313.  
  314.       rem1 = rem1 * 10 % d;
  315.       rem2 = rem2 * 10 % d;
  316.     }
  317.     return 0;
  318.   }
  319.  
  320.   function gcd(a, b) {
  321.  
  322.     if (!a)
  323.       return b;
  324.     if (!b)
  325.       return a;
  326.  
  327.     while (1) {
  328.       a %= b;
  329.       if (!a)
  330.         return b;
  331.       b %= a;
  332.       if (!b)
  333.         return a;
  334.     }
  335.   };
  336.  
  337.   /**
  338.    * Module constructor
  339.    *
  340.    * @constructor
  341.    * @param {number|Fraction=} a
  342.    * @param {number=} b
  343.    */
  344.   function Fraction(a, b) {
  345.  
  346.     if (!(this instanceof Fraction)) {
  347.       return new Fraction(a, b);
  348.     }
  349.  
  350.     parse(a, b);
  351.  
  352.     if (Fraction['REDUCE']) {
  353.       a = gcd(P["d"], P["n"]); // Abuse a
  354.     } else {
  355.       a = 1;
  356.     }
  357.  
  358.     this["s"] = P["s"];
  359.     this["n"] = P["n"] / a;
  360.     this["d"] = P["d"] / a;
  361.   }
  362.  
  363.   /**
  364.    * Boolean global variable to be able to disable automatic reduction of the fraction
  365.    *
  366.    */
  367.   Fraction['REDUCE'] = 1;
  368.  
  369.   Fraction.prototype = {
  370.  
  371.     "s": 1,
  372.     "n": 0,
  373.     "d": 1,
  374.  
  375.     /**
  376.      * Calculates the absolute value
  377.      *
  378.      * Ex: new Fraction(-4).abs() => 4
  379.      **/
  380.     "abs": function() {
  381.  
  382.       return new Fraction(this["n"], this["d"]);
  383.     },
  384.  
  385.     /**
  386.      * Inverts the sign of the current fraction
  387.      *
  388.      * Ex: new Fraction(-4).neg() => 4
  389.      **/
  390.     "neg": function() {
  391.  
  392.       return new Fraction(-this["s"] * this["n"], this["d"]);
  393.     },
  394.  
  395.     /**
  396.      * Adds two rational numbers
  397.      *
  398.      * Ex: new Fraction({n: 2, d: 3}).add("14.9") => 467 / 30
  399.      **/
  400.     "add": function(a, b) {
  401.  
  402.       parse(a, b);
  403.       return new Fraction(
  404.         this["s"] * this["n"] * P["d"] + P["s"] * this["d"] * P["n"],
  405.         this["d"] * P["d"]
  406.       );
  407.     },
  408.  
  409.     /**
  410.      * Subtracts two rational numbers
  411.      *
  412.      * Ex: new Fraction({n: 2, d: 3}).add("14.9") => -427 / 30
  413.      **/
  414.     "sub": function(a, b) {
  415.  
  416.       parse(a, b);
  417.       return new Fraction(
  418.         this["s"] * this["n"] * P["d"] - P["s"] * this["d"] * P["n"],
  419.         this["d"] * P["d"]
  420.       );
  421.     },
  422.  
  423.     /**
  424.      * Multiplies two rational numbers
  425.      *
  426.      * Ex: new Fraction("-17.(345)").mul(3) => 5776 / 111
  427.      **/
  428.     "mul": function(a, b) {
  429.  
  430.       parse(a, b);
  431.       return new Fraction(
  432.         this["s"] * P["s"] * this["n"] * P["n"],
  433.         this["d"] * P["d"]
  434.       );
  435.     },
  436.  
  437.     /**
  438.      * Divides two rational numbers
  439.      *
  440.      * Ex: new Fraction("-17.(345)").inverse().div(3)
  441.      **/
  442.     "div": function(a, b) {
  443.  
  444.       parse(a, b);
  445.       return new Fraction(
  446.         this["s"] * P["s"] * this["n"] * P["d"],
  447.         this["d"] * P["n"]
  448.       );
  449.     },
  450.  
  451.     /**
  452.      * Clones the actual object
  453.      *
  454.      * Ex: new Fraction("-17.(345)").clone()
  455.      **/
  456.     "clone": function() {
  457.       return new Fraction(this);
  458.     },
  459.  
  460.     /**
  461.      * Calculates the modulo of two rational numbers - a more precise fmod
  462.      *
  463.      * Ex: new Fraction('4.(3)').mod([7, 8]) => (13/3) % (7/8) = (5/6)
  464.      **/
  465.     "mod": function(a, b) {
  466.  
  467.       if (isNaN(this['n']) || isNaN(this['d'])) {
  468.         return new Fraction(NaN);
  469.       }
  470.  
  471.       if (a === undefined) {
  472.         return new Fraction(this["s"] * this["n"] % this["d"], 1);
  473.       }
  474.  
  475.       parse(a, b);
  476.       if (0 === P["n"] && 0 === this["d"]) {
  477.         Fraction(0, 0); // Throw DivisionByZero
  478.       }
  479.  
  480.       /*
  481.        * First silly attempt, kinda slow
  482.        *
  483.        return that["sub"]({
  484.        "n": num["n"] * Math.floor((this.n / this.d) / (num.n / num.d)),
  485.        "d": num["d"],
  486.        "s": this["s"]
  487.        });*/
  488.  
  489.       /*
  490.        * New attempt: a1 / b1 = a2 / b2 * q + r
  491.        * => b2 * a1 = a2 * b1 * q + b1 * b2 * r
  492.        * => (b2 * a1 % a2 * b1) / (b1 * b2)
  493.        */
  494.       return new Fraction(
  495.         this["s"] * (P["d"] * this["n"]) % (P["n"] * this["d"]),
  496.         P["d"] * this["d"]
  497.       );
  498.     },
  499.  
  500.     /**
  501.      * Calculates the fractional gcd of two rational numbers
  502.      *
  503.      * Ex: new Fraction(5,8).gcd(3,7) => 1/56
  504.      */
  505.     "gcd": function(a, b) {
  506.  
  507.       parse(a, b);
  508.  
  509.       // gcd(a / b, c / d) = gcd(a, c) / lcm(b, d)
  510.  
  511.       return new Fraction(gcd(P["n"], this["n"]) * gcd(P["d"], this["d"]), P["d"] * this["d"]);
  512.     },
  513.  
  514.     /**
  515.      * Calculates the fractional lcm of two rational numbers
  516.      *
  517.      * Ex: new Fraction(5,8).lcm(3,7) => 15
  518.      */
  519.     "lcm": function(a, b) {
  520.  
  521.       parse(a, b);
  522.  
  523.       // lcm(a / b, c / d) = lcm(a, c) / gcd(b, d)
  524.  
  525.       if (P["n"] === 0 && this["n"] === 0) {
  526.         return new Fraction;
  527.       }
  528.       return new Fraction(P["n"] * this["n"], gcd(P["n"], this["n"]) * gcd(P["d"], this["d"]));
  529.     },
  530.  
  531.     /**
  532.      * Calculates the ceil of a rational number
  533.      *
  534.      * Ex: new Fraction('4.(3)').ceil() => (5 / 1)
  535.      **/
  536.     "ceil": function(places) {
  537.  
  538.       places = Math.pow(10, places || 0);
  539.  
  540.       if (isNaN(this["n"]) || isNaN(this["d"])) {
  541.         return new Fraction(NaN);
  542.       }
  543.       return new Fraction(Math.ceil(places * this["s"] * this["n"] / this["d"]), places);
  544.     },
  545.  
  546.     /**
  547.      * Calculates the floor of a rational number
  548.      *
  549.      * Ex: new Fraction('4.(3)').floor() => (4 / 1)
  550.      **/
  551.     "floor": function(places) {
  552.  
  553.       places = Math.pow(10, places || 0);
  554.  
  555.       if (isNaN(this["n"]) || isNaN(this["d"])) {
  556.         return new Fraction(NaN);
  557.       }
  558.       return new Fraction(Math.floor(places * this["s"] * this["n"] / this["d"]), places);
  559.     },
  560.  
  561.     /**
  562.      * Rounds a rational numbers
  563.      *
  564.      * Ex: new Fraction('4.(3)').round() => (4 / 1)
  565.      **/
  566.     "round": function(places) {
  567.  
  568.       places = Math.pow(10, places || 0);
  569.  
  570.       if (isNaN(this["n"]) || isNaN(this["d"])) {
  571.         return new Fraction(NaN);
  572.       }
  573.       return new Fraction(Math.round(places * this["s"] * this["n"] / this["d"]), places);
  574.     },
  575.  
  576.     /**
  577.      * Gets the inverse of the fraction, means numerator and denominator are exchanged
  578.      *
  579.      * Ex: new Fraction([-3, 4]).inverse() => -4 / 3
  580.      **/
  581.     "inverse": function() {
  582.  
  583.       return new Fraction(this["s"] * this["d"], this["n"]);
  584.     },
  585.  
  586.     /**
  587.      * Calculates the fraction to some integer exponent
  588.      *
  589.      * Ex: new Fraction(-1,2).pow(-3) => -8
  590.      */
  591.     "pow": function(m) {
  592.  
  593.       if (m < 0) {
  594.         return new Fraction(Math.pow(this['s'] * this["d"], -m), Math.pow(this["n"], -m));
  595.       } else {
  596.         return new Fraction(Math.pow(this['s'] * this["n"], m), Math.pow(this["d"], m));
  597.       }
  598.     },
  599.  
  600.     /**
  601.      * Check if two rational numbers are the same
  602.      *
  603.      * Ex: new Fraction(19.6).equals([98, 5]);
  604.      **/
  605.     "equals": function(a, b) {
  606.  
  607.       parse(a, b);
  608.       return this["s"] * this["n"] * P["d"] === P["s"] * P["n"] * this["d"]; // Same as compare() === 0
  609.     },
  610.  
  611.     /**
  612.      * Check if two rational numbers are the same
  613.      *
  614.      * Ex: new Fraction(19.6).equals([98, 5]);
  615.      **/
  616.     "compare": function(a, b) {
  617.  
  618.       parse(a, b);
  619.       var t = (this["s"] * this["n"] * P["d"] - P["s"] * P["n"] * this["d"]);
  620.       return (0 < t) - (t < 0);
  621.     },
  622.  
  623.     "simplify": function(eps) {
  624.  
  625.       // First naive implementation, needs improvement
  626.  
  627.       if (isNaN(this['n']) || isNaN(this['d'])) {
  628.         return this;
  629.       }
  630.  
  631.       var cont = this['abs']()['toContinued']();
  632.  
  633.       eps = eps || 0.001;
  634.  
  635.       function rec(a) {
  636.         if (a.length === 1)
  637.           return new Fraction(a[0]);
  638.         return rec(a.slice(1))['inverse']()['add'](a[0]);
  639.       }
  640.  
  641.       for (var i = 0; i < cont.length; i++) {
  642.         var tmp = rec(cont.slice(0, i + 1));
  643.         if (tmp['sub'](this['abs']())['abs']().valueOf() < eps) {
  644.           return tmp['mul'](this['s']);
  645.         }
  646.       }
  647.       return this;
  648.     },
  649.  
  650.     /**
  651.      * Check if two rational numbers are divisible
  652.      *
  653.      * Ex: new Fraction(19.6).divisible(1.5);
  654.      */
  655.     "divisible": function(a, b) {
  656.  
  657.       parse(a, b);
  658.       return !(!(P["n"] * this["d"]) || ((this["n"] * P["d"]) % (P["n"] * this["d"])));
  659.     },
  660.  
  661.     /**
  662.      * Returns a decimal representation of the fraction
  663.      *
  664.      * Ex: new Fraction("100.'91823'").valueOf() => 100.91823918239183
  665.      **/
  666.     'valueOf': function() {
  667.  
  668.       return this["s"] * this["n"] / this["d"];
  669.     },
  670.  
  671.     /**
  672.      * Returns a string-fraction representation of a Fraction object
  673.      *
  674.      * Ex: new Fraction("1.'3'").toFraction() => "4 1/3"
  675.      **/
  676.     'toFraction': function(excludeWhole) {
  677.  
  678.       var whole, str = "";
  679.       var n = this["n"];
  680.       var d = this["d"];
  681.       if (this["s"] < 0) {
  682.         str += '-';
  683.       }
  684.  
  685.       if (d === 1) {
  686.         str += n;
  687.       } else {
  688.  
  689.         if (excludeWhole && (whole = Math.floor(n / d)) > 0) {
  690.           str += whole;
  691.           str += " ";
  692.           n %= d;
  693.         }
  694.  
  695.         str += n;
  696.         str += '/';
  697.         str += d;
  698.       }
  699.       return str;
  700.     },
  701.  
  702.     /**
  703.      * Returns a latex representation of a Fraction object
  704.      *
  705.      * Ex: new Fraction("1.'3'").toLatex() => "\frac{4}{3}"
  706.      **/
  707.     'toLatex': function(excludeWhole) {
  708.  
  709.       var whole, str = "";
  710.       var n = this["n"];
  711.       var d = this["d"];
  712.       if (this["s"] < 0) {
  713.         str += '-';
  714.       }
  715.  
  716.       if (d === 1) {
  717.         str += n;
  718.       } else {
  719.  
  720.         if (excludeWhole && (whole = Math.floor(n / d)) > 0) {
  721.           str += whole;
  722.           n %= d;
  723.         }
  724.  
  725.         str += "\\frac{";
  726.         str += n;
  727.         str += '}{';
  728.         str += d;
  729.         str += '}';
  730.       }
  731.       return str;
  732.     },
  733.  
  734.     /**
  735.      * Returns an array of continued fraction elements
  736.      *
  737.      * Ex: new Fraction("7/8").toContinued() => [0,1,7]
  738.      */
  739.     'toContinued': function() {
  740.  
  741.       var t;
  742.       var a = this['n'];
  743.       var b = this['d'];
  744.       var res = [];
  745.  
  746.       if (isNaN(a) || isNaN(b)) {
  747.         return res;
  748.       }
  749.  
  750.       do {
  751.         res.push(Math.floor(a / b));
  752.         t = a % b;
  753.         a = b;
  754.         b = t;
  755.       } while (a !== 1);
  756.  
  757.       return res;
  758.     },
  759.  
  760.     /**
  761.      * Creates a string representation of a fraction with all digits
  762.      *
  763.      * Ex: new Fraction("100.'91823'").toString() => "100.(91823)"
  764.      **/
  765.     'toString': function(dec) {
  766.  
  767.       var g;
  768.       var N = this["n"];
  769.       var D = this["d"];
  770.  
  771.       if (isNaN(N) || isNaN(D)) {
  772.         return "NaN";
  773.       }
  774.  
  775.       if (!Fraction['REDUCE']) {
  776.         g = gcd(N, D);
  777.         N /= g;
  778.         D /= g;
  779.       }
  780.  
  781.       dec = dec || 15; // 15 = decimal places when no repitation
  782.  
  783.       var cycLen = cycleLen(N, D); // Cycle length
  784.       var cycOff = cycleStart(N, D, cycLen); // Cycle start
  785.  
  786.       var str = this['s'] === -1 ? "-" : "";
  787.  
  788.       str += N / D | 0;
  789.  
  790.       N %= D;
  791.       N *= 10;
  792.  
  793.       if (N)
  794.         str += ".";
  795.  
  796.       if (cycLen) {
  797.  
  798.         for (var i = cycOff; i--;) {
  799.           str += N / D | 0;
  800.           N %= D;
  801.           N *= 10;
  802.         }
  803.         str += "(";
  804.         for (var i = cycLen; i--;) {
  805.           str += N / D | 0;
  806.           N %= D;
  807.           N *= 10;
  808.         }
  809.         str += ")";
  810.       } else {
  811.         for (var i = dec; N && i--;) {
  812.           str += N / D | 0;
  813.           N %= D;
  814.           N *= 10;
  815.         }
  816.       }
  817.       return str;
  818.     }
  819.   };
  820.  
  821.   if (typeof define === "function" && define["amd"]) {
  822.     define([], function() {
  823.       return Fraction;
  824.     });
  825.   } else if (typeof exports === "object") {
  826.     Object.defineProperty(Fraction, "__esModule", { 'value': true });
  827.     Fraction['default'] = Fraction;
  828.     Fraction['Fraction'] = Fraction;
  829.     module['exports'] = Fraction;
  830.   } else {
  831.     root['Fraction'] = Fraction;
  832.   }
  833.  
  834. })(this);

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.