2016-02-16 31 views
1

如果我想遍歷所有長的範圍內,我會做ingenually:如何正確遍歷所有長型範圍

for (long i = long.MinValue; i <= long.MaxValue; ++i) 
{ 
    // Do something 
} 

但它永遠循環!

例如,如果我這樣做:

for (byte b = byte.MinValue; b <= byte.MaxValue; ++b) 
{ 
    // Do something 
} 

它永遠循環太多,但我解決這樣的:

for (int i = byte.MinValue; i <= byte.MaxValue; ++i) 
{ 
    byte b = Convert.ToByte(i); 

    // Do something 
} 
  1. 隨着long型我該怎麼辦?
  2. long類型如果我不增加1,但距離更遠,我該如何實現相同?
  3. 這些「想法」是循環使用的類型範圍是否正確,是否存在一些需要警告的問題,或者我可以做得更好?
+1

您確定要循環使用所有long:s嗎?即使你每秒循環超過1萬億次,通過它們仍需要大約585年的時間。 – johusman

+1

在真實情況下,我會「跳」,我不會做++ i。我問這個問題僅僅是爲了好奇 –

回答

5

在前兩個示例中,由於數字範圍溢出,循環會一直持續。

i(第一實施例)或b(第二實施例)超過可以被存儲在long(第一示例)的最大值或byte(第二實施例),其值溢出到由該類型和可存儲的值最小循環開始反覆。

切記:在for -loop中,首先檢查循環條件,然後計數器遞增。如果計數器在遞增期間溢出,則後續的循環條件檢查仍然計算爲true

爲了讓您的例子,試試:

for (long i = long.MinValue; i <= long.MaxValue; i++) 
{ 
    if (i == long.MaxValue) 
    { 
     break; 
    } 
} 

如果你想在更大的措施來增加,試試:

const long step = 90000000000; 

for (long i = long.MinValue; i <= long.MaxValue;) 
{ 
    // check if loop counter overflows when incrementing by the step 
    if (i + step < i) 
    { 
     break; 
    } 
    // otherwise it is safe to increment it 
    else 
    { 
     i += step; 
    } 
} 
+0

如果我不增加一個呢? –

+0

現在我更新了我的答案。 –

4

這是由integer overflow引起的,當您嘗試增量通過MaxValue時。你可以代替試試這個:

long i = long.MinValue; 
do 
{ 
    // Do something 
} while (i++ != long.MaxValue); 

這樣,i值檢查它的遞增之前,循環正確終止。

+0

我喜歡這種方法,儘管你應該在循環中包含i ++語句並且有while(i!= long)。MaxValue)否則你會錯過最後一個值,因此有一個錯誤:) –

+0

如果我不增加一個? –

+1

@DanielSiebert我不認爲你會錯過最後一個值......在條件檢查之前,'i'不會改變,所以當檢查失敗時(因爲'i == long.MaxValue'),它已經有了最後一次迭代的價值。 –

1

你可以使用BigInteger,讓您的環形圖案相同,避免溢出:

for (BigInteger i = long.MinValue; i <= long.MaxValue; ++i) 
{ 
    // Do something 
} 

我沒有基準測試,但我會想象t這樣做會有明顯的性能損失。