UNPKG

7.15 kBJavaScriptView Raw
1import { isInteger, log2, log10, cbrt, expm1, sign, toFixed, log1p } from '../../utils/number';
2var n1 = 'number';
3var n2 = 'number, number';
4export function absNumber(a) {
5 return Math.abs(a);
6}
7absNumber.signature = n1;
8export function addNumber(a, b) {
9 return a + b;
10}
11addNumber.signature = n2;
12export function subtractNumber(a, b) {
13 return a - b;
14}
15subtractNumber.signature = n2;
16export function multiplyNumber(a, b) {
17 return a * b;
18}
19multiplyNumber.signature = n2;
20export function divideNumber(a, b) {
21 return a / b;
22}
23divideNumber.signature = n2;
24export function unaryMinusNumber(x) {
25 return -x;
26}
27unaryMinusNumber.signature = n1;
28export function unaryPlusNumber(x) {
29 return x;
30}
31unaryPlusNumber.signature = n1;
32export function cbrtNumber(x) {
33 return cbrt(x);
34}
35cbrtNumber.signature = n1;
36export function ceilNumber(x) {
37 return Math.ceil(x);
38}
39ceilNumber.signature = n1;
40export function cubeNumber(x) {
41 return x * x * x;
42}
43cubeNumber.signature = n1;
44export function expNumber(x) {
45 return Math.exp(x);
46}
47expNumber.signature = n1;
48export function expm1Number(x) {
49 return expm1(x);
50}
51expm1Number.signature = n1;
52export function fixNumber(x) {
53 return x > 0 ? Math.floor(x) : Math.ceil(x);
54}
55fixNumber.signature = n1;
56export function floorNumber(x) {
57 return Math.floor(x);
58}
59floorNumber.signature = n1;
60/**
61 * Calculate gcd for numbers
62 * @param {number} a
63 * @param {number} b
64 * @returns {number} Returns the greatest common denominator of a and b
65 */
66
67export function gcdNumber(a, b) {
68 if (!isInteger(a) || !isInteger(b)) {
69 throw new Error('Parameters in function gcd must be integer numbers');
70 } // https://en.wikipedia.org/wiki/Euclidean_algorithm
71
72
73 var r;
74
75 while (b !== 0) {
76 r = a % b;
77 a = b;
78 b = r;
79 }
80
81 return a < 0 ? -a : a;
82}
83gcdNumber.signature = n2;
84/**
85 * Calculate lcm for two numbers
86 * @param {number} a
87 * @param {number} b
88 * @returns {number} Returns the least common multiple of a and b
89 */
90
91export function lcmNumber(a, b) {
92 if (!isInteger(a) || !isInteger(b)) {
93 throw new Error('Parameters in function lcm must be integer numbers');
94 }
95
96 if (a === 0 || b === 0) {
97 return 0;
98 } // https://en.wikipedia.org/wiki/Euclidean_algorithm
99 // evaluate lcm here inline to reduce overhead
100
101
102 var t;
103 var prod = a * b;
104
105 while (b !== 0) {
106 t = b;
107 b = a % t;
108 a = t;
109 }
110
111 return Math.abs(prod / a);
112}
113lcmNumber.signature = n2;
114/**
115 * Calculate the logarithm of a value.
116 * @param {number} x
117 * @return {number}
118 */
119
120export function logNumber(x) {
121 return Math.log(x);
122}
123logNumber.signature = n1;
124/**
125 * Calculate the 10-base logarithm of a number
126 * @param {number} x
127 * @return {number}
128 */
129
130export function log10Number(x) {
131 return log10(x);
132}
133log10Number.signature = n1;
134/**
135 * Calculate the 2-base logarithm of a number
136 * @param {number} x
137 * @return {number}
138 */
139
140export function log2Number(x) {
141 return log2(x);
142}
143log2Number.signature = n1;
144/**
145 * Calculate the natural logarithm of a `number+1`
146 * @param {number} x
147 * @returns {number}
148 */
149
150export function log1pNumber(x) {
151 return log1p(x);
152}
153log1pNumber.signature = n1;
154/**
155 * Calculate the modulus of two numbers
156 * @param {number} x
157 * @param {number} y
158 * @returns {number} res
159 * @private
160 */
161
162export function modNumber(x, y) {
163 if (y > 0) {
164 // We don't use JavaScript's % operator here as this doesn't work
165 // correctly for x < 0 and x === 0
166 // see https://en.wikipedia.org/wiki/Modulo_operation
167 return x - y * Math.floor(x / y);
168 } else if (y === 0) {
169 return x;
170 } else {
171 // y < 0
172 // TODO: implement mod for a negative divisor
173 throw new Error('Cannot calculate mod for a negative divisor');
174 }
175}
176modNumber.signature = n2;
177/**
178 * Calculate the nth root of a, solve x^root == a
179 * http://rosettacode.org/wiki/Nth_root#JavaScript
180 * @param {number} a
181 * @param {number} root
182 * @private
183 */
184
185export function nthRootNumber(a, root) {
186 var inv = root < 0;
187
188 if (inv) {
189 root = -root;
190 }
191
192 if (root === 0) {
193 throw new Error('Root must be non-zero');
194 }
195
196 if (a < 0 && Math.abs(root) % 2 !== 1) {
197 throw new Error('Root must be odd when a is negative.');
198 } // edge cases zero and infinity
199
200
201 if (a === 0) {
202 return inv ? Infinity : 0;
203 }
204
205 if (!isFinite(a)) {
206 return inv ? 0 : a;
207 }
208
209 var x = Math.pow(Math.abs(a), 1 / root); // If a < 0, we require that root is an odd integer,
210 // so (-1) ^ (1/root) = -1
211
212 x = a < 0 ? -x : x;
213 return inv ? 1 / x : x; // Very nice algorithm, but fails with nthRoot(-2, 3).
214 // Newton's method has some well-known problems at times:
215 // https://en.wikipedia.org/wiki/Newton%27s_method#Failure_analysis
216
217 /*
218 let x = 1 // Initial guess
219 let xPrev = 1
220 let i = 0
221 const iMax = 10000
222 do {
223 const delta = (a / Math.pow(x, root - 1) - x) / root
224 xPrev = x
225 x = x + delta
226 i++
227 }
228 while (xPrev !== x && i < iMax)
229 if (xPrev !== x) {
230 throw new Error('Function nthRoot failed to converge')
231 }
232 return inv ? 1 / x : x
233 */
234}
235nthRootNumber.signature = n2;
236export function signNumber(x) {
237 return sign(x);
238}
239signNumber.signature = n1;
240export function sqrtNumber(x) {
241 return Math.sqrt(x);
242}
243sqrtNumber.signature = n1;
244export function squareNumber(x) {
245 return x * x;
246}
247squareNumber.signature = n1;
248/**
249 * Calculate xgcd for two numbers
250 * @param {number} a
251 * @param {number} b
252 * @return {number} result
253 * @private
254 */
255
256export function xgcdNumber(a, b) {
257 // source: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
258 var t; // used to swap two variables
259
260 var q; // quotient
261
262 var r; // remainder
263
264 var x = 0;
265 var lastx = 1;
266 var y = 1;
267 var lasty = 0;
268
269 if (!isInteger(a) || !isInteger(b)) {
270 throw new Error('Parameters in function xgcd must be integer numbers');
271 }
272
273 while (b) {
274 q = Math.floor(a / b);
275 r = a - q * b;
276 t = x;
277 x = lastx - q * x;
278 lastx = t;
279 t = y;
280 y = lasty - q * y;
281 lasty = t;
282 a = b;
283 b = r;
284 }
285
286 var res;
287
288 if (a < 0) {
289 res = [-a, -lastx, -lasty];
290 } else {
291 res = [a, a ? lastx : 0, lasty];
292 }
293
294 return res;
295}
296xgcdNumber.signature = n2;
297/**
298 * Calculates the power of x to y, x^y, for two numbers.
299 * @param {number} x
300 * @param {number} y
301 * @return {number} res
302 */
303
304export function powNumber(x, y) {
305 // x^Infinity === 0 if -1 < x < 1
306 // A real number 0 is returned instead of complex(0)
307 if (x * x < 1 && y === Infinity || x * x > 1 && y === -Infinity) {
308 return 0;
309 }
310
311 return Math.pow(x, y);
312}
313powNumber.signature = n2;
314/**
315 * round a number to the given number of decimals, or to zero if decimals is
316 * not provided
317 * @param {number} value
318 * @param {number} decimals number of decimals, between 0 and 15 (0 by default)
319 * @return {number} roundedValue
320 */
321
322export function roundNumber(value) {
323 var decimals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
324 return parseFloat(toFixed(value, decimals));
325}
326roundNumber.signature = n2;
327/**
328 * Calculate the norm of a number, the absolute value.
329 * @param {number} x
330 * @return {number}
331 */
332
333export function normNumber(x) {
334 return Math.abs(x);
335}
336normNumber.signature = n1;
\No newline at end of file