Итак, у меня есть следующий код, я знаю, что он где-то сломан, и я просто не могу определить, где …
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
… Google говорит мне, что это так. Так как же я получу в первую очередь 2900029440
а потом 18446744072314613760
для того же расчета? Может кто-нибудь объяснить мне, что здесь происходит? Это выше моих всесторонних возможностей прямо сейчас, и я чувствую, что это крошечная крошечная проблема где-то спрятана … 4902319 * 4096
не должно быть такого огромного числа, чтобы приложение сходило с ума, как это …
Спасибо за помощь!
Сначала вы рассчитываете (4096 * 4902319)
который рассчитывается как int
и это переполняет.
Затем это число преобразуется в uint64_t
,
Пытаться:
(4096 * (uint64_t) 4902319)
Чтобы сделать это рассчитать как uint64_t.
использование Без подписи, долго, долго буквальный:
4096 * 4902319ULL
~~~
До расчета переполняется.