關於 int64型別使用的一點感受

2022-08-19 20:27:08 字數 1367 閱讀 1410

今天要生成乙個20g的單詞檔案,遇到資料邊界的問題,這裡記下。

要生成這個20g的檔案,我首先從乙個檔案裡面讀取了一定量的單詞,放在緩衝區裡面,然後重複把這個緩衝區寫入檔案。這裡我需要計算出迴圈的次數,如果這麼寫:

__int64 k = 20;		//20gb的檔案需要迴圈的次數

k = 20 * 1024 * 1024 * 1024 / nstrlen; //nstrlen:緩衝區字元數

那麼恭喜你,結果是0!

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

可見上面的計算結果都是被當做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

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...