2017-01-21 52 views
-6

我得到這個函數計算階乘給出一個整數:爲什麼我的函數在添加正數時返回負數?

long iterFact(long number) { 
    long factorial = 1; 

    for (long i = 1; i <= number; i++) 
     factorial *= i; 

    return factorial; 
} 

但是當我通過例如20作爲參數,它返回一個負數,我認爲這將是因爲數字變得很長,但即使將所有內容從int更改爲long,我仍然得到一個負數。

+3

整數溢出。此外,它是因式而非斐波那契。 – zch

+0

因爲階乘增長迅速並打破整數限制。 –

+1

_「我以爲這是因爲數字太長了,但我仍然得到一個負數,因爲即使改變了從int到long的所有內容,」_' long'也不是無限的。而不是猜測,檢查每個值,並找出你的類型是否足夠大 –

回答

3

你不是數字,而是乘以它們。事實上,你沒有計算斐波那契數列,但是階乘因子;-)

因子增長非常快:20! (2432902008176640000)不適合您的系統上的long(32位,可能是Windows),因此其中一個乘法會導致算術溢出,C標準明確將其描述爲未定義的行爲。在你的系統上,計算可能以2^32爲模進行,結果可能是負數,但這不是標準保證的。

切換到保證至少有64位的unsigned long long類型,可以讓您計算20!,但在21!之後不久會失敗。實際上2432902008176640000略小於2^63-1,所以輸入long long就足夠了。

0

我假設你是平均因子,而不是斐波那契數列?

在大多數現代系統中,intlong都是32位,這可以表示數量高達約20億。 20階乘約爲20億美元。嘗試使用64位的long long

+2

_「在大多數現代系統上_ _在大多數現代_commodity_系統上。今天開發的大多數現代系統實際上都有16位「int」。最好完全避免這類陳述。 –

+0

感謝您的更正。 – hnau

0

這是一個整數溢出;因爲你的變量是有符號的,並且由於符號位是最重要的變量,所以在某些時候你會溢出變量。其實20!是一個龐大的數字。您應該嘗試將您的變量聲明爲unsigned long,並將其打印出來。

+0

隨機猜測不是隨機猜測引起的問題的解決方案。 –

+0

這是**一個**可能的解釋。但是隨着有符號整數溢出調用未定義的行爲,還有許多其他原因。 – Olaf

+0

對不起,我會在未來回答問題之前加倍小心。感謝精確性,我沒有意識到溢出導致了一個不確定的行爲,我認爲最重要的位被忽略了,但最少的位仍然是連貫的;我在我的機器上進行了一些測試以觀察,並且結果中沒有明顯的邏輯。 –

0

這是有符號的類型的溢出

INT可以是4個字節:-2 147 4832分之648147 483 647

可能是8字節:-9223372036854775808/9223372036854775807

int/long可以被簽名爲a nd無符號

+0

在OP的情況下,'long'不是64位,但可能只是32位,因此算術溢出。 – chqrlie

+0

'int'可以是1個字節或37位等,並且'int'和'long'都不可以無符號。 – Olaf

相關問題