1653622503

# Fraction.js | A Rational Numbers Library Written in JavaScript

## Fraction.js - ℚ in JavaScript

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:

``````1 / 98 * 98 // = 0.9999999999999999
``````

If you need more precision or just want a fraction as a result, have a look at Fraction.js:

``````var Fraction = require('fraction.js');

Fraction(1).div(98).mul(98) // = 1
``````

Internally, numbers are represented as numerator / denominator, which adds just a little overhead. However, the library is written with performance in mind and outperforms any other implementation, as you can see here. This basic data-type makes it the perfect basis for Polynomial.js and Math.js.

## Convert decimal to fraction

The simplest job for fraction.js is to get a fraction out of a decimal:

``````var x = new Fraction(1.88);
var res = x.toFraction(true); // String "1 22/25"
``````

## Examples / Motivation

A simple example might be

``````var f = new Fraction("9.4'31'"); // 9.4313131313131...
f.mul([-4, 3]).mod("4.'8'"); // 4.88888888888888...
``````

The result is

``````console.log(f.toFraction()); // -4154 / 1485
``````

You could of course also access the sign (s), numerator (n) and denominator (d) on your own:

``````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.

## Laplace Probability

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({3}):

``````var p = new Fraction([3].length, 6).toString(); // 0.1(6)
``````

P({1, 4}):

``````var p = new Fraction([1, 4].length, 6).toString(); // 0.(3)
``````

P({2, 4, 6}):

``````var p = new Fraction([2, 4, 6].length, 6).toString(); // 0.5
``````

## Convert degrees/minutes/seconds to precise rational representation:

57+45/60+17/3600

``````var deg = 57; // 57°
var min = 45; // 45 Minutes
var sec = 17; // 17 Seconds

new Fraction(deg).add(min, 60).add(sec, 3600).toString() // -> 57.7547(2)
``````

## Rounding a fraction to the closest tape measure value

A tape measure is usually divided in parts of `1/16`. Rounding a given fraction to the closest value on a tape measure can be determined by

``````function closestTapeMeasure(frac) {

/*
k/16 ≤ a/b < (k+1)/16
⇔ k ≤ 16*a/b < (k+1)
⇔ k = floor(16*a/b)
*/
return new Fraction(Math.round(16 * Fraction(frac).valueOf()), 16);
}
// closestTapeMeasure("1/3") // 5/16
``````

## Rational approximation of irrational numbers

Now it's getting messy ;d To approximate a number like sqrt(5) - 2 with a numerator and denominator, you can reformat the equation as follows: pow(n / d + 2, 2) = 5.

Then the following algorithm will generate the rational number besides the binary representation.

``````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)
``````

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 (Still not the best idea to approximate irrational numbers, but it illustrates the capabilities of Fraction.js perfectly).

## Get the exact fractional part of a number

``````var f = new Fraction("-6.(3416)");
console.log("" + f.mod(1).abs()); // Will print 0.(3416)
``````

## Mathematical correct modulo

The behaviour on negative congruences is different to most modulo implementations in computer science. Even the mod() function of Fraction.js behaves in the typical way. To solve the problem of having the mathematical correct modulo with Fraction.js you could come up with this:

``````var a = -1;
var b = 10.99;

console.log(new Fraction(a)
.mod(b)); // Not correct, usual Modulo

console.log(new Fraction(a)
.mod(b).add(b).mod(b)); // Correct! Mathematical Modulo
``````

## fmod() impreciseness circumvented

It turns out that Fraction.js outperforms almost any fmod() implementation, including JavaScript itself, php.js, 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.

Parser

Any function (see below) as well as the constructor of the Fraction class parses its input and reduce it to the smallest term.

You can pass either Arrays, Objects, Integers, Doubles or Strings.

## Arrays / Objects

``````new Fraction(numerator, denominator);
new Fraction([numerator, denominator]);
new Fraction({n: numerator, d: denominator});
``````

## Integers

``````new Fraction(123);
``````

## Doubles

``````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 observations. If you have problems with the approximation, in the file `examples/approx.js` is a different approximation algorithm, which might work better in some more specific use-cases.

## Strings

``````new Fraction("123.45");
new Fraction("123/45"); // A rational number represented as two decimals, separated by a slash
new Fraction("123:45"); // A rational number represented as two decimals, separated by a colon
new Fraction("4 123/45"); // A rational number represented as a whole number and a fraction
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!
``````

## Two arguments

``````new Fraction(3, 2); // 3/2 = 1.5
``````

