Fraction.js - ℚ in JavaScript
-
<h2>Fraction.js - ℚ in JavaScript</h2>
<p><a href="upload://nVGfF0lVnvmkQJgPYtAwmBO1Lcp.svg"><img src="https://npmjs.org/package/fraction.js "View this project on npm"" alt="NPM Package</a>"></p>
<p><a href="upload://htIhYxu9Zv4NLwcFjeH6LBexRWC.svg"><img src="http://opensource.org/licenses/MIT" alt="MIT license</a>"></p><p>Tired of inprecise numbers represented by doubles, which have to store rational and irrational numbers like PI or sqrt(2) the same way? Obviously the following problem is preventable:</p>
<pre><code>
1 / 98 * 98 // = 0.9999999999999999
</code></pre><p>If you need more precision or just want a fraction as a result, just include <em>Fraction.js</em>:</p>
<pre><code>
var Fraction = require('fraction.js');
// or
import Fraction from 'fraction.js';
</code></pre><p>and give it a trial:</p>
<pre><code>
Fraction(1).div(98).mul(98) // = 1
</code></pre><p>Internally, numbers are represented as <em>numerator / denominator</em>, which adds just a little overhead. However, the library is written with performance and accuracy in mind, which makes it the perfect basis for <a href="https://github.com/infusion/Polynomial.js">Polynomial.js</a> and <a href="https://github.com/josdejong/mathjs">Math.js</a>.</p>
<p>Convert decimal to fraction</p>
<p>===</p>
<p>The simplest job for fraction.js is to get a fraction out of a decimal:</p>
<pre><code>
var x = new Fraction(1.88);
var res = x.toFraction(true); // String "1 22/25"
</code></pre><p>Examples / Motivation</p>
<p>===</p>
<p>A simple example might be</p><pre><code>
var f = new Fraction("9.4'31'"); // 9.4313131313131...
f.mul([-4, 3]).mod("4.'8'"); // 4.88888888888888...
</code></pre>
<p>The result is</p><pre><code>
console.log(f.toFraction()); // -4154 / 1485
</code></pre>
<p>You could of course also access the sign (s), numerator (n) and denominator (d) on your own:</p>
<pre><code>
f.s * f.n / f.d = -1 * 4154 / 1485 = -2.797306...
</code></pre><p>If you would try to calculate it yourself, you would come up with something like:</p>
<pre><code>
(9.4313131 * (-4 / 3)) % 4.888888 = -2.797308133...
</code></pre><p>Quite okay, but yea - not as accurate as it could be.</p>
<p>Laplace Probability</p>
<p>===</p>
<p>Simple example. What's the probability of throwing a 3, and 1 or 4, and 2 or 4 or 6 with a fair dice?</p><p>P({3}):</p>
<pre><code>
var p = new Fraction([3].length, 6).toString(); // 0.1(6)
</code></pre><p>P({1, 4}):</p>
<pre><code>
var p = new Fraction([1, 4].length, 6).toString(); // 0.(3)
</code></pre><p>P({2, 4, 6}):</p>
<pre><code>
var p = new Fraction([2, 4, 6].length, 6).toString(); // 0.5
</code></pre><p>Convert degrees/minutes/seconds to precise rational representation:</p>
<p>===</p><p>57+45/60+17/3600</p>
<pre><code>
var deg = 57; // 57°
var min = 45; // 45 Minutes
var sec = 17; // 17 Secondsnew Fraction(deg).add(min, 60).add(sec, 3600).toString() // -> 57.7547(2)
</code></pre><p>Rational approximation of irrational numbers</p>
<p>===</p><p>Now it's getting messy ;d To approximate a number like <em>sqrt(5) - 2</em> with a numerator and denominator, you can reformat the equation as follows: <em>pow(n / d + 2, 2) = 5</em>.</p>
<p>Then the following algorithm will generate the rational number besides the binary representation.</p>
<pre><code>
var x = "/", s = "";var a = new Fraction(0),
b = new Fraction(1);
for (var n = 0; n <= 10; n++) {var c = a.add(b).div(2);
console.log(n + "\t" + a + "\t" + b + "\t" + c + "\t" + x);
if (c.add(2).pow(2) < 5) {
a = c;
x = "1";
} else {
b = c;
x = "0";
}
s+= x;
}
console.log(s)
</code></pre><p>The result is</p>
<pre><code>
n a[n] b[n] c[n] x[n]
0 0/1 1/1 1/2 /
1 0/1 1/2 1/4 0
2 0/1 1/4 1/8 0
3 1/8 1/4 3/16 1
4 3/16 1/4
新手建议收藏,老手欢迎指点。
</code></pre>