simple-squiggle/node_modules/mathjs/lib/esm/plain/number/arithmetic.js

340 lines
7.1 KiB
JavaScript
Raw Permalink Normal View History

import { isInteger, log2, log10, cbrt, expm1, sign, toFixed, log1p } from '../../utils/number.js';
var n1 = 'number';
var n2 = 'number, number';
export function absNumber(a) {
return Math.abs(a);
}
absNumber.signature = n1;
export function addNumber(a, b) {
return a + b;
}
addNumber.signature = n2;
export function subtractNumber(a, b) {
return a - b;
}
subtractNumber.signature = n2;
export function multiplyNumber(a, b) {
return a * b;
}
multiplyNumber.signature = n2;
export function divideNumber(a, b) {
return a / b;
}
divideNumber.signature = n2;
export function unaryMinusNumber(x) {
return -x;
}
unaryMinusNumber.signature = n1;
export function unaryPlusNumber(x) {
return x;
}
unaryPlusNumber.signature = n1;
export function cbrtNumber(x) {
return cbrt(x);
}
cbrtNumber.signature = n1;
export function ceilNumber(x) {
return Math.ceil(x);
}
ceilNumber.signature = n1;
export function cubeNumber(x) {
return x * x * x;
}
cubeNumber.signature = n1;
export function expNumber(x) {
return Math.exp(x);
}
expNumber.signature = n1;
export function expm1Number(x) {
return expm1(x);
}
expm1Number.signature = n1;
export function fixNumber(x) {
return x > 0 ? Math.floor(x) : Math.ceil(x);
}
fixNumber.signature = n1;
export function floorNumber(x) {
return Math.floor(x);
}
floorNumber.signature = n1;
/**
* Calculate gcd for numbers
* @param {number} a
* @param {number} b
* @returns {number} Returns the greatest common denominator of a and b
*/
export function gcdNumber(a, b) {
if (!isInteger(a) || !isInteger(b)) {
throw new Error('Parameters in function gcd must be integer numbers');
} // https://en.wikipedia.org/wiki/Euclidean_algorithm
var r;
while (b !== 0) {
r = a % b;
a = b;
b = r;
}
return a < 0 ? -a : a;
}
gcdNumber.signature = n2;
/**
* Calculate lcm for two numbers
* @param {number} a
* @param {number} b
* @returns {number} Returns the least common multiple of a and b
*/
export function lcmNumber(a, b) {
if (!isInteger(a) || !isInteger(b)) {
throw new Error('Parameters in function lcm must be integer numbers');
}
if (a === 0 || b === 0) {
return 0;
} // https://en.wikipedia.org/wiki/Euclidean_algorithm
// evaluate lcm here inline to reduce overhead
var t;
var prod = a * b;
while (b !== 0) {
t = b;
b = a % t;
a = t;
}
return Math.abs(prod / a);
}
lcmNumber.signature = n2;
/**
* Calculate the logarithm of a value, optionally to a given base.
* @param {number} x
* @param {number | null | undefined} base
* @return {number}
*/
export function logNumber(x, y) {
if (y) {
return Math.log(x) / Math.log(y);
}
return Math.log(x);
}
/**
* Calculate the 10-base logarithm of a number
* @param {number} x
* @return {number}
*/
export function log10Number(x) {
return log10(x);
}
log10Number.signature = n1;
/**
* Calculate the 2-base logarithm of a number
* @param {number} x
* @return {number}
*/
export function log2Number(x) {
return log2(x);
}
log2Number.signature = n1;
/**
* Calculate the natural logarithm of a `number+1`
* @param {number} x
* @returns {number}
*/
export function log1pNumber(x) {
return log1p(x);
}
log1pNumber.signature = n1;
/**
* Calculate the modulus of two numbers
* @param {number} x
* @param {number} y
* @returns {number} res
* @private
*/
export function modNumber(x, y) {
if (y > 0) {
// We don't use JavaScript's % operator here as this doesn't work
// correctly for x < 0 and x === 0
// see https://en.wikipedia.org/wiki/Modulo_operation
return x - y * Math.floor(x / y);
} else if (y === 0) {
return x;
} else {
// y < 0
// TODO: implement mod for a negative divisor
throw new Error('Cannot calculate mod for a negative divisor');
}
}
modNumber.signature = n2;
/**
* Calculate the nth root of a, solve x^root == a
* http://rosettacode.org/wiki/Nth_root#JavaScript
* @param {number} a
* @param {number} root
* @private
*/
export function nthRootNumber(a, root) {
var inv = root < 0;
if (inv) {
root = -root;
}
if (root === 0) {
throw new Error('Root must be non-zero');
}
if (a < 0 && Math.abs(root) % 2 !== 1) {
throw new Error('Root must be odd when a is negative.');
} // edge cases zero and infinity
if (a === 0) {
return inv ? Infinity : 0;
}
if (!isFinite(a)) {
return inv ? 0 : a;
}
var x = Math.pow(Math.abs(a), 1 / root); // If a < 0, we require that root is an odd integer,
// so (-1) ^ (1/root) = -1
x = a < 0 ? -x : x;
return inv ? 1 / x : x; // Very nice algorithm, but fails with nthRoot(-2, 3).
// Newton's method has some well-known problems at times:
// https://en.wikipedia.org/wiki/Newton%27s_method#Failure_analysis
/*
let x = 1 // Initial guess
let xPrev = 1
let i = 0
const iMax = 10000
do {
const delta = (a / Math.pow(x, root - 1) - x) / root
xPrev = x
x = x + delta
i++
}
while (xPrev !== x && i < iMax)
if (xPrev !== x) {
throw new Error('Function nthRoot failed to converge')
}
return inv ? 1 / x : x
*/
}
nthRootNumber.signature = n2;
export function signNumber(x) {
return sign(x);
}
signNumber.signature = n1;
export function sqrtNumber(x) {
return Math.sqrt(x);
}
sqrtNumber.signature = n1;
export function squareNumber(x) {
return x * x;
}
squareNumber.signature = n1;
/**
* Calculate xgcd for two numbers
* @param {number} a
* @param {number} b
* @return {number} result
* @private
*/
export function xgcdNumber(a, b) {
// source: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
var t; // used to swap two variables
var q; // quotient
var r; // remainder
var x = 0;
var lastx = 1;
var y = 1;
var lasty = 0;
if (!isInteger(a) || !isInteger(b)) {
throw new Error('Parameters in function xgcd must be integer numbers');
}
while (b) {
q = Math.floor(a / b);
r = a - q * b;
t = x;
x = lastx - q * x;
lastx = t;
t = y;
y = lasty - q * y;
lasty = t;
a = b;
b = r;
}
var res;
if (a < 0) {
res = [-a, -lastx, -lasty];
} else {
res = [a, a ? lastx : 0, lasty];
}
return res;
}
xgcdNumber.signature = n2;
/**
* Calculates the power of x to y, x^y, for two numbers.
* @param {number} x
* @param {number} y
* @return {number} res
*/
export function powNumber(x, y) {
// x^Infinity === 0 if -1 < x < 1
// A real number 0 is returned instead of complex(0)
if (x * x < 1 && y === Infinity || x * x > 1 && y === -Infinity) {
return 0;
}
return Math.pow(x, y);
}
powNumber.signature = n2;
/**
* round a number to the given number of decimals, or to zero if decimals is
* not provided
* @param {number} value
* @param {number} decimals number of decimals, between 0 and 15 (0 by default)
* @return {number} roundedValue
*/
export function roundNumber(value) {
var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
return parseFloat(toFixed(value, decimals));
}
roundNumber.signature = n2;
/**
* Calculate the norm of a number, the absolute value.
* @param {number} x
* @return {number}
*/
export function normNumber(x) {
return Math.abs(x);
}
normNumber.signature = n1;