Программа на C дает неверный вывод для простой математики! - PullRequest
1 голос
/ 03 мая 2010

(все объявлены как целые числа, ни одна из них не инициализирована заранее. Я включил math.h и собираю с -lm)

cachesize = atoi(argv[1]);
blocksize = atoi(argv[3]);
setnumber = (cachesize/blocksize);
printf("setnumber: %d\n", setnumber);
setbits = (log(setnumber))/(log(2));
printf("sbits: %d\n", setbits);

когда задан размер кэша как 1024 и размер блока как 16, вывод будет следующим:

setnumber: 64
sbits: 5

но log (64) / log (2) = 6!

Он работает правильно, когда задан размер кэша 512 и размер блока 32. Кажется, я не могу победить.

Я действительно надеюсь, что это глупая ошибка с моей стороны, и я был бы благодарен, если бы кто-нибудь мог указать, что это такое! Спасибо!

PS: Я сначала опубликовал это в Yahoo Ответах, но это было, вероятно, глупо. Больше не буду.

Ответы [ 2 ]

5 голосов
/ 03 мая 2010

log возвращает двойное число. Вы должны округлить вместо усечения. Однако вы можете использовать log2 здесь.

1 голос
/ 03 мая 2010

Происходит следующее: ни log(2), ни log(setnumber) не могут быть точно представлены в виде чисел с плавающей запятой, и их ошибки округления сговариваются, заставляя их коэффициент округляться до значения, меньшего 6, которое затем усекается до 5 при преобразовании в целое число.

Использование log2( ) решит эту проблему на некоторых платформах, которые имеют математическую библиотеку хорошего качества, но стандарт C на самом деле ничего не гарантирует относительно точности log( ) или log2( ) (действительно, некоторые платформы просто реализуют log2( ) как log( )/log(2), так что это может вызвать у вас ту же проблему, что и у вас сейчас).

Вы хотите использовать функцию ilogb( ), которая возвращает показатель степени своего аргумента в виде целочисленного значения со знаком.

setbits = ilogb(setnumber);

Это дает дополнительное преимущество, так как на некоторых платформах работает немного быстрее.

(Следует признать, что это использование ilogb не переносимо на системы, в которых используется плавающая точка не-radix-2, но это гораздо меньшая проблема, чем на платформах, которые имеют просто некачественные математические библиотеки)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...