如何使此代码适用于更大的数字?

Posted

技术标签:

【中文标题】如何使此代码适用于更大的数字?【英文标题】:How do I make this code work with larger numbers? 【发布时间】:2012-07-31 17:30:40 【问题描述】:

此代码应该简化分数并将小数转换为分数,但是当我输入具有较大除数(超过 7 或 8 位的数字)的分数时,它会滞后很多。

http://jsfiddle.net/SuperBoi45/vQjgx/

var fraction = ;

fraction.simplify = function( frac ) 
    if ( frac.indexOf('/') < 0 ) return frac;
    var numbers = frac.split('/'),
        factor = null,
        parsed = null;

    return (function run( nums ) 
        factor = fraction.factor( nums[0], nums[1] );

        if ( factor === 1 ) 
            parsed = [ Math.abs(nums[0]), Math.abs(nums[1]) ];

            if ( nums[1] === 1 ) return nums[0];
            else if ( nums[1] === -1 ) return -nums[0];
            else if ( nums[0] < 0 && nums[1] < 1 ) return parsed[0] + '/' + parsed[1];
            else if ( nums[0] < 0 || nums[1] < 0 ) return '-' + parsed[0] + '/' + parsed[1];
            else return nums[0] + '/' + nums[1];
        

        return run( [ nums[0] / factor, nums[1] / factor ] );
    )( numbers );
;
fraction.convert = function( decimal ) 
    var j = decimal.length - 1,
        b = "1";

    if ( decimal.indexOf(".") >= 0 && decimal.length > 1 ) 

        while ( decimal.charAt( j ) != "." ) 
            b += "0";
            j--;
        

        decimal *= b;
        decimal += "/" + b;

    

    return decimal;

;
fraction.factor = (function() 

    var greater = function( a, b ) 
        return a > b ? a : b;
    ;

    return function( x, y ) 
        x = Math.abs( x );
        y = Math.abs( y );

        var a = greater( x, y ),
            i = a,
            b = ( i === x ) ? y : x;

        for ( ; i >= 1; i-- ) 
            if ( a % i === 0 && b % i === 0 ) return i;
        

        return 1;
    ;

)();​

我试图让它像 Wolfram Alpha 一样工作,因为您可以放入具有大除数的分数,并且在向您显示其快速渲染结果时它不会冻结一点。

http://wolframalpha.com/

任何人都可以修复此代码以使用更大的数字。我想你必须使用与我不同的算法。另一方面,有没有人知道 WA 的算法或者可以将我引导到我可以找到的网站?

【问题讨论】:

你能举一个“大”数字的例子吗? 除数超过 7 或 8 位的分数。 看看下面关于在 javascript 中使用类型化 64 位数组的教程,我不确定它是否完全足够,但它是我所知道的最好的 html5rocks.com/en/tutorials/webgl/typed_arrays 您可能想查找 Euclid 的最大公分母算法。他是个很聪明的人。 【参考方案1】:

用这个替换fraction.factor()

function gcd(a, b) 
    if (b > a) return gcd(b, a);
    if (b === 0) return a;
    return gcd(b, a % b);
;

这是欧几里得的算法,它可以作为数论的一个很好的介绍。它的运行速度会比您的迭代方法快方式

【讨论】:

你能解释一下它的作用吗?谢谢! @David 很好,Wikipedia page 提供了丰富的信息,如果通常过于密集。这个想法来自一些可以在基本数论中证明的相当简单的事情。通过迭代将较小数字除以较大数字的其余部分,您最终会达到一个数字是另一个数字的倍数的地步。然后,该数字将平均分配其间的所有步骤,一直到最初的两个数字。 (当然,答案可能是 1,这意味着数字互质。) 而且它更快,因为它不是以 1 迭代,而是因为它正在解决除法问题,所以它“跳跃”了一大步。也就是说,作为可能除数进行测试的数字会相对较快地变小。 @David 如果您有兴趣,this book(Elementary Number Theory by Underwood Dudley)是对该主题的一个很好的介绍。数论真的很吸引人。我是业余爱好者:-)

以上是关于如何使此代码适用于更大的数字?的主要内容,如果未能解决你的问题,请参考以下文章

如何在旧代码库上使用 gitversion

txt文件中最常用的词

如何制作中心更大的旋转木马? (扑)

如何使此代码在单个文件夹中运行多个图像?

如何在 UITabBar 中显示六个 TabBarItem

如何使用 Perl 处理大数据文件?