Daily Archives: May 16, 2012

Code of the Day: Javascript Decimal Expansion a.k.a Division


Today’s Code of the Day is about decimal expansion, which is just division.

So you might be asking yourself, “if decimal expansion is divsion. Then why not use a/b?”.
Well the problem is that Javascript has a ton of problems when dealing with floating point operations because of the way they are stored.

Examples:

var a = 1/3;
a.toString()     // returns  "0.3333333333333333"
a.toFixed(25);   // returns "0.3333333333333333148296163"
0.1 + 0.2;       // returns 0.30000000000000004

Source for decimalExpansion()

// borrowed from jQuery 1.7.2
var isNumeric = function(val){
	return !isNaN(parseFloat(val)) && isFinite(val);
};
/**
* @author Larry Battle <http://bateru.com/news/contact-me>
* @date May 16, 2012
* @license MIT and GPLv3
*/
//decimalExpansion returns a string representation of a divided by b to a fixed length.
// All the paramaters must be whole numbers.
// Example: decimalExpansion( 1, 3, 3 ) === "0.333"
var decimalExpansion = function (top, bottom, decLength) {
	if (!isNumeric(top) || !isNumeric(bottom) || !isNumeric(decLength) || !bottom) {
		return null;
	}
	var sign = ((top * bottom) != Math.abs(top * bottom)) ? "-" : "";
	top = Math.abs(top);
	bottom = Math.abs(bottom);
	decLength = Math.abs(decLength);
 
	var result = Math.floor(top / bottom),
	remainder = top % bottom,
	maxDecimal = 100,
	i = Math.min(Math.max(0, decLength), maxDecimal) + 1;
 
	if (1 < i) {
		result += ".";
		while (i--) {
			top = remainder * 10;
			remainder = top % bottom;
			result += "" + Math.floor(top / bottom);
		}
		result = result.replace(/(\d)(\d)$/, function (match, a, b) {
				return +b > 4 ? +a + 1 : a;
			});
	}
	return sign + result;
};

Test cases:

Demo:

Here are excellent links over the topic.
Wolfram MathWorld: Decimal Expansion
Wikipedia.org: Fraction (mathematics)
Oracle: What Every Computer Scientist Should Know About Floating-Point Arithmetic

Larry Battle

Hello, I'm Larry Battle and I love to program, fix problems and discover new technologies. Check out my stackoverflow and github accounts. I also do book reviews on amazon.com. I'm not the best of writers but I do enjoy spreading my knowledge through my short blogs at bateru.com/news. So please leave some feedback. It would be greatly appreciated.

More Posts - Website

Follow Me:
Twitter