Спецификатор noexcept

228
03 марта 2017, 01:52
class Math { 
    public: 
        static bool __fastcall      IsPowerOfTwo( int x ) noexcept;
};
__forceinline bool Math::IsPowerOfTwo( int x ) { // хз что делает :D
    return ( x & ( x - 1 ) ) == 0 && x > 0;
}

noexcept надо тоже писать в определении?

Answer 1

Согласно стандарту C++ (15.4 Exception specification)

5 If any declaration of a function has an exception-specification that is not a noexcept-specification allowing all exceptions, all declarations, including the definition and any explicit specialization, of that function shall have a compatible exception-specification....

Это значит, что определение функции IsPowerOfTwo также должно содержать спецификацию исключения noexcept или noexcept( true )

Что касается самой функции, то она определяет, является ли заданное положительное целое число степенью 2.

( x & ( x - 1 ) ) == 0 && x > 0;

Выражение ( x & ( x - 1 ) ) означает следующее. Все целые числа, являющиеся степенью 2 имеют следующий вид (на примере одного байта)

0000 0001
0000 0010
0000 0100
0000 1000
0001 0000
0010 0000
0100 0000

и т.д. для остальных байтов. То есть в числе присутствует лишь одна битовая 1. Если для какого-нибудь из перечисленных чисел вычесть 1, то получим

   0000 0100 - 1 == 0000 0011

Теперь если сделать битовую операцию & (AND) с полученными числами, то результат будет равен 0.

   0000 0100
   0000 0011
   =========
   0000 0000

Если бы исходное число не являлось степенью 2, как, например,

   0000 1100

то есть если оно содержит более одной битовой 1, то после вычитания 1 в старших разрядах сохранятся другие единицы, если они присутствуют в числе

   0000 1100 - 1 == 0000 1011
        ^                ^ 

Поэтому побитовая операция & (AND) не даст 0.

   0000 1100
   0000 1011
   =========
   0000 1000
Answer 2

поясню про выражение

x & (x-1) == 0 && x > 0

оно проверяет положительное число x на степень двойки

тоесть это числа вида x = 2^i, где i позиция единственного единичного бита

в двоичном представлении имеют следующий вид:

0000...100000 = 2^i = x

а числа x - 1 имеют вид

0000...011111 = 1*2^i-1 + 1*2^i-2 + ... + 1*2^0 = x-1

тоесть все разряды начиная с i-1 ого единичные,

отсюда если побитово применить AND тоесть x & (x-1) получим 0 что означает что, число x это степень двойки, в противном случае, соотвественно не является степенью двойки

READ ALSO
Как писать Qt-код в MSVS 2015 [требует правки]

Как писать Qt-код в MSVS 2015 [требует правки]

Пишу проект в MSVS 2015, коллега сейчас закончил свою часть, но он писал на Qt 56

224
C++. Сортировка слиянием

C++. Сортировка слиянием

Вроде как алгоритм верный, но результат не выводитПодскажите в чем проблема

219