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!
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