今天要生成乙個20g的單詞檔案,遇到資料邊界的問題,這裡記下。
要生成這個20g的檔案,我首先從乙個檔案裡面讀取了一定量的單詞,放在緩衝區裡面,然後重複把這個緩衝區寫入檔案。這裡我需要計算出迴圈的次數,如果這麼寫:
__int64 k = 20; //20gb的檔案需要迴圈的次數那麼恭喜你,結果是0!k = 20 * 1024 * 1024 * 1024 / nstrlen; //nstrlen:緩衝區字元數
因為在計算20*1024*1024*1024的時候,資料是按照32位來對待的,所以實際上當計算結果大於2^32時,就會發生資料截斷.請看下面的截圖(來自於除錯視窗):
可見上面的計算結果都是被當做int的。一旦資料結果越界,就會發生資料截斷。所謂截斷實際上是乙個記憶體塊的覆蓋,多餘的部分被捨棄。當你把乙個int賦值給char,多出來的部分就被捨棄。這個截斷的結果取決於資料原始的型別,比如上面的int,覆蓋以後結果仍然是有符號的。上面的結果可以自己畫一下資料在記憶體裡面的儲存模型,可以得到跟上面一樣的結果。
那麼如何使上面的計算得到正確的結果呢?答案是讓每次計算都不會溢位
把上面的計算乘法改一下就可以實現了:
__int64 k = 20; //20gb的檔案需要迴圈的次數這裡的每次中間運算(1024*1024*1024=2^30 < 2^31-1)都沒有超過int的範圍k *= 1024 * 1024 * 1024;
k /= nstrlen;
cout << "loop = " << k << endl;
這裡出現了__int64型別,通過檢視msdn可以得知,他是微軟編譯器對於64整形的拓展,相應的還有unsigned __int64型別。
注意這兩種型別的格式化方式:
__int64 i64;
scanf(「%i64d」, &i64);
printf(「%i64d \n」, &i64);
型別 使用的字首
指定的型別
__int64
i64d,i,o,x, orx
unsigned __int64
i64o,u,x, orx
格式化的形式
%[flags] [width] [.precision] type在c++中,最好不要使用cout,cin處理__int64,否則結果可能會出現差異,我就遇到輸出結果中有字母的情況。相反應該使用c庫中的格式化函式處理。
int64型別的使用
int型別範圍為 2 31,2 31 即 2147483648 2147483647,unsigned型別範圍為 0,2 32 即0 2147483648,當需要表示的整數小於10位時可以使用。當需要表示的整數大於10位時,使用int型別將會出現溢位,此時可以使用 int64型別。int64型別範圍...
關於java泛型的一點理解
一 boolean addall collection c 泛型,extends 表示乙個邊界限制。如果e是乙個介面,extends表示需要乙個實現了此介面的類來對泛型引數進行指定。如果e是乙個類,則可表示使用其子類,可以認為extends表達了乙個 得關係 static 表示後面會用到 colle...
關於完型填空的一點點思考
完型填空智慧型寫作上具有一定的應用場景,比如張三語言天賦不好,之前某個詞不知道用哪個詞彙更好,可以通過bert 最好的幾個單詞供張三選擇。數學任務描述 my best friend dances really well.比如friend如果刪除掉,可以 出來是friend。cls my best m...