$(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>