假设1杯等于2.36 dl。 我想要一个函数,该函数可以输入代表dl的杯子的小数,并输出分数的杯子数。
这是我到目前为止所得到的:
var dl = 2.36;
cupToFraction(.78); // 1/3 cup
cupToFraction(2.36); // 1 cup
cupToFraction(4.72); // 2 cups
cupToFraction(8.26); // 3 1/2 cups
function cupToFraction (cup) {
var deci = (cup / dl);
alert(deci);
}
答案 0 :(得分:1)
一种选择是使用连续分数获得有理逼近:
var dl = 2.36;
function cupToFraction (cup) {
var deci = (cup / dl);
var integerPart = Math.floor(deci);
deci -= integerPart;
deci = 1 / deci;
var c = [];
// Tune these parameters for how far you want the continued fraction to go
// 3 means at most 3 terms; 10 means no terms higher than 10.
for (let i = 0; i < 3 && deci < 10; ++i) {
let f = Math.floor(deci);
c.push(f);
deci -= f;
deci = 1/deci;
}
if (c.length === 0) return [integerPart, 0, 1];
var p = 1, q = c.pop();
while (c.length > 0) {
var int = c.pop();
p = q*int + p;
[p, q] = [q, p];
}
// Handle case like cupToFraction(2.35)
if (p === q) { p = 0; integerPart++; }
return [integerPart, p, q];
}
它返回一个元素为integerPart, numerator, denominator
的数组。例如,cupToFraction(8.26)
为[3, 1, 2]
赋予3 1/2
。我确定可以对该算法进行更优化,但是现在必须这样做。
答案 1 :(得分:0)
使用Fraction.js的解决方案可能更强大,更简单:
function cupToFraction(cup) {
return new Fraction(cup).div(2.36).simplify(0.1).toFraction(true);
}
cupToFraction(.78); // "1/3"
cupToFraction(2.36); // "1"
cupToFraction(4.72); // "2"
cupToFraction(8.26); // "3 1/2"
您可以根据需要进行一切,但是输入数字会使用Farey序列(非常稳定)转换为分数,并且可以像这样传递分数:
cupToFraction("3 2/12"); // "1 1/3"
精度可以通过simplify(eps)
的参数进行控制。