2017-04-10 91 views
3

我試圖乘以數字,即1000010000 + 1通過C程序。但我沒有得到正確的輸出。乘以兩個長號

printf("%lld",(100000)*(100001)); 

我曾嘗試在不同的編譯器上面的代碼,但我得到的同樣1410165408代替10000100000我。

+1

它看起來像你在一個平臺,其中'int'是32位(或其附近,但最有可能的32)。您需要使用更寬的數據類型。 –

回答

6

好吧,讓我們乘

int64_t a = 100000; 
    int64_t b = 100001; 
    int64_t c = a * b; 

,我們會得到(二進制)

 1001010100000011010110101010100000 /* 10000100000 decimal */ 

,但如果你將其轉換爲int32_t

int32_t d = (int32_t) c; 

你會得到最後32位只有(和thr流程頂端10):

 01010100000011010110101010100000 /* 1410165408 decimal */ 

甲最簡單的方法時,可能的是,是既常量聲明爲64位值(LL後綴代表long long):

printf("%lld",(100000LL)*(100001LL)); 
+0

非常感謝.....但我得做一個正確的輸出。 –

+0

請注意,追加'LL'將確保常量具有至少64位寬度,因爲「long long」必須是該寬度或更寬。 – chux

1

你可以像下面這樣做

long long int a = 100000; 
long long int b = 100001; 
printf("%lld",(a)*(b)); 

這會給出正確的答案。

你在做什麼是(100000)*(100001)默認的編譯器,即需要100000成整數,並在(int)100001並將其存儲但是printf的過程中它打印(INT)爲(長長整型)

4

你兩個整數是int,這也會得到int的結果。 printf()格式說明符說%lld,這需要long long int,沒關係。

你可以施放或使用後綴:

printf("%lld", 100000LL * 100001LL); 

這將打印10000100000。當然還有一個限制,因爲long long int中的位數仍然是恆定的。

5

在C,用於計算的類型取決於操作數的類型,而不是存儲結果的類型。

純整數常量(如100000)的類型爲int,因爲它們可以放在一個裏面。然而,100000 * 100001的乘法不適合,所以你會得到整數溢出和未定義的行爲。切換到long不一定能解決任何問題,因爲它也可能是32位。

另外,在大多數系統上,使用%lld格式說明符打印int也是未定義的行爲。

這裏所有邪惡的根源是C中的蹩腳默認類型(出於某種原因稱爲「原始數據類型」)。簡單地擺脫他們和他們所有的不確定性,和你的錯誤將會消失與他們:

#include <stdio.h> 
#include <inttypes.h> 

int main(void) 
{ 
    printf("%"PRIu64, (uint64_t)100000 * (uint64_t)100001); 
    return 0; 
} 

或者等價的:UINT64_C(100000) * UINT64_C(100001)

+0

細節;如果代碼使用'UINT64_C(100000)* ...',它返回類型'uint_least64_t',那麼指定的匹配printf說明符是'PRIuLEAST64' – chux