Source: util/Math.js

//------------------------------------------------------------------------------
// Constructor scope
//------------------------------------------------------------------------------

/**
 * Creates a new instance of the Math class. Note that this class is intended 
 * as a static library of methods, thus instantiation results in a warning.
 *
 * @constructor
 *
 * @class
 * @classdesc
 *
 * The Math class contains a library of static methods for common mathematical 
 * calculations. The class can thus be used as an alternative to JavaScripts' 
 * built-in Math class.
 */
rune.util.Math = function() {
    console.warn("This class is not meant to be instantiated; all content is static.");
};

//------------------------------------------------------------------------------
// Public static constants
//------------------------------------------------------------------------------

/**
 * Magic number used when converting between degrees to radians.
 *
 * @constant {number}
 * @default 0.01745329251
 */
rune.util.Math.DEG_TO_RAD = Math.PI / 180.0;

/**
 * Magic number used when converting between radians to degrees.
 *
 * @constant {number}
 * @default 57.2957795131
 */
rune.util.Math.RAD_TO_DEG = 180.0 / Math.PI;

//------------------------------------------------------------------------------
// Public static methods
//------------------------------------------------------------------------------

/**
 * Returns the absolute value of n.
 * 
 * @param {number} n A number.
 * 
 * @return {number} The absolute value of the given number.
 */
rune.util.Math.abs = function(n) {
    return (n > 0) ? n : -n;
};

/**
 * Returns the mean of n.
 *
 * @param {Array} n A list of numbers. 
 * 
 * @return {number} The mean of given numbers.
 */
rune.util.Math.avg = function(n) {
    var sum = 0;
    var i = n.length;
    while (i--) {
        sum += (n[i]);
    }
    
    return sum / n.length;
};

/**
 * Returns the smallest integer greater than or equal to n.
 *
 * @param {number} n A number.
 * 
 * @return {number} The smallest integer greater than or equal to the given number.
 */
rune.util.Math.ceil = function(n) {
    var t = ~~n;
    return (t === n) ? n : (n > 0) ? (t + 1) : (t - 1);
};

/**
 * Returns true based on a chance of n.
 *
 * @param {number} n Chance between 0 and 100.
 * 
 * @return {boolean} True or false, depending on the chance of n.
 */
rune.util.Math.chance = function(n) {
    n = n || 50;
    n = Math.min(n, 100);
    n = Math.max(n,   0);

    return n >= Math.random() * 100;
};

/**
 * Returns a number within a specified range.
 *
 * @param {number} num A number.
 * @param {number} min Minimum number.
 * @param {number} max Maximum number.
 * 
 * @return {number} A number between the minimum and maximum value.
 */
rune.util.Math.clamp = function(num, min, max) {
    return Math.min(Math.max(num, min), max);
};

/**
 * Returns the cosine of n.
 *
 * @param {number} n The angle in radians for which to return the cosine.
 * 
 * @return {number} The cosine of the given number.
 */
rune.util.Math.cos = function(n) {
    return rune.util.Math.sin(n + 1.570796327);
};

/**
 * Converts an angle in degrees to radians.
 *
 * @param {number} angle Angle described in degrees.
 * 
 * @return {number} Specified angle in radians.
 */
rune.util.Math.degreesToRadians = function(angle) {
    return angle * rune.util.Math.DEG_TO_RAD;
};

/**
 * Calculates the difference between a and b.
 * 
 * @param {number} a A number.
 * @param {number} b A number.
 * 
 * @return {number} The difference between a and b.
 */
rune.util.Math.diff = function(a, b) {
    return Math.abs(a - b);
};

/**
 * Returns the distance between two points.
 * 
 * @param {number} x1 The x coordinate of the first point.
 * @param {number} y1 The y coordinate of the first point.
 * @param {number} x2 The x coordinate of the second point.
 * @param {number} y2 The y coordinate of the second point.
 * 
 * @return {number} The distance between the first and second points.
 */
rune.util.Math.distance = function(x1, y1, x2, y2) {
    var a = x1 - x2;
    var b = y1 - y2;

    return Math.sqrt(a * a + b * b);
};

/**
 * Returns the largest integer less than or equal to n.
 *
 * @param {number} n A number.
 * 
 * @return {number} A number representing the largest integer less than or equal to the specified number.
 */
rune.util.Math.floor = function(n) {
    return ~~n;
};

/**
 * Returns a human-friendly string representation of a quantity specified in 
 * bytes.
 *
 * @param {number} bytes Number of bytes.
 * @param {number} decimals Number of decimals.
 * 
 * @return {string} Human-friendly string representation.
 */
