5
\$\begingroup\$

I wrote a simple script that converts a decimal to a mixed number, proper, or improper fraction depending on the inputed decimal.

It works but I think it could be improved as it hangs when large decimals are used. Please review and let me know how I could improve and simplify it. Thanks.

My script on JS Bin: http://jsbin.com/axulob/1/edit

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script>
window.onload = function() {
 var factor; 
 // Finds the highest common factor of 2 numbers
 function highestCommonFactor() {
 for (factor = numerator; factor > 0; factor--) {
 if ((numerator % factor == 0) && (denominator % factor == 0)) {
 return factor;
 }
 }
 }
 // Enter a decimal to convert to a fraction
 var decimal = "1.75";
 // Split the decimal
 var decimalArray = decimal.split(".");
 var leftDecimalPart = decimalArray[0];
 var rightDecimalPart = decimalArray[1];
 // Save decimal part only for later use
 var decimalOnly = "0." + rightDecimalPart;
 // Find the decimal multiplier
 var multiplier = "1";
 for (var i = 0; i < rightDecimalPart.length; i++) {
 multiplier += "0";
 }
 // Create numerator by multiplying the multiplier and decimal part together
 var numerator = Number(multiplier) * Number(decimalOnly);
 var denominator = multiplier;
 // Find the highest common factor for the numerator and denominator
 highestCommonFactor();
 // Simplify the fraction by dividing the numerator and denominator by the factor
 var numerator = Number(numerator) / Number(factor);
 var denominator = Number(denominator) / Number(factor);
 // Output as a mixed number fraction (depending on input)
 var mixedNumber = leftDecimalPart + " " + numerator + "/" + denominator;
 // Output as a proper fraction or improper fraction (depending on input)
 var numerator = numerator + (leftDecimalPart * denominator);
 var fraction = numerator + "/" + denominator;
 // Display solution
 document.getElementById("divSolution").innerText = fraction;
}
</script>
</head>
<body>
<div id="divSolution"></div>
</body>
</html>
asked Jan 8, 2013 at 0:36
\$\endgroup\$
1
  • \$\begingroup\$ Why not use an existing fraction library instead? Here's one github.com/LarryBattle/Ratio.js \$\endgroup\$ Commented Jan 10, 2013 at 16:38

1 Answer 1

4
\$\begingroup\$
  1. highestCommonFactor should take 2 integers as parameter instead of relying on the variable numerator and `denominator'. Also, you could find it using Euclid'a algorithm.

  2. I am wrong is saying that this piece of code :

    var rightDecimalPart = decimalArray[1];
    // Save decimal part only for later use
    var decimalOnly = "0." + rightDecimalPart;
    // Find the decimal multiplier
    var multiplier = "1";
    for (var i = 0; i < rightDecimalPart.length; i++) {
     multiplier += "0";
    }
    // Create numerator by multiplying the multiplier and decimal part together
    var numerator = Number(multiplier) * Number(decimalOnly);
    

is here to transform a number such as 78924 in 0.78924 and then check that have to multiply it by 100000 to get an integer which is ... 78924.

Edit After a first cleanup, I get :

function highestCommonFactor(a,b) {
 if (b==0) return a;
 return highestCommonFactor(b,a%b);
}
var decimal = "1.75";
var decimalArray = decimal.split(".");
var leftDecimalPart = decimalArray[0];
var rightDecimalPart = decimalArray[1];
var denominator = "1";
for (var i = 0; i < rightDecimalPart.length; i++) {
 denominator += "0";
}
document.getElementById("debug").innerText = denominator;
var factor = highestCommonFactor(rightDecimalPart, denominator);
// Simplify the fraction by dividing the numerator and denominator by the factor
var denominator = Number(denominator) / Number(factor);
var numerator = (Number(rightDecimalPart) / Number(factor)) + (leftDecimalPart * denominator);
// Display solution as a proper fraction or improper fraction (depending on input)
document.getElementById("divSolution").innerText = numerator + "/" + denominator;

I'll try to go a step further.

Edit 2 After a rewriting of the calculation, here's what I got :

function highestCommonFactor(a,b) {
 if (b==0) return a;
 return highestCommonFactor(b,a%b);
}
var decimal = "1.75";
var decimalArray = decimal.split(".");
var leftDecimalPart = decimalArray[0]; // 1
var rightDecimalPart = decimalArray[1]; // 75
var numerator = leftDecimalPart + rightDecimalPart // 175
var denominator = Math.pow(10,rightDecimalPart.length); // 100
var factor = highestCommonFactor(numerator, denominator); // 25
denominator /= factor;
numerator /= factor;
document.getElementById("divSolution").innerText = numerator + "/" + denominator;
answered Jan 8, 2013 at 1:21
\$\endgroup\$
3
  • \$\begingroup\$ Thanks for taking the time to go through my code. Could you explain how the function highestCommonFactor works? \$\endgroup\$ Commented Jan 8, 2013 at 21:31
  • \$\begingroup\$ I understand Euclid'a algorithm but I don't get how it's returning 2 values (return highestCommonFactor(b,a%b))? I assume it's multiplying (b) * ((a%b)). \$\endgroup\$ Commented Jan 8, 2013 at 22:39
  • \$\begingroup\$ The method highestCommonFactor takes 2 (integer) arguments and return 1 (integer) value. I used the formula from en.wikipedia.org/wiki/… to write this recursive function. \$\endgroup\$ Commented Jan 9, 2013 at 0:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.