Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Floating-point versions of Math.round, Math.floor, Math.ceil
/**
* Adjusts a number to a given precision, working around the buggy floating-point math of Javascript. Works for
* round, floor, ceil operations.
*
* Lifted from the Math.round entry of MDN. Minor changes without effect on the algorithm.
*
* @param {string} operation "round", "floor", "ceil"
* @param {number} value
* @param {number} [precision=0] can be negative: round( 104,-1 ) => 100
* @returns {number}
*/
function _decimalAdjust ( operation, value, precision ) {
var exp;
if ( typeof precision === 'undefined' || +precision === 0 ) return Math[operation]( value );
value = +value;
precision = +precision;
// Return NaN if the value is not a number or the precision is not an integer
if ( isNaN( value ) || !(typeof precision === 'number' && precision % 1 === 0) ) return NaN;
exp = -precision;
// Shift
value = value.toString().split( 'e' );
value = Math[operation]( +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)) );
// Shift back
value = value.toString().split( 'e' );
return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}
var Nums = {};
Nums.round = function ( value, precision ) {
return _decimalAdjust( 'round', value, precision );
};
Nums.floor = function ( value, precision ) {
return _decimalAdjust( 'floor', value, precision );
};
Nums.ceil = function ( value, precision ) {
return _decimalAdjust( 'ceil', value, precision );
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment