2013-12-22 89 views
1

我的程序出現了一個問題,它應該總計從1到70000(1 + 2 + 3 + 4 + ... + 69999 + 70000)的數字。我的程序可以將數字總和不超過65535,但是對於超過65535的總和,結果顯示負數,這是錯誤的。任何人都可以向我解釋爲什麼我的程序不能總和65535以上的數字嗎?C++數字總和

這是我的代碼:

#include <stdio.h> 

void sum(int *s) 
{ 
    *s=0; 
    int i=1; 
    int n=70000; 
    while(i<=n) 
    { 
     *s+=i; 
     i++; 
    } 
} 

main() 
{ 
    int s; 
    sum(&s); 

    printf("Suma prirodnih brojeva od 1 do 70000 je: %d\n",s); 
} 
+0

一旦工作。它值得在這裏要求代碼審查:codereview.stackexchange.com –

回答

9

你INT溢出它的能力。

試一下。最好是無符號的,因爲你不需要負數。

+1

然後用n(n + 1)/ 2替換循環:) – juanchopanza

+0

如果我理解你,你的意思是VOID ZBIR(LONG INT * S)? – user3127589

+1

如果他可以將數字總和保持在65535,那麼他的'int'是32位,這很可能和'long'完全一樣。 –

1

這是因爲整數可以容納高達原來的限制是-32767到32767 可以使用數據類型

你可以參考下面的數據類型的能力(即使它取決於編譯)

  • 短整型和int:-32,767至32,767
  • 無符號短整數和unsigned int:0至65535
  • 長整型:-2,147,483,647到2,147,483,647
  • unsigned long int類型:0到4,294,967,295
+1

值得指出的是,這些範圍取決於平臺。標準中只規定了其中一些最小尺寸。 – juanchopanza

2

首先,你應該在你的帖子弄不好格式。

我想到的第一個解決方案可能是在您的實現中,整數的大小等於16位(2個字節),而不是通常的32位(4個字節)。您應該使用long來代替標準32位內存。

此外,我不知道你爲什麼決定使用引用時,你可以簡單地從這樣的總和函數返回值:

long sum(long s) 
{ 
    //while code 

    return value; 
} 

我希望它能幫助。

+0

basicaly我明白,但我不知道我將如何使用這個,因爲我得到了這個程序的一些更多的限制:D無論如何謝謝 – user3127589

2

每個整數可以保存一個預定義的值範圍。在C中,你可以通過使用特殊的宏來看到這個範圍。例如,對於int類型,可以按照以下方式獲取可以存儲在此類型對象中的最大值和最小值。

#include <limits.h> 
#included <stdio.h> 

int main() 
{ 
    printf("The maximum value of type int is %d and the minimum value is %d\n", INT_MAX, INT_MIN); 
} 

如果某個值不適合給定類型的對象,則應該選擇一個具有更高等級的整數類型。例如,unsigned int的範圍通常大於signed int的範圍。您應該通過運行我展示的程序來選擇適當的類型。但是不要忘記在printf語句中使用正確的格式說明符。你可以檢查unsigned int,long,unsigned long,long long和unsigned long long。

1

計算機體系結構涵蓋了您遇到的問題。

一個基本的int被設計爲有16位,它給出的範圍可達65535.這意味着在這一點上所有給定的位都是1即1111 1111 1111 1111.不可能將1添加到該位模式因爲它只支持16位,因此加1(或更多)會產生不希望的行爲:請查閱overflow

因此,您需要使用具有更多位模式的實現:long int是您應該使用的東西。它使用32位來表示數據。給你更多的範圍。如果我沒有錯,超過40億。

接下來,您不應該手動添加1到7000(如上面的註釋中所述)。的1總和爲n = N(N + 1)/ 2

因此您的代碼:當n = 7000

long sum(){ 
    return ((7000(7000 + 1))/2) 
} 
+1

不要作出int是16位的假設。它通常是32(或64)。檢查sizeof(int)http://stackoverflow.com/a/5036313/14065。 long通常與int相同。強制64你需要使用'long long'。 http://stackoverflow.com/a/271132/14065 –

1

其實時存儲在存儲器中的號碼,它被映射到它的等效二進制碼 例如4在內存中存儲爲100。它需要3位將4存儲在內存中,因爲其二進制需要3位。它需要大致log(n)(以2爲底)將n存儲在內存中。所以如果n非常大,log(n)也很大並且發生溢出。 Int是4個字節,意思是32位。你應該嘗試一個長整型(8字節)來處理你的總和。如果數字變得更大,那麼可以使用長整型int,對於長整型int無法處理的數字,可以通過C++中的GNU MULTIPLE PRECISION LIBRARY來處理。這裏的這個文庫 https://gmplib.org

0

基準可以使用這一事實優化它:

1 + 2 + 3 + ... + (n - 1) + n = (1 + n) + (2 + (n - 1)) + (3 + (n - 2)) + ... + ((n/2) + (n/2) + 1) = (n + 1) * (n/2) = (n + 1) * n/2

0

對於N數目的總和的公式是N *(N-1)/ 2。

在你的情況,這將是70000 *2分之69999= 2449965000(2.5十億大約)

要存儲在一個變量需要一個能夠存儲足夠的比特來表示2.5十億的變量。

8位= 0〜256 16個比特= 0〜65535 32位= 0至4294967295(足夠大)

你需要一個32位的變量。 你也可以用它作爲備忘單:http://www.cplusplus.com/reference/climits/

你想要的類型是一個無符號長整型。

將i和n的類型更改爲無符號長整型,並且您的代碼將起作用。