'use strict'; module.exports = function (math) { var util = require('../../util/index'), BigNumber = math.type.BigNumber, Complex = require('../../type/Complex'), collection = math.collection, isNumber = util.number.isNumber, isInteger = util.number.isInteger, isBoolean = util['boolean'].isBoolean, isComplex = Complex.isComplex, isCollection = collection.isCollection, toFixed = util.number.toFixed; /** * Round a value towards the nearest integer. * For matrices, the function is evaluated element wise. * * Syntax: * * math.round(x) * math.round(x, n) * * Examples: * * math.round(3.2); // returns Number 3 * math.round(3.8); // returns Number 4 * math.round(-4.2); // returns Number -4 * math.round(-4.7); // returns Number -5 * math.round(math.pi, 3); // returns Number 3.142 * math.round(123.45678, 2); // returns Number 123.46 * * var c = math.complex(3.2, -2.7); * math.round(c); // returns Complex 3 - 3i * * math.round([3.2, 3.8, -4.7]); // returns Array [3, 4, -5] * * See also: * * ceil, fix, floor * * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x Number to be rounded * @param {Number | BigNumber | Boolean | Array | null} [n=0] Number of decimals * @return {Number | BigNumber | Complex | Array | Matrix} Rounded value */ math.round = function round(x, n) { if (arguments.length != 1 && arguments.length != 2) { throw new math.error.ArgumentsError('round', arguments.length, 1, 2); } if (n == undefined) { // round (x) if (isNumber(x)) { return Math.round(x); } if (isComplex(x)) { return new Complex ( Math.round(x.re), Math.round(x.im) ); } if (x instanceof BigNumber) { return x.toDecimalPlaces(0); } if (isCollection(x)) { return collection.deepMap(x, round); } if (isBoolean(x) || x === null) { return Math.round(x); } throw new math.error.UnsupportedTypeError('round', math['typeof'](x)); } else { // round (x, n) if (!isNumber(n) || !isInteger(n)) { if (n instanceof BigNumber) { n = parseFloat(n.valueOf()); } else if (isBoolean(n) || x === null) { return round(x, +n); } else { throw new TypeError('Number of decimals in function round must be an integer'); } } if (n < 0 || n > 15) { throw new Error ('Number of decimals in function round must be in te range of 0-15'); } if (isNumber(x)) { return roundNumber(x, n); } if (isComplex(x)) { return new Complex ( roundNumber(x.re, n), roundNumber(x.im, n) ); } if (x instanceof BigNumber) { return x.toDecimalPlaces(n); } if (isCollection(x) || isCollection(n)) { return collection.deepMap2(x, n, round); } if (isBoolean(x) || x === null) { return round(+x, n); } throw new math.error.UnsupportedTypeError('round', math['typeof'](x), math['typeof'](n)); } }; /** * 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 */ function roundNumber (value, decimals) { return parseFloat(toFixed(value, decimals)); } };