P003 - Błąd zaokrąglenia liczby rzeczywistej
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: P003
//--------------------------

#include <iostream>
#include <iomanip>

using namespace std;

main()
{
  float x = 0;

  for(int i = 1; i <= 10; i++) x += 0.1; 
   
  if (x == 1)
    cout << "OK\n\n";
  else
    cout << "NIE OK\n\n";
  system("pause");
}

 

Widok okienka konsoli w uruchomionym programie
NIE OK

       Wyjaśnienie

Liczba rzeczywista LR jest zapisywana w komputerach w postaci specjalnego kodu zmiennoprzecinkowego. W kodzie tym liczba reprezentowana jest przez dwie inne liczby - mantysę m oraz cechę c - zgodnie ze wzorem:

Cecha c jest liczbą całkowitą ze znakiem, natomiast mantysa m jest ułamkiem właściwym, którego mianownik jest zawsze równy pewnej potędze liczby 2. Zatem mantysa może przyjmować tylko wartości, które dają się przedstawić w postaci ułamka:

Gdzie x jest liczbą całkowitą ze znakiem, a n określa liczbę bitów mantysy.

Zwróć uwagę, iż ułamka dziesiętnego 0,1 nie da się przedstawić w tej reprezentacji. Aby było to możliwe, licznik ułamka musiałby być dokładnie 10 razy mniejszy od mianownika, a żadna potęga liczby 2 nie dzieli się przez 10 bez reszty. Wyjaśnienie jest bardzo proste. Potęgi liczby 2 można rozłożyć jedynie na iloczyn czynników 2, np.

Natomiast podzielność przez 10 = 2 x 5 wymaga w dzielonej liczbie obecności czynnika 5, którego tutaj nie ma. Wnioskujemy zatem, iż ułamek dziesiętny 0,1 można przedstawić w reprezentacji zmiennoprzecinkowej tylko z pewną dokładnością:

W programie dodajemy dziesięć razy taką przybliżoną wartość ułamka 0,1. Na przykład załóżmy, iż mantysa jest 24 bitowa:

W efekcie wynik nie jest równy dokładnie 1 i program wypisuje drugi napis, zamiast spodziewanego napisu pierwszego.

 

Dokładny opis liczb rzeczywistych znajdziesz w artykule o binarnym kodowaniu liczb.

 



List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2017 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.