- ベストアンサー
Windowsファイルのサイズの問題
ネットでWindowsのファイルのサイズを計算するサンプルをみています。 ひとつのサンプルをみても、わからないですので、知っている方に質問したいです。 サンプルは WFDはWIN32_FIND_DATA構造体の変数で、 DWORD dwHigh = WFD.nFileSizeHigh; DWORD dwLow = WFD.nFileSizeLow; __int64 nSize; int nLen; char szTemp[MAX_PATH]; char* p; int nCnt; nSize = dwHigh; nSize = (nSize << 32) + 1023; nSize += dwLow; nSize = (nSize >> 10); //KB単位にする いくつの問題があります。 ●ファイルのサイズは、どうしてこんなに計算するの? どう計算するの? ●(nSize << 32) とnSize >> 10 はなにをやっているの? よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>nSize = dwHigh; >nSize = (nSize << 32) + 1023; >nSize += dwLow; >nSize = (nSize >> 10); //KB単位にする >●ファイルのサイズは、どうしてこんなに計算するの? > どう計算するの? 判りやすく書くと nSize = dwHigh; nSize = (nSize << 32); nSize += dwLow; と nSize += 1023; nSize = (nSize >> 10); //KB単位にする です。 前半はnSizeの上位32ビットにdwHighを、下位32ビットにdwLowを入れています。 nSize = dwHigh; まず、nSizeにdwHighを入れます。この状態でnSizeの下位32ビットにdwHighが居ます。 nSize = (nSize << 32); 本来、dwHighは上位32ビットに居て欲しいので、nSizeを左に32ビットシフトし、それをnSizeに入れます。この状態でnSizeの上位32ビットにdwHighが居ます。下位32ビットは0になっています。 nSize += dwLow; nSizeにdwLowを足せば、上位32ビットはそのまま。下位32ビットにdwLowが入ります。この状態でnSizeの上位32ビットにdwHighが居ます。下位32ビットにdwLowが居ます。 これで、nSizeには、64ビットのファイルサイズが入りました。 後半は、ファイルサイズを「キロバイト単位」にしています。 nSize += 1023; nSizeに1023を足して、端数を切り上げる準備をしています。 0→1023 1~1024→1024~2047 1025~2048→2048~3095 のようになります。 nSize = (nSize >> 10); //KB単位にする nSizeを右に10ビットシフトすると、1024で割った事になります。 0→1023→0キロバイト 1~1024→1024~2047→1キロバイト 1025~2048→2048~3095→2キロバイト のようになります。 >●(nSize << 32) とnSize >> 10 はなにをやっているの? 上の説明でもう判りますね。
その他の回答 (3)
- redfox63
- ベストアンサー率71% (1325/1856)
たとえば右シフトは 16の右シフトを考えると 16は 2進で1 0000と表現します 16 >> 1 を実行すると 1000(8) つまり1/2 16 >> 2 ならば 0100(4) つまり1/4 16 >> 3 ならば 0010(2) つまり1/8 16 >> 4 ならば 0001(1) つまり1/16 ということになります つまり >> は 2のn乗で除算することになります
こればっかりはCPUの中では全て2進数だということとビット演算を勉強して貰わないとあまりにも長くなるので長くなるので参考リンクを ファイルサイズが負数になることも、現行のWindowsでは最上位の符号ビットが1になってしまうようなファイルサイズも「まだ」扱うことはないので算術シフトか論理シフトかは今は問題になりません 割り算もシフトも余りは切り捨てです ちょうど1024の倍数にならない場合の余りは1~1023 余りに+1023をすれば1024~2046、それに対しての÷1024は必ず1になるのでその分切り上げとして扱えます ちょうど1024の倍数の時は+1023は端数にしかなれないので答えは変わりません
64ビット整数の上位と下位それぞれ別々に32ビットの変数に入ってるからまとめてあげないとちゃんと使えないから <<32で下位に代入した32ビット分を64ビット整数の上位に移動 >>10は1024で割り算 CPUでは除算よりシフト演算の方が速いから でもまともなコンパイラなら除算で書いても最適化すれば同じコード出すんで普通に書いとけと +1023は切り上げのため こういうコードの時はLARGE_INTEGER使った方が書きやすい
お礼
回答してくれてありがとうございました。 ●<<32で下位に代入した32ビット分を64ビット整数の上位に移動 これについてなんとかイメージできますが、 ●>>10は1024で割り算 これはわからないので、詳しく教えていただけませんか? ●+1023は切り上げのため これもイメージできないので、説明していただけませんか? よろしくお願いします。