2016-11-21 322 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整型的转变,我并没有最终意识到该值可能会落入范围内。 –