2009-07-17 40 views
1

相當容易,如果BigInteger的數量是543,我希望它切斷了最後一位,使其54Java的BigInteger,以切斷最後一位

兩種簡單的方法來做到這一點可能是:

  1. 使用字符串,獲取子字符串並使用新值創建新的biginteger。
  2. 使用BigIntegers劃分方法與標記10(10分之543= 54.3 => 54)

的事情是我將與課程的大整數來執行此的次數很多

我的猜測是,玩弄字符串會慢一些,但是我再也沒有使用Bigintegers,也不知道「除法」操作有多昂貴。

速度在這裏是必不可少的,實現這個速度的最快方法是什麼(內存速度沒有問題)?

其他解決方案也是受歡迎的。

+0

您真正知道的唯一方法 - 並且真正知道問題的重要性 - 是分析您的應用程序。我懷疑toString()會比較慢,但實際上並沒有嘗試過。 – kdgregory 2009-07-17 17:50:22

+5

如果你威脅要削減大整數的最後一位數字,我認爲執行速度將是你最擔心的問題。我聽說他們很狡猾,反擊! – Totty 2009-07-17 17:55:48

+0

@Totty哈哈,讓我笑了:D – Milan 2009-07-17 17:58:03

回答

3

除以10比使用子串操作快得多。使用以下基準,我得到大約161倍(比例與位數成正比)

long divTime = 0; 
    long substrTime = 0; 
    final int bitsCount = 1000; 

    for (int i = 0; i < 1000; ++i) { 
     long t1, t2; 
     BigInteger random = new BigInteger(bitsCount, new Random()); 

     t1 = System.currentTimeMillis(); 
     random.divide(BigInteger.TEN); 
     t2 = System.currentTimeMillis(); 
     divTime += (t2 - t1); 

     t1 = System.currentTimeMillis(); 
     String str = random.toString(); 
     new BigInteger(str.substring(0, str.length() - 1)); 
     t2 = System.currentTimeMillis(); 
     substrTime += (t2 - t1); 
    } 

    System.out.println("Divide: " + divTime); 
    System.out.println("Substr: " + substrTime); 
    System.out.println("Ratio: " + (substrTime/divTime)); 
5

除以10最有可能會更快。

0

最快的方法是用有效的內部分割實現將數字除以10。該操作的內部是在幕後,但肯定是不平凡的,因爲該數字存儲在base-2中。

-7

如果性能是至關重要的...不要用java

在其編譯成機器代碼語言(如C或C++)的整數除法是一個巨大的因素更快。字符串操作使用(或可以使用)內存分配,因此速度很慢。

我敢打賭,在Java int分區也會更快。否則他們的虛擬機執行是非常奇怪的。

2

如果您創建一個數字爲10的靜態BigInteger,然後用它除以10,那麼這可能是最快的方法。它每次都會創造一個臨時的新BigInteger。

子字符串的問題在於你實際上每創建一個新字符串都會更慢,更不用說慢速迭代通過字符串來獲取其子字符串。

1

最快的實現方式可能是使用內部表示使用基數10的數據類型,即某種BCD。然後,除以10將意味着丟棄最後一個字節(或者,如果以正確的方式實現,則甚至只是遞增/遞減索引)。

當然,你必須從頭開始實施所有的算術和其他操作,這使得這項工作很多。

0

即使提出這個問題也許爲時過早。以明顯的方式去做(除以十),然後進行基準測試,並在需要時對其進行優化。轉換爲字符串表示並返回將會慢得多。

0

單獨的toString()可能比子字符串慢。

0

不同的人都說,除以10會比轉換爲字符串並取得子字符串更快。要理解爲什麼,只需考慮從BigInteger轉換爲String的計算,反之亦然。例如:

/* simplified pseudo code for converting +ve numbers to strings */ 
StringBuffer sb = new StringBuffer(...); 
while (number != 0) { 
    digit = number % 10; 
    sb.append((char)(digit + '0')); 
    number = number/10; 
} 
return sb.toString(); 

需要注意的重要一點是,從多個轉換成字符串需要通過反覆10.除以實際上分割數正比於日誌10(數量)。沿着另一個方向進行log10(數字)乘法運算。很顯然,這比單個分區的計算量多10個。