2012-07-31 38 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