Search code examples
javascriptfractions

JavaScript: Show decimals in fraction format


I want to make a ml to oz converter and present the remaining decimal in fraction formats 1/2, 1/3, 2/3, etc... As example 50 ml would be 1 2/3 oz. The integer is on the left side, and the decimal on the right side is showing in fraction format.

I understand that the formula to convert ml to oz is:

ml * 0.03381

50 * 0.03381 = 1.6905. The decimal .6905 would be rounded to 2/3 (0.66666666666) so the fraction part is presented in a readable format.

Thanks!


Solution

  • You can create a approximateFraction function, that can take in a decimal and a maxDenominator, and you can use that in a ml to Oz converter. Right now this limits the maximum denominator of conversion to 10. and that gives 50ml -> 1 7/10. You can reduce the maximum denominator to a lower number if you set it to 5 or 6 then it will give you 1 2/3 instead.

    function approximateFraction(decimal, maxDenominator) {
      let numerator = 1;
      let denominator = 1;
      let minError = Math.abs(decimal - (numerator / denominator));
    
      for (let d = 2; d <= maxDenominator; d++) {
        const n = Math.round(decimal * d);
        const error = Math.abs(decimal - (n / d));
    
        if (error < minError) {
          minError = error;
          numerator = n;
          denominator = d;
        }
      }
    
      return [numerator, denominator];
    }
    
    function mlToOzAndFraction(ml, maxDenominator) {
      const oz = ml * 0.033814;
      const integerPart = Math.floor(oz);
      const decimalPart = oz - integerPart;
      const [numerator, denominator] = approximateFraction(decimalPart, maxDenominator);
      const ozFraction = numerator !== 0 ? `${numerator}/${denominator}` : '';
      return `${integerPart}${ozFraction ? ' ' : ''}${ozFraction} oz`;
    }
    
    console.log('Max denominator 10: ', mlToOzAndFraction(50, 10)); // 50ml -> 1 7/10 oz
    console.log('Max denominator 5: ', mlToOzAndFraction(50, 5)); // 50ml -> 1 2/3 oz