Происходит следующее: ни log(2)
, ни log(setnumber)
не могут быть точно представлены в виде чисел с плавающей запятой, и их ошибки округления сговариваются, заставляя их коэффициент округляться до значения, меньшего 6
, которое затем усекается до 5
при преобразовании в целое число.
Использование log2( )
решит эту проблему на некоторых платформах, которые имеют математическую библиотеку хорошего качества, но стандарт C на самом деле ничего не гарантирует относительно точности log( )
или log2( )
(действительно, некоторые платформы просто реализуют log2( )
как log( )/log(2)
, так что это может вызвать у вас ту же проблему, что и у вас сейчас).
Вы хотите использовать функцию ilogb( )
, которая возвращает показатель степени своего аргумента в виде целочисленного значения со знаком.
setbits = ilogb(setnumber);
Это дает дополнительное преимущество, так как на некоторых платформах работает немного быстрее.
(Следует признать, что это использование ilogb
не переносимо на системы, в которых используется плавающая точка не-radix-2, но это гораздо меньшая проблема, чем на платформах, которые имеют просто некачественные математические библиотеки)