Package Exports
- arithmetica
- arithmetica/float
Readme
arithmetica
is an implementation of arithmetic operators for Rational numbers
A Rational is a number that can be expressed as a fraction of two integers. It includes also repeating decimals hence is a super-set of floating point numbers.
Installation
With npm do
npm install arithmeticaThis package is implemented with ECMAScript modules. CommonJS is not supported, nor bundle is provided.
If you need a bundle, for example only with floating point operators (i.e. without repeating decimals) you can do something like.
git clone git@github.com:fibo/arithmetica.git
cd arithmetica
esbuild --bundle float/index.js --minify --outfile=arithmetica.jsIt will produce a 1.6kb (minified, not gzipped) arithmetica.js file.
Usage
import { add } from "arithmetica";
add("1", "2"); // '3'
// Here 0._3 represents 0.3333333333333333...
add("0._3", "1")); // '1._3'NOTA BENE: there is no runtime check on types: consumers are responsible to feed inputs
that are actual Rational types, for instance using isRational type-guard.
If you want only floating point operators, without repeating decimals support, you can do
import { add } from "arithmetica/float";
add("0.1", "0.2"); // '0.3'Types
Float
A Float is a string that expresses a decimal representation of a number.
Decimal separator is "." character. Exponential notation is not allowed. Integer part can be omitted.
For example:
- "0"
- "1.2"
- "-0.42"
- ".123"
Rational
A Rational includes every Float plus repeating decimals that are decimal representation of a number whose digits are periodic.
A repeating decimal is represented by a string like:
- "0._3": represents fraction
1/3, that is 0.33333... - "0.123_456": represents number 0.123456456456456456456456...
Type guards
isFloat
isFloat(arg: unknown): arg is Float
Use isFloat type-guard to check if some data belongs to Float type.
import { Float, isFloat, sub } from "arithmetica/float";
function minusOne (a: string): Float {
if (isFloat(a)) return sub(a, "1");
throw new TypeError(`Argument is not a Float ${a}`);
}Of course it can be used also on an ECMAScript runtime.
import { isFloat, mul } from "arithmetica/float";
function timesTen (a) {
if (isFloat(a)) return mul(a, "10");
throw new TypeError("Argument is not a Float");
}isRational
isRational(arg: unknown): arg is Rational
Use isRational type-guard to check if some data belongs to Rational type.
import { Rational, isRational, add } from "arithmetica";
function plusOneThird (a: string): Rational {
if (isRational(a)) return add(a, "0._3");
throw new TypeError(`Argument is not a Rational ${a}`);
}Operators
Every operator imported from arithmetica/float has the same signature as its homonym operator imported from arithmetica, but of course with type Float instead of a Rational in its signature.
eq
Implements equality operator.
eq(a: Rational, b: Rational): boolean
import { eq } from "arithmetica";
eq("1", "2"); // false
eq("42", "42.0"); // trueadd
Implements addition operator.
add(a: Rational, b: Rational): Rational
import { add } from "arithmetica";
add("1", "2"); // '3'
add("0._1", "0._1"); // '0._2' i.e. 0.2222222...
add("0._1", "0._8"); // "1"sub
Implements subtraction operator.
sub(a: Rational, b: Rational): Rational
import { sub } from "arithmetica";
sub("1", "2"); // '-1'
sub("0._1", "0._1"); // '0'
sub("1", "0._1"); // "0._8"neg
Implements negation operator.
neg(a: Rational): Rational
import { neg } from "arithmetica";
neg("1"); // '-1'
neg("-42"); // '42'mul
Implements multiplication operator.
mul(a: Rational, b: Rational): Rational
import { mul } from "arithmetica";
mul("2", "-3"); // '-6'
mul("0._3", "0.3"); // '0.1'div
Implements division operator.
div(a: Rational, b: Rational): Rational
It throws RangeError if denominator is zero.
import { div } from "arithmetica";
div("-10", "2"); // '-5'
try {
div("2", "0");
} catch (err) {
console.error(err); // RangeError: Division by zero
}inv
Implements inversion operator.
inv(a: Rational): Rational
import { inv } from "arithmetica";
inv("2"); // '0.5'
inv("1._1"); // '9'lt
Implements less then operator.
lt(a: Rational, b: Rational): boolean
import { lt } from "arithmetica";
lt("-2", "1"); // truegt
Implements greater then operator.
gt(a: Rational, b: Rational): boolean
import { gt } from "arithmetica";
gt("-2", "1"); // false
gt("42", "24"); // trueUtils
coerceToFloat
Coerces to
Float.
coerceToFloat(arg: unknown): Float
import { coerceToFloat } from "arithmetica/float";
coerceToFloat(0); // '0'
coerceToFloat(-1.23); // '-1.23'floatToNumber
Converts a
Floatto anumber.
floatToNumber(floatStr: Float, mantissaLength?: number): number
import { floatToNumber } from "arithmetica/float";
floatToNumber("42.01", 0); // 42
floatToNumber("1234.56789", 2); // 1234.57coerceToRational
Coerces to
Rational.
coerceToRational(arg: unknown): Rational
import { coerceToRational } from "arithmetica";
coerceToRational(42); // '42'
coerceToRational(-1n); // '-1'rationalToNumber
Converts a
Rationalto anumber.
rationalToNumber(rational: Rational, mantissaLength?: number): number
Notice that mantissaLength argument is optional:
it set the number of digits of the decimal part, max is 16.
Output is rounded.
import { rationalToNumber } from "arithmetica";
rationalToNumber("0.10"); // 0.1
rationalToNumber("0._3", 8); // 0.33333333
rationalToNumber("0.456", 2); // 0.46