是否有一个 JavaScript 函数可以减少一个分数

IT技术 javascript function fractions
2021-03-21 16:42:30

说我们有分数2/4,它可以减少到1/2

是否有可以进行还原的 JavaScript 函数?

6个回答
// Reduce a fraction by finding the Greatest Common Divisor and dividing by it.
function reduce(numerator,denominator){
  var gcd = function gcd(a,b){
    return b ? gcd(b, a%b) : a;
  };
  gcd = gcd(numerator,denominator);
  return [numerator/gcd, denominator/gcd];
}

reduce(2,4);
// [1,2]

reduce(13427,3413358);
// [463,117702]
@zzzzBov 一个有趣的边缘案例。当然可以添加if (isNaN(numerator) || isNaN(denominator)) return NaN;为第一行。
2021-04-25 16:42:30
这是一个非常优雅的gcd功能。唯一的变化,我建议是某种形式的输入检查的NaN作为gcd(NaN, 1)产生1在那里我会想到NaN或错误。
2021-04-30 16:42:30
有趣的事实,该解决方案使用 Euclid 算法来查找 GCD:en.wikipedia.org/wiki/Euclidean_algorithm
2021-05-07 16:42:30
有用!请注意,您可能希望对分子进行四舍五入以获得不超过分母的分数:reduce(Math.round(.25 * 4), 4))这将使小的(估计)值固定在您提供的最大分母上。
2021-05-13 16:42:30
效果很好,但为什么要指定gcd两次函数名称,然后将数值结果分配给同一个变量?这是糟糕的 JavaScript 礼仪。
2021-05-15 16:42:30

不,但是你可以很容易地自己写一个。本质上,您需要将分数的顶部和底部除以它们的“最大公分母”......您可以从欧几里德算法中计算出来。

阅读此处了解更多信息:http : //www.jimloy.com/number/euclids.htm

编辑:

代码(因为每个人似乎都在这样做,但这并不使用递归)

var FractionReduce = (function(){
    //Euclid's Algorithm
    var getGCD = function(n, d){
        var numerator = (n<d)?n:d;
        var denominator = (n<d)?d:n;        
        var remainder = numerator;
        var lastRemainder = numerator;

        while (true){
            lastRemainder = remainder;
            remainder = denominator % numerator;
            if (remainder === 0){
                break;
            }
            denominator = numerator;
            numerator = remainder;
        }
        if(lastRemainder){
            return lastRemainder;
        }
    };

    var reduce = function(n, d){
        var gcd = getGCD(n, d);

        return [n/gcd, d/gcd];
    };

    return {
            getGCD:getGCD,
            reduce:reduce
           };

}());

alert(FractionReduce.reduce(3413358, 13427));

要减少分数,请将分子和分母除以最大公因数。Phrogz 和 David 已经提供了源代码。

但是,如果您正在搜索用于处理分数的 javascript 库,那么这里有一些可供选择。

  1. 分数.js
  2. 数学理性
  3. Ratio.js
  4. Rational.js

这是一个使用Ratio.js的示例

var a = Ratio(2,4);

a.toString() == "2/4";
a.simplify().toString() == "1/2";    // reduce() returns a clone of the Ratio()
a.toString() == "2/4"; // Ratio functions are non-destructive.
有用,谢谢。我在这里发布了一个问题,询问这些库的相对效率:stackoverflow.com/questions/15840390/...
2021-04-23 16:42:30
@Omn 那么您是否已经使用 jsperf.com 分析了性能?如果您在打开票证时发现 Ratio.js 有任何问题,我会尝试修复它。github.com/LarryBattle/Ratio.js
2021-05-02 16:42:30
我没有创建和运行基准测试的经验。我最终只是进入代码并查看似乎具有更好的编码、注释和实现功能的内容。我最终选择了 Ratio.js,但从那以后我就没有机会在这个项目上工作了。如果我发现任何问题,我肯定会通知您,如果我能自己看到问题,我可能只会贡献错误修复。
2021-05-07 16:42:30

我知道这是一篇旧帖子,但我将接受的答案转换为循环解决方案而不是递归函数。这将具有更高的内存效率并且可能更快(不需要内存堆栈操作和执行调用)。

function reduce(numerator, denominator) {
    var a = numerator;
    var b = denominator;
    var c;
    while (b) {
        c = a % b; a = b; b = c;
    }
    return [numerator / a, denominator / a];
}

内存占用只有 5 个数字结构和一个简单的循环。

我知道已经有答案了,但我想分享一个 JS 库,我在寻找将十进制数转换为分数减少分数时发现的

该库调用Fraction.js,这对我真的很有帮助,并为我节省了很多时间和工作。希望它可以对其他人非常有用!