2016-11-21 177 views
1

我正在解決一個問題,其中任務是在用戶提到的給定行處輸出pascal三角形的結果。將int轉換爲無符號long long

https://leetcode.com/problems/pascals-triangle-ii/

我寫我的溶液,其存儲了巨大的階乘結果的問題。

vector<int> getRow(int rowIndex) { 

      vector<int> v; 

      int C = 1; 
      v.push_back(1); 

       for (int i = 1; i <= rowIndex; i++) 
       { 
        printf("%d ", C); 
        C = C * (rowIndex +1 - i)/i; 
        v.push_back(C); 
       } 

    return v; 
} 

通過這些問題去,

What range of values can integer types store in C++

How many bytes is unsigned long long?

,並通過一些其他渠道去,我做了如下改變,這給了我需要的結果。

C = (unsigned long long)C * (rowIndex +1 - i)/i; 

由於「C」是一個類型INT和我的矢量V存儲INT的,我想知道爲什麼會鑄造無符號長長仍然給我有效的結果。

+1

只是一個猜測......也許是因爲經過'i'除法後,數值會回到'int'是一個完整且合法的值的區域? –

回答

3

子表達式C * (rowIndex +1 - i)可以溢出在您的分裂之前。通過將C轉換爲更大的數據類型,整個表達式就變成了這種類型,所以乘法不會溢出。然後在與i劃分後,結果再次轉換爲int,但由於該劃分,它在int的範圍內。

請注意,這僅適用於您當前擁有的值。如果你繼續使用更高的值,那麼遲早你會發生溢出,這種劇情無法修復。

+0

我對如何將一個無符號long long值存儲在一個int變量中感到困惑......對於長時間打破我的頭腦感覺超級愚蠢。 –

1

當你說

(unsigned long long)C 

你是不是做實際的變量C無符號很長很長。你只是在說這樣做時

C * (rowIndex +1 - i)/i; 

把C(在右邊)當作unsigned long long。也就是說,只有臨時空間來保存C,然後保持與(rowIndex + 1 - i)的乘法運算,然後與i的分割在一個很大的空間完成。如果整個結果大於整數可能具有的值,則這也不起作用。

+0

非常擔心無符號長整型向int整型的轉變,我並沒有最終意識到該值可能會落入範圍內。 –