// add number formatting to number types
Number.prototype.format = function(format) {
    if (! (typeof(format) == 'string')) {return '';} // sanity check
    
    var hasComma = -1 < format.indexOf(','),
    psplit = format.replace(/[^0-9.]/g, '').split('.'),
    that = this;
    
    // compute precision
    if (1 < psplit.length) {
        // fix number precision
        if (that < 0.01) that = that.toFixed(3);
        else that = that.toFixed(psplit[1].length);
    }
    // error: too many periods
    else if (2 < psplit.length) {
        throw('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
    }
    // remove precision
    else {
        that = that.toFixed(0);
    }
    
    // get the string now that precision is correct
    var fnum = that.toString();
    
    // format has comma, then compute commas
    if (hasComma) {
        // remove precision for computation
        psplit = fnum.split('.');
	
        var cnum = psplit[0],
        parr = [],
        j = cnum.length,
        m = Math.floor(j / 3),
        n = cnum.length % 3 || 3; // n cannot be ZERO or causes infinite loop
	
        // break the number into chunks of 3 digits; first chunk may be less than 3
        for (var i = 0; i < j; i += n) {
	    if (i != 0) {n = 3;}
	    parr[parr.length] = cnum.substr(i, n);
	    m -= 1;
        }
	
        // put chunks back together, separated by comma
        fnum = parr.join(',');
	
        // add the precision back in
        if (psplit[1]) {fnum += '.' + psplit[1];}
    }
    
    // replace the number portion of the format with fnum
    return format.replace(/[\d,?.?]+/, fnum);
};


Number.prototype.format_unit = function(unit) {
    var unit_prefixes = {
	'-15':'f',
	'-12':'p',
	'-9':'n',
	'-6':'µ',
	'-3':'m',
	'0':'',
	'3':'k',
	'6':'M',
	'9':'G',
	'12':'T'
    };
    
    var exponent = 3*Math.floor(Math.log(Math.abs(this))/Math.log(10)/3);
    if (this==0) exponent=0;
    
    var reduced = Math.round(this/Math.pow(10,exponent)*10)/10;
    var unit_prefix = unit_prefixes[exponent];
    
    return reduced+' '+unit_prefix+unit;
};