## Repeating decimal places

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);
}
``````

Attributes

The Fraction object allows direct access to the numerator, denominator and sign attributes. It is ensured that only the sign-attribute holds sign information so that a sign comparison is only necessary against this attribute.

``````var f = new Fraction('-1/2');
console.log(f.n); // Numerator: 1
console.log(f.d); // Denominator: 2
console.log(f.s); // Sign: -1
``````

## Functions

### Fraction abs()

Returns the actual number without any sign information

### Fraction neg()

Returns the actual number with flipped sign in order to get the additive inverse

Returns the sum of the actual number and the parameter n

### Fraction sub(n)

Returns the difference of the actual number and the parameter n

### Fraction mul(n)

Returns the product of the actual number and the parameter n

### Fraction div(n)

Returns the quotient of the actual number and the parameter n

### Fraction pow(exp)

Returns the power of the actual number, raised to an possible rational exponent. If the result becomes non-rational the function returns `null`.

### Fraction mod(n)

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. Please note that mod() is just like the modulo operator of most programming languages. If you want a mathematical correct modulo, see here.

### Fraction mod()

Returns the modulus (rest of the division) of the actual object (numerator mod denominator)

### Fraction gcd(n)

Returns the fractional greatest common divisor

### Fraction lcm(n)

Returns the fractional least common multiple

### Fraction ceil([places=0-16])

Returns the ceiling of a rational number with Math.ceil

### Fraction floor([places=0-16])

Returns the floor of a rational number with Math.floor

### Fraction round([places=0-16])

Returns the rational number rounded with Math.round

### Fraction inverse()

Returns the multiplicative inverse of the actual number (n / d becomes d / n) in order to get the reciprocal

### Fraction simplify([eps=0.001])

Simplifies the rational number under a certain error threshold. Ex. `0.333` will be `1/3` with `eps=0.001`

### boolean equals(n)

Check if two numbers are equal

### int compare(n)

Compare two numbers.

``````result < 0: n is greater than actual number
result > 0: n is smaller than actual number
result = 0: n is equal to the actual number
``````

### boolean divisible(n)

Check if two numbers are divisible (n divides this)

### double valueOf()

Returns a decimal representation of the fraction

### String toString([decimalPlaces=15])

Generates an exact string representation of the actual object. For repeated decimal places all digits are collected within brackets, like `1/3 = "0.(3)"`. For all other numbers, up to `decimalPlaces` significant digits are collected - which includes trailing zeros if the number is getting truncated. However, `1/2 = "0.5"` without trailing zeros of course.

Note: As `valueOf()` and `toString()` are provided, `toString()` is only called implicitly in a real string context. Using the plus-operator like `"123" + new Fraction` will call valueOf(), because JavaScript tries to combine two primitives first and concatenates them later, as string will be the more dominant type. `alert(new Fraction)` or `String(new Fraction)` on the other hand will do what you expect. If you really want to have control, you should call `toString()` or `valueOf()` explicitly!

### String toLatex(excludeWhole=false)

Generates an exact LaTeX representation of the actual object. You can see a live demo on my blog.

The optional boolean parameter indicates if you want to exclude the whole part. "1 1/3" instead of "4/3"

### String toFraction(excludeWhole=false)

Gets a string representation of the fraction

The optional boolean parameter indicates if you want to exclude the whole part. "1 1/3" instead of "4/3"

### Array toContinued()

Gets an array of the fraction represented as a continued fraction. The first element always contains the whole part.

``````var f = new Fraction('88/33');
var c = f.toContinued(); // [2, 1, 2]
``````

### Fraction clone()

Creates a copy of the actual Fraction object

## Exceptions

If a really hard error occurs (parsing error, division by zero), fraction.js throws exceptions! Please make sure you handle them correctly.

## Installation

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
``````

## Using Fraction.js with the browser

``````<script src="fraction.js"></script>
<script>
console.log(Fraction("123/456"));
</script>
``````

## Using Fraction.js with require.js

``````<script src="require.js"></script>
<script>
requirejs(['fraction.js'],
function(Fraction) {
console.log(Fraction("123/456"));
});
</script>
``````

## Using Fraction.js with TypeScript

``````import Fraction from "fraction.js";
console.log(Fraction("123/456"));
``````

## Coding Style

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.

Precision

