2012-07-31 79 views
1

此代码应该简化分数并将小数转换为分数,但是当我放入分数较大的分数(数字超过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的工作,因为你可以把大dividens分数,并显示您的快速渲染结果时,它不会冻结一位。

http://wolframalpha.com/

谁能解决这个代码用更大的数字工作。我想你不得不使用与我的算法不同的算法。另一方面,有没有人知道WA的算法,或者可以指导我到一个我可以找到的网站?

+0

你能给出一个“大”数字的例子吗? – Pointy 2012-07-31 17:31:14

+0

分数大于7或8位数的分数。 – 0x499602D2 2012-07-31 17:33:01

+0

看看下面的关于在JavaScript中使用类型化的64位数组的教程,我不确定它是否完全足够,但它是我知道的最好的http://www.html5rocks.com/en/tutorials/webgl/typed_arrays/ – 2012-07-31 17:33:42

回答

2

更换fraction.factor()与此:

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

这是欧几里德的算法,它可以作为一个伟大的介绍数论。它将运行方式比您的迭代方法更快。

+0

你说得对。它的工作速度相当快。 – 0x499602D2 2012-07-31 17:47:42

+0

你能解释它的作用吗?谢谢! – 0x499602D2 2012-07-31 22:17:31

+0

@大卫[Wikipedia page](http://en.wikipedia.org/wiki/Euclidean_algorithm)是丰富的,如果通常过于密集。这个想法来自你可以用基本数论证明的一些相当简单的事情。通过迭代将较小数字分成更大数字的其余部分,您最终会达到一个数字是另一个数字的倍数。那么这个数字将会平均分配所有的步骤,直到原来的两个数字。 (当然,答案可能是1,这意味着数字是相对主要的。) – Pointy 2012-07-31 22:24:06