rune.util.Math.formatBytes = function(bytes, decimals) {
    decimals = decimals || 2;

    if (bytes === 0) return "0 Bytes";

    var k     = 1024;
    var dm    = decimals < 0 ? 0 : decimals;
    var sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
    var i     = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
};

/**
 * Returns the percentage (as float) of a specified number.
 * 
 * @param {number} num A number.
 * @param {number} max Maximum number.
 * 
 * @return {number} Percentage of given numbers.
 */
rune.util.Math.percentDec = function(num, max) {
    return rune.util.Math.clamp(1 - (num / max), 0, 1);
};

/**
 * Returns the percentage (as integer) of a specified number.
 * 
 * @param {number} num A number.
 * @param {number} max Maximum number.
 * 
 * @return {number} Percentage of given numbers.
 */
rune.util.Math.percentInc = function(num, max) {
    return rune.util.Math.clamp((num / max), 0, 1);
};

/**
 * Returns whether n is an even number (true) or not (false).
 * 
 * @param {number} n A number.
 * 
 * @return {boolean} Whether a given number is even.
 */
rune.util.Math.isEven = function(n) {
    return (parseInt(n, 10) & 1) === 0;
};

/**
 * Checks whether n is a number. The method does not consider 
 * "special values" like NaN or Infinity as numbers; they must be 
 * digit-based, either positive or negative.
 * 
 * @param {number|undefined} n A number.
 * 
 * @return {boolean} Whether n is an number.
 */
rune.util.Math.isNum = function(n) {
    return /^[-]?\d+$/.test(n);
};

/**
 * Returns whether n is an odd number (true) or not (false).
 *
 * @param {number} n A number.
 * 
 * @return {boolean} Whether a given number is odd.
 */
rune.util.Math.isOdd = function(n) {
    return (parseInt(n, 10) & 1) !== 0;
};

/**
 * Returns whether a number is power of two (true) or not (false).
 * 
 * @param {number} n A number.
 * 
 * @return {boolean} Whether a given number is power of two.
 */
rune.util.Math.isPowerOfTwo = function(n) {
    return (n & (n - 1)) === 0;
};

/**
 * Returns a random floating point number.
 *
 * @param {number} [min] Minimum number.
 * @param {number} [max] Maximum number.
 * 
 * @return {number} A random number between the minimum and maximum value.
 */
rune.util.Math.random = function(min, max) {
    min = (typeof min === "number") ? min : Number.MIN_VALUE;
    max = (typeof max === "number") ? max : Number.MAX_VALUE;
    
    return Math.random() * (max - min) + min;
};

/**
 * Returns a random integer.
 *
 * @param {number} [min] Minimum number.
 * @param {number} [max] Maximum number.
 * 
 * @return {number} A random number between the minimum and maximum value.
 */
rune.util.Math.randomInt = function(min, max) {
    min = (typeof min === "number") ? min : Number.MIN_VALUE;
    max = (typeof max === "number") ? max : Number.MAX_VALUE;

    return Math.round((Math.random() * (max - min)) + min);
};

/**
 * Converts an angle in radians to degrees.
 *
 * @param {number} radians Angle described in radians.
 * 
 * @return {number} Specified angle in degrees.
 */
rune.util.Math.radiansToDegrees = function(radians) {
    return radians * rune.util.Math.RAD_TO_DEG;
};

/**
 * Returns the sine of n.
 * 
 * @param {number} n A number (given in radians).
 * 
 * @return {number} The sine of the given number.
 */
rune.util.Math.sin = function(n) {
    n *= 0.3183098862;

    if (n > 1) {
        n -= (Math.ceil( n) >> 1) << 1;
    } else if (n < -1) {
        n += (Math.ceil(-n) >> 1) << 1;
    }

    if (n > 0) {
        return n * (3.1 + n * (0.5 + n * (-7.2 + n * 3.6)));
    } else {
        return n * (3.1 - n * (0.5 + n * ( 7.2 + n * 3.6)));
    }
};

/**
 * Returns a number within a specified range.
 *
 * @param {number} num A number.
 * @param {number} min Minimum number.
 * @param {number} max Maximum number.
 * 
 * @return {number} A number between the minimum and maximum value.
 */
rune.util.Math.wrap = function(num, min, max) {
    var range = max - min + 1;

    if (num < min) {
        num += range * parseInt(((min - num) / range + 1), 10);
    }

    return min + (num - min) % range;
};