Witajcie. W jaki bardzo szybki sposób mogę spradzić czy podana liczba jest potęgą dwójki i jeżeli nią nie jest to znaleźć najbliższą potęge dwójki tej liczby?
Czytałem że robi to się przesunięciami bitowymi ale nic z tego nie rozumiem i nie wiem w jaki sposób mogę to zaimplementować. Mogę prosić o wytłumaczenie?
Generalnie schemat jest taki, że np. (5 << 3) = (5 * 8) bo (2^3) = 8.
chodziło mi bardziej dogłębne tłumaczenie najlepiej na podstawie kodu bo dalej nierozumem tego :P
przesuwając 5 << 3 otrzymuje 40, przesuwając 7 otrzymuje 56 a potrzebuje po prostu 8
Ten artykuł ci pomoże.
http://www.skorks.com/2010/10/write-a-function-to-determine-if-a-number-is-a-power-of-2/
Każda potęga dwójki ma w zapisie dwójkowym zapalony jeden bajt. Kolejne potęgi dwójki:
1 10 100 1000 10000 100000
etc.
Potęgą dwóki nie jest:
100001
, bo ma 2 zapalone bity.
Jeśli chodzi o sprawdzanie czy jest potęgą dwójki za pomocą przesunięcia bitowego to generalnie możesz porównywać z kolejnymi potęgami dwójki:
unsigned int liczba = 1;
for( int i = 0; i < 32; ++i ) //Obrazuje przesunięcie maksymalnie o 32 bity. Na procesorze x86 więcej nie wejdzie do int.
{
if( sprawdzana == liczba )
//potega dwojki wyświetlam komunikat
liczba<<1; // przesunięcie - szybkie mnożenie *2 - szybkie obliczanie kolejnych potęg
}
Osobiście robiłbym to za pomocą AND, ale "pokazywanie "ale jest pro" wobec początkującego jest żałosne...", więc nie pokażę :)
if(X&(X-1)) cout<<X<<" - NIE jest potęgą dwójki"<<endl;
unsigned long long NiearDown(unsigned long long X)
{
unsigned long long V=X;
while(X&=X-1) V=X;
return V;
}
unsigned long long NearUp(unsigned long long X)
{
unsigned long long V=NiearDown(X);
return V<X?V<<1:V;
}