關於__int64類型使用的一點感受


今天要生成一個20G的單詞文件,遇到數據邊界的問題,這里記下。

 

要生成這個20G的文件,我首先從一個文件里面讀取了一定量的單詞,放在緩沖區里面,然后重復把這個緩沖區寫入文件。這里我需要計算出循環的次數,如果這么寫:

__int64 k = 20;		//20GB的文件需要循環的次數
k = 20 * 1024 * 1024 * 1024 / nStrLen;	//nStrLen:緩沖區字符數

那么恭喜你,結果是0!

因為在計算20*1024*1024*1024的時候,數據是按照32位來對待的,所以實際上當計算結果大於2^32時,就會發生數據截斷.請看下面的截圖(來自於調試窗口):

image

可見上面的計算結果都是被當做int的。一旦數據結果越界,就會發生數據截斷。所謂截斷實際上是一個內存塊的覆蓋,多余的部分被舍棄。當你把一個int賦值給char,多出來的部分就被舍棄。這個截斷的結果取決於數據原始的類型,比如上面的int,覆蓋以后結果仍然是有符號的。上面的結果可以自己畫一下數據在內存里面的存儲模型,可以得到跟上面一樣的結果。

 

那么如何使上面的計算得到正確的結果呢?答案是讓每次計算都不會溢出

把上面的計算乘法改一下就可以實現了:

__int64 k = 20;		//20GB的文件需要循環的次數
k *= 1024 * 1024 * 1024;
k /= nStrLen;
cout << "Loop = " << k << endl;

這里的每次中間運算(1024*1024*1024=2^30 < 2^31-1)都沒有超過int的范圍

 

這里出現了__int64類型,通過查看msdn可以得知,他是微軟編譯器對於64整形的拓展,相應的還有unsigned __int64類型。

注意這兩種類型的格式化方式:

__int64 i64;

scanf(“%I64d”, &i64);

printf(“%I64d \n”, &i64);

類型

使用的前綴 指定的類型
__int64 I64

d, i, o, x, or X

unsigned __int64 I64

o, u, x, or X

格式化的形式

%[flags] [width] [.precision] [{h | l | ll | I | I32 | I64}]type

在c++中,最好不要使用cout,cin處理__int64,否則結果可能會出現差異,我就遇到輸出結果中有字母的情況。相反應該使用c庫中的格式化函數處理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM