$(function () {
// main source
// from jquery 1.7.2
var isNumeric = function (val) {
return !isNaN(parseFloat(val)) && isFinite(val);
};
// has problems with "361111111111111111 / 86".
// real answer = 4.19896640826873384884e15
// javascript gives = 4198966408268734.00000000000000000000
// decimalExpansion gives 4198966408268734.7674418604651
/**
* @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.
test("test for invalid inputs", function () {
equal(decimalExpansion("s", 3, 1), null);
equal(decimalExpansion(1, "s", 1), null);
equal(decimalExpansion(1, "s", -1), null);
equal(decimalExpansion(1, 0, 1), null);
});
test("test whole numbers result (decLength = 0)", function () {
equal(decimalExpansion(0, 3, 0), "0");
equal(decimalExpansion(3, 3, 0), "1");
equal(decimalExpansion(9, 3, 0), "3");
equal(decimalExpansion(-9, -3, 0), "3");
equal(decimalExpansion(-9, 3, 0), "-3");
equal(decimalExpansion(9, -3, 0), "-3");
});
test("test postive numbers", function () {
equal(decimalExpansion(1, 3, 1), "0.3");
equal(decimalExpansion(1, 3, 2), "0.33");
equal(decimalExpansion(1, 3, 3), "0.333");
equal(decimalExpansion(1, 3, 200), decimalExpansion(1, 3, 100));
equal(decimalExpansion(1, 33, 4), "0.0303");
equal(decimalExpansion(4, 3, 3), "1.333");
equal(decimalExpansion(40, 3, 3), "13.333");
});
test("test negative numbers", function () {
equal(decimalExpansion(1, -3, 1), "-0.3");
equal(decimalExpansion(-1, 3, 2), "-0.33");
equal(decimalExpansion(1, -3, 3), "-0.333");
equal(decimalExpansion(-1, 33, 4), "-0.0303");
equal(decimalExpansion(-4, 3, 3), "-1.333");
equal(decimalExpansion(-40, 3, 3), "-13.333");
});
test("test rounding", function () {
equal(decimalExpansion(100, 11, 3), "9.091");
equal(decimalExpansion(1, 3, 0), "0");
equal(decimalExpansion(1, 10, 0), "0");
equal(decimalExpansion(10, 18, 0), "0");
equal(decimalExpansion(1, 7, 0), "0");
equal(decimalExpansion(5, 49, 2), "0.10");
equal(decimalExpansion(5, 49, 2), "0.10");
});
// user controls events.
var updateOutput = function () {
var a = $("#input-numerator").val() || 1;
var b = $("#input-denominator").val() || 1;
var decLen = $("#decimalLength").val() || 1;
$("#javascript-output").html((a / b).toFixed(Math.min(Math.max(decLen, 0), 20)));
var val = decimalExpansion(a, b, decLen) || "You must type in a number.";
$("#decimalExpansion-output").html(val);
};
var rNum = function (val) {
return Math.floor((val || 1) * Math.random());
};
var generateExample = function () {
$("#input-numerator").val(rNum(100));
$("#input-denominator").val(rNum(100));
$("#decimalLength").val(rNum(100));
updateOutput();
};
$("#exampleButton").click(generateExample);
$(".inputs").keyup(updateOutput);
generateExample();
});
<!--
/**
* @author Larry Battle <http://bateru.com/news/contact-me>
* @date May 16, 2012
* @license MIT and GPLv3
*/
-->
<!DOCTYPE HTML PUBLIC>
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
</head>
<body>
<fieldset>
<legend>Javascript Demo: toFixed() vs decimalExpansion()</legend>
Fraction:
<input type="text" class="inputs" name="input-numerator" id="input-numerator" size="4"> / <input type="text" class="inputs" id="input-denominator" size="4"><br/><br/>
Decimal Length:
<input type="text" class="inputs" id="decimalLength">
<br/>
<dl>
<dt>Output from ( a/b ).toFixed( decimalLength )</dt>
<dd><textarea cols=45 id="javascript-output"></textarea><br/></dd>
</dl>
<dl>
<dt>Output from decimalExpansion( a, b, decimalLength )</dt>
<dd><textarea cols=45 id="decimalExpansion-output"></textarea><br/></dd>
</dl>
<input type="button" id="exampleButton" value="Generate Random Example"/>
<br/>
</div>
For more information visit: <a href="http://bateru.com/news/?s=decimal+expansion">Bateru.com/news/</a>
</fieldset>
<h1 id="qunit-header">Decimal Expansion example</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup, will be hidden</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
</body>
</html>