Fraction.js tries to circumvent floating point errors, by having an internal representation of numerator and denominator. As it relies on JavaScript, there is also a limit. The biggest number representable is `Number.MAX_SAFE_INTEGER / 1` and the smallest is `-1 / Number.MAX_SAFE_INTEGER`, with `Number.MAX_SAFE_INTEGER=9007199254740991`. If this is not enough, there is `bigfraction.js` shipped experimentally, which relies on `BigInt` and should become the new Fraction.js eventually.

Testing

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 and licensing

Copyright (c) 2014-2022, Robert Eisele Dual licensed under the MIT or GPL Version 2 licenses.

Author: infusion
Official Website: https://github.com/infusion/Fraction.js

1632537859

## Nbb

Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.

## Status

Experimental. Please report issues here.

## Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

• Fast startup without relying on a custom version of Node.js.
• Small artifact (current size is around 1.2MB).
• First class macros.
• Support building small TUI apps using Reagent.
• Complement babashka with libraries from the Node.js ecosystem.

## Requirements

Nbb requires Node.js v12 or newer.

## How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).

## Usage

Install `nbb` from NPM:

``````\$ npm install nbb -g
``````

Omit `-g` for a local install.

Try out an expression:

``````\$ nbb -e '(+ 1 2 3)'
6
``````

And then install some other NPM libraries to use in the script. E.g.:

``````\$ npm install csv-parse shelljs zx
``````

Create a script which uses the NPM libraries:

``````(ns script
(:require ["csv-parse/lib/sync\$default" :as csv-parse]
["fs" :as fs]
["path" :as path]
["shelljs\$default" :as sh]
["term-size\$default" :as term-size]
["zx\$default" :as zx]
["zx\$fs" :as zxfs]
[nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/\$ #js ["ls"])
``````

Call the script:

``````\$ nbb script.cljs
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
\$ ls
node_modules
package-lock.json
package.json
script.cljs
``````

## Macros

Nbb has first class support for macros: you can define them right inside your `.cljs` file, like you are used to from JVM Clojure. Consider the `plet` macro to make working with promises more palatable:

``````(defmacro plet
[bindings & body]
(let [binding-pairs (reverse (partition 2 bindings))
body (cons 'do body)]
(reduce (fn [body [sym expr]]
(let [expr (list '.resolve 'js/Promise expr)]
(list '.then expr (list 'clojure.core/fn (vector sym)
body))))
body
binding-pairs)))
``````

Using this macro we can look async code more like sync code. Consider this puppeteer example:

``````(-> (.launch puppeteer)
(.then (fn [browser]
(-> (.newPage browser)
(.then (fn [page]
(-> (.goto page "https://clojure.org")
(.then #(.screenshot page #js{:path "screenshot.png"}))
(.catch #(js/console.log %))
(.then #(.close browser)))))))))
``````

Using `plet` this becomes:

``````(plet [browser (.launch puppeteer)
page (.newPage browser)
_ (.goto page "https://clojure.org")
_ (-> (.screenshot page #js{:path "screenshot.png"})
(.catch #(js/console.log %)))]
(.close browser))
``````

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above `plet` macro is similar to `promesa.core/let`.

## Startup time

``````\$ time nbb -e '(+ 1 2 3)'
6
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total
``````

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via `npx` this adds another 300ms or so, so for faster startup, either use a globally installed `nbb` or use `\$(npm bin)/nbb script.cljs` to bypass `npx`.

## Dependencies

### NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.

### Classpath

To load `.cljs` files from local paths or dependencies, you can use the `--classpath` argument. The current dir is added to the classpath automatically. So if there is a file `foo/bar.cljs` relative to your current dir, then you can load it via `(:require [foo.bar :as fb])`. Note that `nbb` uses the same naming conventions for namespaces and directories as other Clojure tools: `foo-bar` in the namespace name becomes `foo_bar` in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

``````\$ classpath="\$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"
``````

and then feed it to the `--classpath` argument:

``````\$ nbb --classpath "\$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]
``````

Currently `nbb` only reads from directories, not jar files, so you are encouraged to use git libs. Support for `.jar` files will be added later.

## Current file

The name of the file that is currently being executed is available via `nbb.core/*file*` or on the metadata of vars:

``````(ns foo
(:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"
``````

## Reagent

Nbb includes `reagent.core` which will be lazily loaded when required. You can use this together with ink to create a TUI application:

``````\$ npm install ink
``````

`ink-demo.cljs`:

``````(ns ink-demo
(:require ["ink" :refer [render Text]]
[reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
(js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
[:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))
``````

## Promesa

Working with callbacks and promises can become tedious. Since nbb v0.0.36 the `promesa.core` namespace is included with the `let` and `do!` macros. An example:

``````(ns prom
(:require [promesa.core :as p]))

(defn sleep [ms]
(js/Promise.
(fn [resolve _]
(js/setTimeout resolve ms))))

(defn do-stuff
[]
(p/do!
(println "Doing stuff which takes a while")
(sleep 1000)
1))

(p/let [a (do-stuff)
b (inc a)
c (do-stuff)
d (+ b c)]
(prn d))
``````
``````\$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while
3
``````

Also see API docs.

## Js-interop

Since nbb v0.0.75 applied-science/js-interop is available:

``````(ns example
(:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1
``````

Most of this library is supported in nbb, except the following:

• destructuring using `:syms`
• property access using `.-x` notation. In nbb, you must use keywords.

See the example of what is currently supported.

## Examples

See the examples directory for small examples.

Also check out these projects built with nbb:

## API

See API documentation.

## Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.

## Build

Prequisites:

• babashka >= 0.4.0
• Clojure CLI >= 1.10.3.933
• Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

• Clone and cd into this repo
• `bb release`

Run `bb tasks` for more project-related tasks.

Author: borkdude
Official Website: https://github.com/borkdude/nbb

#node #javascript

1642993740

## Fraction.js: A rational number library for JavaScript

Fraction.js - ℚ in JavaScript

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:

``````1 / 98 * 98 // = 0.9999999999999999
``````

If you need more precision or just want a fraction as a result, have a look at Fraction.js:

``````var Fraction = require('fraction.js');

Fraction(1).div(98).mul(98) // = 1
``````

Internally, numbers are represented as numerator / denominator, which adds just a little overhead. However, the library is written with performance in mind and outperforms any other implementation, as you can see here. This basic data-type makes it the perfect basis for Polynomial.js and Math.js.

Convert decimal to fraction

The simplest job for fraction.js is to get a fraction out of a decimal:

``````var x = new Fraction(1.88);
var res = x.toFraction(true); // String "1 22/25"
``````

Examples / Motivation

A simple example might be

``````var f = new Fraction("9.4'31'"); // 9.4313131313131...
f.mul([-4, 3]).mod("4.'8'"); // 4.88888888888888...
``````

The result is

``````console.log(f.toFraction()); // -4154 / 1485
``````

You could of course also access the sign (s), numerator (n) and denominator (d) on your own:

``````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.

Laplace Probability

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({3}):

``````var p = new Fraction([3].length, 6).toString(); // 0.1(6)
``````

P({1, 4}):

``````var p = new Fraction([1, 4].length, 6).toString(); // 0.(3)
``````

P({2, 4, 6}):

``````var p = new Fraction([2, 4, 6].length, 6).toString(); // 0.5
``````

Convert degrees/minutes/seconds to precise rational representation:

57+45/60+17/3600

``````var deg = 57; // 57°
var min = 45; // 45 Minutes
var sec = 17; // 17 Seconds

new Fraction(deg).add(min, 60).add(sec, 3600).toString() // -> 57.7547(2)
``````

Rounding a fraction to the closest tape measure value

A tape measure is usually divided in parts of `1/16`. Rounding a given fraction to the closest value on a tape measure can be determined by

``````function closestTapeMeasure(frac) {

/*
k/16 ≤ a/b < (k+1)/16
⇔ k ≤ 16*a/b < (k+1)
⇔ k = floor(16*a/b)
*/
return new Fraction(Math.round(16 * Fraction(frac).valueOf()), 16);
}
// closestTapeMeasure("1/3") // 5/16
``````

Rational approximation of irrational numbers

Now it's getting messy ;d To approximate a number like sqrt(5) - 2 with a numerator and denominator, you can reformat the equation as follows: pow(n / d + 2, 2) = 5.

Then the following algorithm will generate the rational number besides the binary representation.

``````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)
``````

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 (Still not the best idea to approximate irrational numbers, but it illustrates the capabilities of Fraction.js perfectly).

## Get the exact fractional part of a number

``````var f = new Fraction("-6.(3416)");
console.log("" + f.mod(1).abs()); // Will print 0.(3416)
``````

## Mathematical correct modulo

The behaviour on negative congruences is different to most modulo implementations in computer science. Even the mod() function of Fraction.js behaves in the typical way. To solve the problem of having the mathematical correct modulo with Fraction.js you could come up with this:

``````var a = -1;
var b = 10.99;

console.log(new Fraction(a)
.mod(b)); // Not correct, usual Modulo

console.log(new Fraction(a)
.mod(b).add(b).mod(b)); // Correct! Mathematical Modulo
``````

## fmod() impreciseness circumvented

It turns out that Fraction.js outperforms almost any fmod() implementation, including JavaScript itself, php.js, 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.

Parser

Any function (see below) as well as the constructor of the Fraction class parses its input and reduce it to the smallest term.

You can pass either Arrays, Objects, Integers, Doubles or Strings.

## Arrays / Objects

``````new Fraction(numerator, denominator);
new Fraction([numerator, denominator]);
new Fraction({n: numerator, d: denominator});
``````

## Integers

``````new Fraction(123);
``````

## Doubles

``````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 observations. If you have problems with the approximation, in the file `examples/approx.js` is a different approximation algorithm, which might work better in some more specific use-cases.

## Strings

``````new Fraction("123.45");
new Fraction("123/45"); // A rational number represented as two decimals, separated by a slash
new Fraction("123:45"); // A rational number represented as two decimals, separated by a colon
new Fraction("4 123/45"); // A rational number represented as a whole number and a fraction
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!
``````

## Two arguments

``````new Fraction(3, 2); // 3/2 = 1.5
``````

## Repeating decimal places

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);
}
``````

Attributes

The Fraction object allows direct access to the numerator, denominator and sign attributes. It is ensured that only the sign-attribute holds sign information so that a sign comparison is only necessary against this attribute.

``````var f = new Fraction('-1/2');
console.log(f.n); // Numerator: 1
console.log(f.d); // Denominator: 2
console.log(f.s); // Sign: -1
``````

Functions

## Fraction abs()

Returns the actual number without any sign information

## Fraction neg()

Returns the actual number with flipped sign in order to get the additive inverse

Returns the sum of the actual number and the parameter n

## Fraction sub(n)

Returns the difference of the actual number and the parameter n

## Fraction mul(n)

Returns the product of the actual number and the parameter n

## Fraction div(n)

Returns the quotient of the actual number and the parameter n

## Fraction pow(exp)

Returns the power of the actual number, raised to an possible rational exponent. If the result becomes non-rational the function returns `null`.

## Fraction mod(n)

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. Please note that mod() is just like the modulo operator of most programming languages. If you want a mathematical correct modulo, see here.

## Fraction mod()

Returns the modulus (rest of the division) of the actual object (numerator mod denominator)

## Fraction gcd(n)

Returns the fractional greatest common divisor

## Fraction lcm(n)

Returns the fractional least common multiple

## Fraction ceil([places=0-16])

Returns the ceiling of a rational number with Math.ceil

## Fraction floor([places=0-16])

Returns the floor of a rational number with Math.floor

## Fraction round([places=0-16])

Returns the rational number rounded with Math.round

## Fraction inverse()

Returns the multiplicative inverse of the actual number (n / d becomes d / n) in order to get the reciprocal

## Fraction simplify([eps=0.001])

Simplifies the rational number under a certain error threshold. Ex. `0.333` will be `1/3` with `eps=0.001`

## boolean equals(n)

Check if two numbers are equal

## int compare(n)

Compare two numbers.

``````result < 0: n is greater than actual number
result > 0: n is smaller than actual number
result = 0: n is equal to the actual number
``````

## boolean divisible(n)

Check if two numbers are divisible (n divides this)

## double valueOf()

Returns a decimal representation of the fraction

## String toString([decimalPlaces=15])

Generates an exact string representation of the actual object. For repeated decimal places all digits are collected within brackets, like `1/3 = "0.(3)"`. For all other numbers, up to `decimalPlaces` significant digits are collected - which includes trailing zeros if the number is getting truncated. However, `1/2 = "0.5"` without trailing zeros of course.

Note: As `valueOf()` and `toString()` are provided, `toString()` is only called implicitly in a real string context. Using the plus-operator like `"123" + new Fraction` will call valueOf(), because JavaScript tries to combine two primitives first and concatenates them later, as string will be the more dominant type. `alert(new Fraction)` or `String(new Fraction)` on the other hand will do what you expect. If you really want to have control, you should call `toString()` or `valueOf()` explicitly!

## String toLatex(excludeWhole=false)

Generates an exact LaTeX representation of the actual object. You can see a live demo on my blog.

The optional boolean parameter indicates if you want to exclude the whole part. "1 1/3" instead of "4/3"

## String toFraction(excludeWhole=false)

Gets a string representation of the fraction

The optional boolean parameter indicates if you want to exclude the whole part. "1 1/3" instead of "4/3"

## Array toContinued()

Gets an array of the fraction represented as a continued fraction. The first element always contains the whole part.

``````var f = new Fraction('88/33');
var c = f.toContinued(); // [2, 1, 2]
``````

## Fraction clone()

Creates a copy of the actual Fraction object

Exceptions

If a really hard error occurs (parsing error, division by zero), fraction.js throws exceptions! Please make sure you handle them correctly.

Installation

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
``````

Using Fraction.js with the browser

``````<script src="fraction.js"></script>
<script>
console.log(Fraction("123/456"));
</script>
``````

Using Fraction.js with require.js

``````<script src="require.js"></script>
<script>
requirejs(['fraction.js'],
function(Fraction) {
console.log(Fraction("123/456"));
});
</script>
``````

Coding Style

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.

Precision

Fraction.js tries to circumvent floating point errors, by having an internal representation of numerator and denominator. As it relies on JavaScript, there is also a limit. The biggest number representable is `Number.MAX_SAFE_INTEGER / 1` and the smallest is `-1 / Number.MAX_SAFE_INTEGER`, with `Number.MAX_SAFE_INTEGER=9007199254740991`. If this is not enough, there is `bigfraction.js` shipped experimentally, which relies on `BigInt` and should become the new Fraction.js eventually.

Testing

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``

Author: infusion
Source Code: https://github.com/infusion/Fraction.js

1626321063

## JS Development Company India | JavaScript Development Services

PixelCrayons: Our JavaScript web development service offers you a feature-packed & dynamic web application that effectively caters to your business challenges and provide you the best RoI. Our JavaScript web development company works on all major frameworks & libraries like Angular, React, Nodejs, Vue.js, to name a few.

With 15+ years of domain expertise, we have successfully delivered 13800+ projects and have successfully garnered 6800+ happy customers with 97%+ client retention rate.

Looking for professional JavaScript web app development services? We provide custom JavaScript development services applying latest version frameworks and libraries to propel businesses to the next level. Our well-defined and manageable JS development processes are balanced between cost, time and quality along with clear communication.

Our JavaScript development companies offers you strict NDA, 100% money back guarantee and agile/DevOps approach.

#javascript development company #javascript development services #javascript web development #javascript development #javascript web development services #javascript web development company

1653622503

## Fraction.js - ℚ in JavaScript

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:

``````1 / 98 * 98 // = 0.9999999999999999
``````

If you need more precision or just want a fraction as a result, have a look at Fraction.js:

``````var Fraction = require('fraction.js');

Fraction(1).div(98).mul(98) // = 1
``````

Internally, numbers are represented as numerator / denominator, which adds just a little overhead. However, the library is written with performance in mind and outperforms any other implementation, as you can see here. This basic data-type makes it the perfect basis for Polynomial.js and Math.js.

## Convert decimal to fraction

The simplest job for fraction.js is to get a fraction out of a decimal:

``````var x = new Fraction(1.88);
var res = x.toFraction(true); // String "1 22/25"
``````

## Examples / Motivation

A simple example might be

``````var f = new Fraction("9.4'31'"); // 9.4313131313131...
f.mul([-4, 3]).mod("4.'8'"); // 4.88888888888888...
``````

The result is

``````console.log(f.toFraction()); // -4154 / 1485
``````

You could of course also access the sign (s), numerator (n) and denominator (d) on your own:

``````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.

## Laplace Probability

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({3}):

``````var p = new Fraction([3].length, 6).toString(); // 0.1(6)
``````

P({1, 4}):

``````var p = new Fraction([1, 4].length, 6).toString(); // 0.(3)
``````

P({2, 4, 6}):

``````var p = new Fraction([2, 4, 6].length, 6).toString(); // 0.5
``````

## Convert degrees/minutes/seconds to precise rational representation:

57+45/60+17/3600

``````var deg = 57; // 57°
var min = 45; // 45 Minutes
var sec = 17; // 17 Seconds

new Fraction(deg).add(min, 60).add(sec, 3600).toString() // -> 57.7547(2)
``````

## Rounding a fraction to the closest tape measure value

A tape measure is usually divided in parts of `1/16`. Rounding a given fraction to the closest value on a tape measure can be determined by

``````function closestTapeMeasure(frac) {

/*
k/16 ≤ a/b < (k+1)/16
⇔ k ≤ 16*a/b < (k+1)
⇔ k = floor(16*a/b)
*/
return new Fraction(Math.round(16 * Fraction(frac).valueOf()), 16);
}
// closestTapeMeasure("1/3") // 5/16
``````

## Rational approximation of irrational numbers

Now it's getting messy ;d To approximate a number like sqrt(5) - 2 with a numerator and denominator, you can reformat the equation as follows: pow(n / d + 2, 2) = 5.

Then the following algorithm will generate the rational number besides the binary representation.

``````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)
``````

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 (Still not the best idea to approximate irrational numbers, but it illustrates the capabilities of Fraction.js perfectly).

## Get the exact fractional part of a number

``````var f = new Fraction("-6.(3416)");
console.log("" + f.mod(1).abs()); // Will print 0.(3416)
``````

## Mathematical correct modulo

The behaviour on negative congruences is different to most modulo implementations in computer science. Even the mod() function of Fraction.js behaves in the typical way. To solve the problem of having the mathematical correct modulo with Fraction.js you could come up with this:

``````var a = -1;
var b = 10.99;

console.log(new Fraction(a)
.mod(b)); // Not correct, usual Modulo

console.log(new Fraction(a)
.mod(b).add(b).mod(b)); // Correct! Mathematical Modulo
``````

## fmod() impreciseness circumvented

It turns out that Fraction.js outperforms almost any fmod() implementation, including JavaScript itself, php.js, 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.

Parser

Any function (see below) as well as the constructor of the Fraction class parses its input and reduce it to the smallest term.

You can pass either Arrays, Objects, Integers, Doubles or Strings.

## Arrays / Objects

``````new Fraction(numerator, denominator);
new Fraction([numerator, denominator]);
new Fraction({n: numerator, d: denominator});
``````

## Integers

``````new Fraction(123);
``````

## Doubles

``````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 observations. If you have problems with the approximation, in the file `examples/approx.js` is a different approximation algorithm, which might work better in some more specific use-cases.

## Strings

``````new Fraction("123.45");
new Fraction("123/45"); // A rational number represented as two decimals, separated by a slash
new Fraction("123:45"); // A rational number represented as two decimals, separated by a colon
new Fraction("4 123/45"); // A rational number represented as a whole number and a fraction
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!
``````

## Two arguments

``````new Fraction(3, 2); // 3/2 = 1.5
``````

## Repeating decimal places

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);
}
``````

Attributes

The Fraction object allows direct access to the numerator, denominator and sign attributes. It is ensured that only the sign-attribute holds sign information so that a sign comparison is only necessary against this attribute.

``````var f = new Fraction('-1/2');
console.log(f.n); // Numerator: 1
console.log(f.d); // Denominator: 2
console.log(f.s); // Sign: -1
``````

## Functions

### Fraction abs()

Returns the actual number without any sign information

### Fraction neg()

Returns the actual number with flipped sign in order to get the additive inverse

Returns the sum of the actual number and the parameter n

### Fraction sub(n)

Returns the difference of the actual number and the parameter n

### Fraction mul(n)

Returns the product of the actual number and the parameter n

### Fraction div(n)

Returns the quotient of the actual number and the parameter n

### Fraction pow(exp)

Returns the power of the actual number, raised to an possible rational exponent. If the result becomes non-rational the function returns `null`.

### Fraction mod(n)

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. Please note that mod() is just like the modulo operator of most programming languages. If you want a mathematical correct modulo, see here.

### Fraction mod()

Returns the modulus (rest of the division) of the actual object (numerator mod denominator)

### Fraction gcd(n)

Returns the fractional greatest common divisor

### Fraction lcm(n)

Returns the fractional least common multiple

### Fraction ceil([places=0-16])

Returns the ceiling of a rational number with Math.ceil

### Fraction floor([places=0-16])

Returns the floor of a rational number with Math.floor

### Fraction round([places=0-16])

Returns the rational number rounded with Math.round

### Fraction inverse()

Returns the multiplicative inverse of the actual number (n / d becomes d / n) in order to get the reciprocal

### Fraction simplify([eps=0.001])

Simplifies the rational number under a certain error threshold. Ex. `0.333` will be `1/3` with `eps=0.001`

### boolean equals(n)

Check if two numbers are equal

### int compare(n)

Compare two numbers.

``````result < 0: n is greater than actual number
result > 0: n is smaller than actual number
result = 0: n is equal to the actual number
``````

### boolean divisible(n)

Check if two numbers are divisible (n divides this)

### double valueOf()

Returns a decimal representation of the fraction

### String toString([decimalPlaces=15])

Generates an exact string representation of the actual object. For repeated decimal places all digits are collected within brackets, like `1/3 = "0.(3)"`. For all other numbers, up to `decimalPlaces` significant digits are collected - which includes trailing zeros if the number is getting truncated. However, `1/2 = "0.5"` without trailing zeros of course.

Note: As `valueOf()` and `toString()` are provided, `toString()` is only called implicitly in a real string context. Using the plus-operator like `"123" + new Fraction` will call valueOf(), because JavaScript tries to combine two primitives first and concatenates them later, as string will be the more dominant type. `alert(new Fraction)` or `String(new Fraction)` on the other hand will do what you expect. If you really want to have control, you should call `toString()` or `valueOf()` explicitly!

### String toLatex(excludeWhole=false)

Generates an exact LaTeX representation of the actual object. You can see a live demo on my blog.

The optional boolean parameter indicates if you want to exclude the whole part. "1 1/3" instead of "4/3"

### String toFraction(excludeWhole=false)

Gets a string representation of the fraction

The optional boolean parameter indicates if you want to exclude the whole part. "1 1/3" instead of "4/3"

### Array toContinued()

Gets an array of the fraction represented as a continued fraction. The first element always contains the whole part.

``````var f = new Fraction('88/33');
var c = f.toContinued(); // [2, 1, 2]
``````

### Fraction clone()

Creates a copy of the actual Fraction object

## Exceptions

If a really hard error occurs (parsing error, division by zero), fraction.js throws exceptions! Please make sure you handle them correctly.

## Installation

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
``````

## Using Fraction.js with the browser

``````<script src="fraction.js"></script>
<script>
console.log(Fraction("123/456"));
</script>
``````

## Using Fraction.js with require.js

``````<script src="require.js"></script>
<script>
requirejs(['fraction.js'],
function(Fraction) {
console.log(Fraction("123/456"));
});
</script>
``````

## Using Fraction.js with TypeScript

``````import Fraction from "fraction.js";
console.log(Fraction("123/456"));
``````

## Coding Style

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.

Precision

Fraction.js tries to circumvent floating point errors, by having an internal representation of numerator and denominator. As it relies on JavaScript, there is also a limit. The biggest number representable is `Number.MAX_SAFE_INTEGER / 1` and the smallest is `-1 / Number.MAX_SAFE_INTEGER`, with `Number.MAX_SAFE_INTEGER=9007199254740991`. If this is not enough, there is `bigfraction.js` shipped experimentally, which relies on `BigInt` and should become the new Fraction.js eventually.

Testing

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 and licensing

Copyright (c) 2014-2022, Robert Eisele Dual licensed under the MIT or GPL Version 2 licenses.

Author: infusion
Official Website: https://github.com/infusion/Fraction.js

1593507275

## Grokking Call(), Apply() and Bind() Methods in JavaScript

These functions are very important for every JavaScript Developer and are used in almost every JavaScript Library or Framework. Check out the code snippet below.

Taken from the very popular library Lodash

``````/**
* Creates a function that invokes `func` with arguments reversed.
*
* @since 4.0.0
* @category Function
* @param {Function} func The function to flip arguments for.
* @returns {Function} Returns the new flipped function.
* @see reverse
* @example
*
* const flipped = flip((...args) => args)
*
* flipped('a', 'b', 'c', 'd')
* // => ['d', 'c', 'b', 'a']
*/
function flip(func) {
if (typeof func !== 'function') {
throw new TypeError('Expected a function')
}
return function(...args) {
return func.apply(this, args.reverse())
}
}

export default flip
``````

Look at the statement on line 21, return func.apply(this, args.reverse())

In this article, we will have a look at the call()apply() and bind() methods of JavaScript. Basically these 3 methods are used to control the invocation of the function. The call() and apply() were introduced in ECMAScript 3 while bind() was added as a part of ECMAScript 5.

Let us start with an example to understand these.

Suppose you are a student of X university and your professor has asked you to create a math library, for an assignment, which calculates the area of a circle.

``````const calcArea = {
pi: 3.14,
area: function(r) {
return this.pi * r * r;
}
}
``````

calcArea.area(4); // prints 50.24

``````
You test this and verify its result, it is working fine and you upload the library to portal way before the deadline ends. Then you ask your classmates to test and verify as well, you come to know that that your result and their results mismatches the decimals precision. You check the assignment guidelines, Oh no! The professor asked you to use a constant **pi** with 5 decimals precision. But you used **3.14** and not **3.14159** as the value of pi. Now you cannot re-upload the library as the deadline date was already over. In this situation, **call()** function will save you.``````

#js #javascript-development #javascript #javascript-interview #javascript-tips