2016-12-21 73 views
1

試圖編譯我的代碼中斷以下行:爲什麼我會得到整數溢出,我該如何解決?

printf("%llu\n", 0x12345678 * 0x12345678); 

我得到這個:

program.c:45:34: warning: integer overflow in expression [-Woverflow] 
    printf("%llu\n", (0x12345678 * 0x12345678)); 

我該如何解決這個問題?

+6

'0×12345678 * 0x12345678' - >'0x12345678ULL * 0x12345678' – BLUEPIXY

+0

@BLUEPIXY我以前從來沒有看到,但它修復了警告。謝謝。 – bjd2385

+0

@ bjd2385這裏的關鍵是瞭解C使用什麼類型的_calculation_,這是根據操作數的類型確定的。存儲最終結果的類型不影響用於計算的類型。 – Lundin

回答

1

[接受修正後每@Lundin]評論

在你的機器,0x12345678unsigned long long窄 - 肯定是一個signed long也許int

A signed long * signed long仍然是signed long並且可能患有有符號整數溢出,這是UB。 signed long的範圍小於0x12345678 * 0x12345678的數學乘積。通過使用ULL後綴,數學至少用unsigned long long數學完成。 @BLUEPIXY

printf("%llu\n", 0x12345678ULL * 0x12345678); 
// or if the constant can not be changed 
printf("%llu\n", 1ULL * SOME_BIG_CONSTANT * SOME_BIG_CONSTANT); 

迂腐注:當打印整數類型可能int/unsigned更寬,保證最終計算結果的說明符相匹配。考慮到SOME_BIG_CONSTANT可能比unsigned long long更寬。或者離開演員陣容,並應付潛在的編譯器警告。

printf("%llu\n", (unsigned long long) (1ULL * SOME_BIG_CONSTANT * SOME_BIG_CONSTANT)); 

又見Why write 1,000,000,000 as 1000*1000*1000 in C?
There are reasons not to use 1000 * 1000 * 1000

+1

'0x12345678'在32位機器上是(有符號的)'int',而不是無符號的。不同於'0x82345678',它的類型是'unsigned int'。 – Lundin

+0

@lundin - 同意。 – chux

相關問題