Dziś do szybkiego przemyślenia coś, co potrafi wprawić w osłupienie gdy niewinne parę linijek kodu blokuje działanie dużego modułu, który nie ma nic wspólnego z matematyką.
EDIT Po poście Sebastiana uprościłem kod do absolutnego minimum, aby uwidocznić problem
Oto i on!
#include <iostream> #include <ctime> #include <cstdlib> #include <cmath> unsigned long long int suma = 0; int main() { srand( time ( NULL ) ); unsigned long long int losowa = rand() << 10 | rand() << 5 | rand(); for ( int i = 63; i >= 0; i-- ) { if ( ( (1<<i) & losowa ) > 0 ) { suma += ( 1<<i ); } } std::cout << "Suma: " << suma << std::endl; std::cout << "Losowa: " << losowa << std::endl; return 0; }
Trochę wstyd z takim błędem. :P
OdpowiedzUsuń1. Zapisujesz do jednej zmiennej, czytasz z innej (dlatego wynik się nie zgadza).
2. Czytasz poza zakresem tablicy.
Nie wiem czy dobrze zrozumiałem to "zawieranie". Nie chodzi Ci po prostu o to, czy dany bit jest aktywny/włączony/wysoki/etc.?
Poprawne rozwiązanie:
for (int i = 0, iend = sizeof(losowa) * 8; i < iend && losowa > 0; ++i)
{
if (losowa & 1)
cout << "2^" << i << " zawiera sie w losowej" << endl;
losowa >>= 1;
}
Uprościłem, ogołociłem.. próbuj :)
UsuńNo teraz widzę trzeci błąd. Liczysz na węższych typach i dlatego całość się rozpada. Niestety promocja działa z "lekkim" opóźnieniem, w tym przypadku dopiero w momencie porównywania. Nie powiem, że cały czas o tym myślałem pisząc swoje rozwiązanie, ale jednak takie rzeczy trzeba mieć z tyłu głowy (wzorce jednak się przydają :)). To tak samo jak z dzieleniem, trzeba pamiętać aby ręcznie zrzutować zmienną za wczasu, albo przy mnożeniu węższych typów danych, kiedy spodziewamy się wartości bliskich ekstremum.
UsuńW sumie ciekawsze jest umiejscowienie błędu. Na pewno bardzo ciekawym doświadczeniem musiało być otrzymywanie nieprawidłowej odpowiedzi losowo. :)
W sumie to mogłeś podać rozwiązanie od razu. Dzięki, że wyczyściłeś kod, tamte błędy od razu dyskwalifikowały całe rozwiązanie jako mogące działać, więc nie było nad czym dalej się rozwodzić.