為什么長時間溢出?
long long int n=2000*2000*2000*2000;long long int n=pow(2000,4);為什么第一個溢出而第二個不溢出?
解答動態(tài)
2000是一個通常為32位的整數(shù)。只用2000ll;2000LL,正如@AdrianMole所建議的那樣。
默認(rèn)情況下,文本是可以保存其值但不小于int的最小類型。2000可以很容易地存儲在int中,因為標(biāo)準(zhǔn)保證它至少是16位類型。
算法總是使用expressin中存在的最大類型執(zhí)行,但不小于int-sochar*char將在乘法之前提升為int,但類型不取決于結(jié)果是否可以存儲在推斷類型中。這是在你的情況下發(fā)生的事情——乘法是用INTS完成的,但是結(jié)果溢出。2 C++不支持基于Haskell CAN的目的地推斷類型。
。在第一行代碼的RHS上的常量(文字)是int值(不是長It)。因此,多重應(yīng)用程序是使用int算法執(zhí)行的,它將溢出。
要解決這個問題,請使用LL使常量變長后綴:
longint n=2000LL*2000LL*2000LL*2000LL; cppreference
2000*2000*2000*2000是4個int值的乘積,它返回一個int值。當(dāng)您將這個int值賦給long long int n時,溢出已經(jīng)發(fā)生(如果int是32位,則結(jié)果值將不適合)。
您需要確保不會發(fā)生溢出,因此當(dāng)您編寫
long long long int n=(long long int)2000*2000*2000*2000時; 確保正在執(zhí)行l(wèi)ong long int乘法(long long int乘以int返回long long int,因此在您的情況下沒有溢出)。這里很重要:轉(zhuǎn)換為long long int的優(yōu)先級高于乘法,因此這相當(dāng)于to
long long int n=((long long int)2000)*2000*2000*2000; 一個更短(更好的方法)是寫2000LL或2000LL,而不是舊的C樣式轉(zhuǎn)換(long long int)2000,后者也會觸發(fā)編譯器警告(brace init是首選,但是這對long int不起作用,long int在一行中有三個標(biāo)識符,而不是一個標(biāo)識符)。這使整型文字具有正確的類型。對于適合整數(shù)的2000,不需要這樣做,但是對于不適合整數(shù)的更高值,則需要這樣做。
long-long-int n=2000LL*2000*2000*2000;long-long-int n=2000LL*2000LL*2000LL*2000LL;第一個是使用32位整數(shù)的乘法。然后將結(jié)果轉(zhuǎn)換為long long int。由于32位整數(shù)無法存儲2000^4,因此結(jié)果溢出。
第二個調(diào)用pow函數(shù),該函數(shù)將第一個參數(shù)轉(zhuǎn)換為double并返回double。然后將結(jié)果轉(zhuǎn)換為long long int。在這種情況下沒有溢出,因為數(shù)學(xué)是在雙精度值上完成的。- End
免責(zé)聲明:
本頁內(nèi)容僅代表作者本人意見,若因此產(chǎn)生任何糾紛由作者本人負(fù)責(zé),概與琴島網(wǎng)公司無關(guān)。本頁內(nèi)容僅供參考,請您根據(jù)自身實際情況謹(jǐn)慎操作。尤其涉及您或第三方利益等事項,請咨詢專業(yè)人士處理。