Security News
The Push to Ban Ransom Payments Is Gaining Momentum
Ransomware costs victims an estimated $30 billion per year and has gotten so out of control that global support for banning payments is gaining momentum.
fraction.js
Advanced tools
Package description
The fraction.js npm package is a library for handling fractional values in JavaScript. It allows for the creation, manipulation, and conversion of fractions, providing a way to perform arithmetic operations and comparisons with fractions.
Creating fractions
This feature allows for the creation of fraction instances from strings, numbers, or other fractions.
const Fraction = require('fraction.js');
let fraction = new Fraction('9/5');
Arithmetic operations
This feature enables the performance of arithmetic operations such as addition, subtraction, multiplication, and division between fractions.
let result = new Fraction(1, 2).add(new Fraction(1, 4));
Comparison operations
This feature allows for the comparison of fractions to check for equality, or to determine which is greater or less than the other.
let isEqual = new Fraction(1, 2).equals(new Fraction(2, 4));
Conversion to other formats
This feature provides methods to convert fractions to other formats, such as decimal values or strings.
let decimal = new Fraction(3, 4).valueOf();
Math.js is an extensive math library for JavaScript and Node.js, which supports fractions as well as a wide range of other mathematical functions and data types. It is more comprehensive than fraction.js but also larger in size.
Decimal.js is a library for arbitrary-precision decimal arithmetic. While it does not handle fractions directly, it can perform precise arithmetic operations which are useful when dealing with decimals that would otherwise be represented as fractions.
Big.js is a small, fast JavaScript library for arbitrary-precision arithmetic with big numbers. Like decimal.js, it does not handle fractions per se but is useful for high precision arithmetic.
Algebra.js is a library that includes fractions as part of its functionality to build and solve algebraic expressions. It provides a different approach by focusing on algebraic structures rather than just fractions.
Readme
Tired of inprecise numbers represented by doubles? Have a look at Fraction.js, which represents rational numbers or ratios as two integers in the form of n / d.
A simple example might be
var f = new Fraction("9.4'31'");
f.mul([-4, 3]).mod("4.'8'");
The result is
f.s * f.n / f.d = -1 * 4154 / 1485 = -2.797306...
If you would try to calculate it yourself, you would come up with something like:
(9.4313131 * (-4 / 3)) % 4.888888 = -2.797308133...
Quite okay, but yea - not as accurate as it could be.
To approximate a number like sqrt(5) - 2 as n / d, you can reformat the equation as follows: pow(n / d + 2, 2) is 5
The formulated algorithm, which also generates the binary representation, could look like
var x = "/", s = "";
var a = new Fraction(0),
b = new Fraction(1);
for (var n = 0; n <= 10; n++) {
var c = new Fraction(a).add(b).div(2);
console.log(n + "\t" + a.n + "/" + a.d + "\t" + b.n + "/" + b.d + "\t" + c.n + "/" + c.d + "\t" + x);
if (Math.pow(c.n / c.d + 2, 2) < 5) {
a = c;
x = "1";
} else {
b = c;
x = "0";
}
s+= x;
}
console.log(s)
The result is
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 7/32 1
5 7/32 1/4 15/64 1
6 15/64 1/4 31/128 1
7 15/64 31/128 61/256 0
8 15/64 61/256 121/512 0
9 15/64 121/512 241/1024 0
10 241/1024 121/512 483/2048 1
Thus the approximation after 11 iterations of the bisection method is 483 / 2048 and the binary representation is 0.00111100011 (see WolframAlpha)
I published another example on how to approximate PI with fraction.js on my blog.
var f = new Fraction("6.(3416)");
console.log("" + f.mod(1))
It turns out that Fraction.js outperforms almost any fmod() implementation, including JavaScript itself, C++, Python, Java and even Wolframalpha due to the fact that numbers like 0.05, 0.1, ... are infinite decimal in base 2.
The equation fmod(4.55, 0.05) gives 0.04999999999999957, wolframalpha says 1/20. The correct answer should be zero, as 0.05 divides 4.55 without any remainder.
Any function (see below) as well as the constructor of the Fraction class parses it's input and reduce it to the smallest term.
You can pass either Arrays, Objects, Integers, Doubles or Strings.
new Fraction(numerator, denumerator);
new Fraction([numerator, denumerator]);
new Fraction({n: numerator, d: denumerator});
new Fraction(123);
new Fraction(55.4);
Note: If you pass a double as it is, Fraction.js will perform a number analysis based on Farey Sequences. If you concern performance, cache Fraction.js objects and pass arrays/objects.
The method is really precise, but too large exact numbers, like 1234567.9991829 will result in a wrong approximation. If you want to keep the number as it is, convert it to a string, as the string parser will not perform any further approximation.
new Fraction("123.45");
new Fraction("123.'456'"); // Note the quotes, see below!
new Fraction("123.(456)"); // Note the brackets, see below!
new Fraction("123.45'6'"); // Note the quotes, see below!
new Fraction("123.45(6)"); // Note the brackets, see below!
Fraction.js can easily handle repeating decimal places. For example 1/3 is 0.3333.... There is only one repeating digit. As you can see in the examples above, you can pass a number like 1/3 as "0.'3'" or "0.(3)", which are synonym. There are no tests to parse something like 0.166666666 to 1/6! If you really want to handle this number, wrap around brackets on your own with the function below for example: 0.1(66666666)
Assume you want to divide 123.32 / 33.6(567). WolframAlpha states that you'll get a period of 1776 digits. Fraction.js comes to the same result. Give it a try:
var f = new Fraction("123.32");
console.log("Bam: " + f.div("33.6(567)"));
To automatically make a number like "0.123123123" to something more Fraction.js friendly like "0.(123)", I hacked this little brute force algorithm in a 10 minutes. Improvements are welcome...
function formatDecimal(str) {
var comma, pre, offset, pad, times, repeat;
if (-1 === (comma = str.indexOf(".")))
return str;
pre = str.substr(0, comma + 1);
str = str.substr(comma + 1);
for (var i = 0; i < str.length; i++) {
offset = str.substr(0, i);
for (var j = 0; j < 5; j++) {
pad = str.substr(i, j + 1);
times = Math.ceil((str.length - offset.length) / pad.length);
repeat = new Array(times + 1).join(pad); // Silly String.repeat hack
if (0 === (offset + repeat).indexOf(str)) {
return pre + offset + "(" + pad + ")";
}
}
}
return null;
}
var f, x = formatDecimal("13.0123123123"); // = 13.0(123)
if (x !== null) {
f = new Fraction(x);
}
Returns the actual number without any sign information
Returns the sum of the actual number and the parameter n
Returns the difference of the actual number and the parameter n
Returns the product of the actual number and the parameter n
Returns the quotient of the actual number and the parameter n
Set a number n to the actual object
Returns the modulus (rest of the division) of the actual object and n (this % n). It's a much more precise fmod() if you will.
Returns the reciprocal of the actual number (n / d becomes d / n)
Check if two numbers are equal
Check if two numbers are divisible (n divides this)
Returns a decimal representation of the fraction
Generates an exact string representation of the actual object, including repeating decimal places of any length.
If a really hard error occurs (parsing error, division by zero), fraction.js throws exceptions! Please make sure you handle them correctly.
Installing fraction.js is as easy as cloning this repo or use one of the following commands:
bower install fraction.js
or
npm install fraction.js
As every library I publish, fraction.js is also built to be as small as possible after compressing it with Google Closure Compiler in advanced mode. Thus the coding style orientates a little on maxing-out the compression rate. Please make sure you keep this style if you plan to extend the library.
If you plan to enhance the library, make sure you add test cases and all the previous tests are passing. You can test the library with
npm test
Copyright (c) 2014, Robert Eisele (robert@xarg.org) Dual licensed under the MIT or GPL Version 2 licenses.
FAQs
A rational number library
We found that fraction.js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Ransomware costs victims an estimated $30 billion per year and has gotten so out of control that global support for banning payments is gaining momentum.
Application Security
New SEC disclosure rules aim to enforce timely cyber incident reporting, but fear of job loss and inadequate resources lead to significant underreporting.
Security News
The Python Software Foundation has secured a 5-year sponsorship from Fastly that supports PSF's activities and events, most notably the security and reliability of the Python Package Index (PyPI).