P004 - Utrata precyzji w operacji dodawania liczb rzeczywistych |
---|
Program uruchomiono w środowisku Bloodshed Dev-C++ 4.9.9.2 |
// I Liceum Ogólnokształcące // im. K. Brodzińskiego // w Tarnowie //-------------------------- // Koło informatyczne 2006/7 //-------------------------- // Program: P004 //-------------------------- #include <iostream> #include <iomanip> using namespace std; main() { float x = 0; cout.precision(0); // 0 cyfr po przecinku cout.setf(ios::fixed); // format stałoprzecinkowy for(int i = 1; i <= 100000000; i++) x++; cout << x << endl << endl; system("pause"); } |
Widok okienka konsoli w uruchomionym programie |
---|
16777216 |
W kodzie zmiennoprzecinkowym mantysa m i wykładnik c rezerwują ustaloną ilość bitów. Zatem można dokładnie przedstawić tylko takie liczby, które da się wyrazić wzorem:
gdzie n jest liczbą bitów mantysy, a k liczbą co najwyżej n-bitową. Liczba bitów wchodzących do k określa tzw. precyzję zapisu zmiennoprzecinkowego, czyli ilość najbardziej znaczących cyfr, które są pamiętane dokładnie. Jeśli liczba wymaga do zapisu większej ilości bitów, to bity młodsze nie zostaną zapamiętane, co prowadzi właśnie do utraty precyzji.
W przypadku powyższego programu mantysa dla typu float jest 24-bitowa, czyli zapamiętuje dokładnie 24 bity liczby. Liczbę 16777216 można zapamiętać jako:
Jeśli dodamy do tej liczby 1, to otrzymamy
16777217(10) = 1000000000000000000000001(2)
Jest to liczba 25-bitowa. Mantysa może natomiast zapamiętać tylko 24 najstarsze bity z pominięciem ostatniego bitu (zaznaczonego tutaj kolorem czerwonym).
Ponieważ licznik ułamka musi być liczbą całkowitą, to 0,5 zostaje odrzucone i otrzymujemy z powrotem liczbę 16777216. Dlatego wynik dodawania 1 zatrzymuje się na tej wartości, pomimo iż w pętli wykonywane jest 100 milionów dodawań.
Dokładny opis liczb rzeczywistych znajdziesz w artykule o binarnym kodowaniu liczb.
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe