2014-05-17 46 views
-5

numeric_limits ::最大()=> 2147483647爲什麼`而(基礎×10 <= 2147447412)`溢出

int x = 2147447412; 
int base = 1; 
while (base * 10 <= x) 
    base *= 10; // this loop will run forever. 

while ((long long)(base * 10) <= (long long)(x)) 
    base *= 10; // this loop still will run forever 

while (x - base * 10 >= 0) 
    base *= 10; // this loop will stop. 

問題>爲什麼會出現while循環運行下去嗎?溢出?

+4

'base'是'int'。 '10'是一個'int'。乘以它們的結果是一個'int'。 – chris

+0

爲了讓你的循環不會永遠運行;你應該檢查條件溢出。 (OR)使x長爲 – Rahul

+2

@Rahul,'long'通常仍然是32位。 – chris

回答

1

是的,溢出。一旦base達到1e9,base * 10溢出。所以你有未定義的行爲。

+0

我認爲錯過的一點是在while語句的條件檢查中,當'base' = 1e9時,'base * 10'溢出。 – q0987

+0

@q這正是我寫的。 –

+0

對不起,我的意思是我錯過了點:) – q0987

0

base1000000000和​​完成時,它表現出未定義的行爲。在你的情況下,它似乎溢出成爲負面。

+0

也許編譯器足夠聰明,可以用'while(true)'替換它。 – chris

+1

呃,我檢查了Clang和GCC。 Clang並沒有真正簡化,但GCC實際上在此做了一個數字:http://coliru.stacked-crooked.com/a/b0e0bbb90373105d – chris

+0

有趣的是GCC如何優化代碼。 –

0

在某個點,的base值將是1000000000,其小於x,但乘以由10溢出,因而在while循環中的條件是從未見過。

1

固定碼檢測什麼會做乘法之前溢出:

int const kBase = 10; 
int const kMax = numeric_limits<decltype(kBase)>::max()/kBase; 

int b = 1; 
do { 
    b *= kBase; 
} while (b <= kMax); 
+0

此代碼與原始代碼有不同的含義。 – q0987

+0

@ q0987你是對的,錯過了最後一次迭代 – Jeff

+0

@AlanStokes是的,也意識到了截斷早,但忽略修復它 – Jeff