1

だから、私は次のコードを持っています、私はそれがどこかで壊れていることを知っています、そして私は単にどこを特定することができません...

static uint64_t get_disk_total(const char* path)
{
    struct statvfs stfs;
    if ( statvfs(path, &stfs) == -1 )
    {
        return 0;
    }
    uint64_t t = stfs.f_blocks * stfs.f_bsize;
    std::cout  << "total for [" << path << "] is:" << t 
               << " block size (stfs.f_bsize):" <<   stfs.f_bsize
               << " block count (stfs.f_blocks):" << stfs.f_blocks 
               << " mul:" << stfs.f_blocks * stfs.f_bsize
               << " hardcoded: " << (uint64_t)(4096 * 4902319)     // line 50
               <<  std::endl ;
    return t;
}

コンパイルすると、次のように表示されます。

part_list.cpp: In function ‘uint64_t get_disk_total(const char*)’:
part_list.cpp:50:59: warning: integer overflow in expression [-Woverflow]

良い。実行すると、結果は次のようになります (手動で改行を追加):

total for [/] is:2900029440 
block size (stfs.f_bsize):4096 
block count (stfs.f_blocks):4902319 
mul:2900029440 
hardcoded: 18446744072314613760

私は知ってい4902319 * 4096 = 20079898624ます...グーグルはそれが私に教えてくれます。では、どうやって最初に取得し2900029440、次に18446744072314613760同じ計算を行うのでしょうか? 誰かがここで何が起こっているのか説明してもらえますか? 現時点では、私の包括的な能力を超えており、これはどこかに隠された小さな小さな問題だと感じています...4902319 * 4096アプリケーションがこのように狂ってしまうほど大きな数になるべきではありません...

ご協力ありがとうございました!

4

2 に答える 2

6

まず、どれがどのよう(4096 * 4902319)に計算されint、オーバーフローするかを計算します。次に、その数値は に変換されuint64_tます。

試す:

(4096 *  (uint64_t) 4902319) 

uint64_tとして計算するようにします。

于 2013-03-18T10:08:34.000 に答える
1

Unsigned long longリテラルを使用:

   4096 * 4902319ULL
                 ~~~

計算がオーバーフローする前。

于 2013-03-18T10:12:09.510 に答える